Repository: TheBrainFamily/cypress-cucumber-preprocessor (js)

Issue:
cypress-cucumber-example not working with bundled features
Seems bundled features breaks step resolution where there is more than one instance of a matching step 

**Steps to reproduce:**

Updated the cypress-cucumber-example project to include 
cypress-cucumber-preprocessor: ^1.15.1

Added All.features file to cypress/integration folder

npx cypress run --spec cypress/integration/All.features 

````
====================================================================================================

  (Run Starting)

  ┌────────────────────────────────────────────────────────────────────────────────────────────────┐
  │ Cypress:    3.3.0                                                                              │
  │ Browser:    Electron 61 (headless)                                                             │
  │ Specs:      1 found (All.features)                                                             │
  │ Searched:   cypress/integration/All.features                                                   │
  └────────────────────────────────────────────────────────────────────────────────────────────────┘


────────────────────────────────────────────────────────────────────────────────────────────────────
                                                                                                    
  Running: All.features...                                                                 (1 of 1) 


  The Google
    ✓ Opening a Google network page (1128ms)
    ✓ Different kind of opening (3074ms)

  The Facebook
    ✓ Opening a social network page (2442ms)
    1) Different kind of opening

  The Twitter
    ✓ Opening Twitter (3343ms)
    ✓ Opening Twitter again (3009ms)


  5 passing (32s)
  1 failing

  1) The Facebook Different kind of opening:
     CypressError: Timed out retrying: expected 'Facebook – log in or sign up' to include 'Google'
      at Object.cypressErr (https://www.facebook.com/__cypress/runner/cypress_runner.js:83139:11)
      at Object.throwErr (https://www.facebook.com/__cypress/runner/cypress_runner.js:83104:18)
      at Object.throwErrByPath (https://www.facebook.com/__cypress/runner/cypress_runner.js:83131:17)
      at retry (https://www.facebook.com/__cypress/runner/cypress_runner.js:76579:16)
      at https://www.facebook.com/__cypress/runner/cypress_runner.js:68565:18
      at tryCatcher (https://www.facebook.com/__cypress/runner/cypress_runner.js:132036:23)
      at Promise._settlePromiseFromHandler (https://www.facebook.com/__cypress/runner/cypress_runner.js:130054:31)
      at Promise._settlePromise (https://www.facebook.com/__cypress/runner/cypress_runner.js:130111:18)
      at Promise._settlePromise0 (https://www.facebook.com/__cypress/runner/cypress_runner.js:130156:10)
      at Promise._settlePromises (https://www.facebook.com/__cypress/runner/cypress_runner.js:130231:18)
      at Async._drainQueue (https://www.facebook.com/__cypress/runner/cypress_runner.js:126960:16)
      at Async._drainQueues (https://www.facebook.com/__cypress/runner/cypress_runner.js:126970:10)
      at Async.drainQueues (https://www.facebook.com/__cypress/runner/cypress_runner.js:126844:14)
      at <anonymous>




  (Results)

  ┌────────────────────────────┐
  │ Tests:        6            │
  │ Passing:      5            │
  │ Failing:      1            │
  │ Pending:      0            │
  │ Skipped:      0            │
  │ Screenshots:  1            │
  │ Video:        true         │
  │ Duration:     32 seconds   │
  │ Spec Ran:     All.features │
  └────────────────────────────┘


  (Screenshots)

  - /Users/jcundill/code/cypress-cucumber-example/cypress/screenshots/All.features/The Facebook -- Different kind of opening (failed).png (1280x720)


  (Video)

  - Started processing:   Compressing to 32 CRF
  - Finished processing:  /Users/jcundill/code/cypress-cucumber-example/cypress/videos/All.features.mp4 (6 seconds)


====================================================================================================

  (Run Finished)


      Spec                                                Tests  Passing  Failing  Pending  Skipped 
  ┌────────────────────────────────────────────────────────────────────────────────────────────────┐
  │ ✖ All.features                              00:32        6        5        1        -        - │
  └────────────────────────────────────────────────────────────────────────────────────────────────┘
    1 of 1 failed (100%)                        00:32        6        5        1        -        -  

````

Pull request description:
fix(featuresloader): make bundling feature work with repeated non-glo…
…bal steps

fix #230

Patch:
diff --git a/.scripts/runOnExample.bash b/.scripts/runOnExample.bash
index 0c83cee..861fc4f 100644
--- a/.scripts/runOnExample.bash
+++ b/.scripts/runOnExample.bash
@@ -5,4 +5,4 @@ cd cypress-cucumber-example
 npm install
 rm -rf node_modules/cypress-cucumber-preprocessor
 npm link cypress-cucumber-preprocessor
-npm run test
+npm run test:all
diff --git a/cypress/integration/DataTable.feature b/cypress/integration/DataTable.feature
index 39a6c44..23b5c47 100644
--- a/cypress/integration/DataTable.feature
+++ b/cypress/integration/DataTable.feature
@@ -8,4 +8,10 @@ Feature: Being a plugin handling DataTable scenario
       | number | another number |
       | 1      | 2              |
       | 3      | 4              |
-    Then I verify the datatable result is equal to 10
\ No newline at end of file
+    Then I verify the datatable result is equal to 10
+
+
+  Scenario: New line character
+    Given I have a table with some escaped characters in it
+      | foo      | bar      |
+      | foo\nfoo | bar\nbar |
diff --git a/cypress/support/step_definitions/dataTable.js b/cypress/support/step_definitions/dataTable.js
index ae5c21e..b6400cf 100644
--- a/cypress/support/step_definitions/dataTable.js
+++ b/cypress/support/step_definitions/dataTable.js
@@ -1,9 +1,10 @@
-/* global then, when */
+// eslint-disable-next-line import/no-extraneous-dependencies
+const { Given, When, Then } = require("cypress-cucumber-preprocessor/steps");
 
 // you can have external state, and also require things!
 let sum = 0;
 
-when("I add all following numbers:", dataTable => {
+When("I add all following numbers:", dataTable => {
   // console.log("a, ", dataTable.rawTable.slice(1))
   sum = dataTable.rawTable
     .slice(1)
@@ -14,6 +15,11 @@ when("I add all following numbers:", dataTable => {
     );
 });
 
-then("I verify the datatable result is equal to {int}", result => {
+Then("I verify the datatable result is equal to {int}", result => {
   expect(sum).to.equal(result);
 });
+
+Given("I have a table with some escaped characters in it", dataTable => {
+  console.log(dataTable);
+  // we don't need to do anything, just make sure it doesn't break
+});
diff --git a/lib/featuresLoader.js b/lib/featuresLoader.js
index d17a58e..fd1859a 100644
--- a/lib/featuresLoader.js
+++ b/lib/featuresLoader.js
@@ -3,6 +3,7 @@ const path = require("path");
 const fs = require("fs");
 const { Parser } = require("gherkin");
 const log = require("debug")("cypress:cucumber");
+const jsStringEscape = require("js-string-escape");
 
 const { getStepDefinitionsPaths } = require("./getStepDefinitionsPaths");
 const { cucumberTemplate } = require("./cucumberTemplate");
@@ -19,21 +20,39 @@ const createCucumber = (
 ) =>
   `
     ${cucumberTemplate}
-    
   window.cucumberJson = ${JSON.stringify(cucumberJson)};
 
+  var moduleCache = arguments[5];
+
+  // Stolen from https://github.com/browserify/browserify/issues/1444
+  function clearFromCache(instance)
+  {
+      for(var key in moduleCache)
+      {
+          if(moduleCache[key].exports == instance)
+          {
+              delete moduleCache[key];
+              return;
+          }
+      }
+      throw "could not clear instance from module cache";
+  }
+
   ${globalToRequire.join("\n")}
 
   ${specs
     .map(
       ({ spec, filePath, name }) => `
         describe(\`${name}\`, function() {
+        window.currentFeatureName = \`${name}\`
         ${nonGlobalToRequire &&
           nonGlobalToRequire
             .find(fileSteps => fileSteps[filePath])
             [filePath].join("\n")}
             
-        createTestsFromFeature('${path.basename(filePath)}', \`${spec}\`);
+        createTestsFromFeature('${path.basename(filePath)}', \`${jsStringEscape(
+        spec
+      )}\`);
         })
         `
     )
@@ -51,7 +70,7 @@ module.exports = function(_, filePath) {
   if (isNonGlobalStepDefinitionsMode()) {
     nonGlobalStepDefinitionsToRequire = features.map(featurePath => ({
       [featurePath]: getStepDefinitionsPaths(featurePath).map(
-        sdPath => `require('${sdPath}')`
+        sdPath => `clearFromCache(require('${sdPath}'))`
       )
     }));
   } else {
diff --git a/lib/loader.js b/lib/loader.js
index 7713444..6edabd1 100644
--- a/lib/loader.js
+++ b/lib/loader.js
@@ -1,9 +1,11 @@
 const log = require("debug")("cypress:cucumber");
 const path = require("path");
 const { Parser } = require("gherkin");
+const jsStringEscape = require("js-string-escape");
 const { getStepDefinitionsPaths } = require("./getStepDefinitionsPaths");
 const { cucumberTemplate } = require("./cucumberTemplate");
 const { getCucumberJsonConfig } = require("./getCucumberJsonConfig");
+
 // This is the template for the file that we will send back to cypress instead of the text of a
 // feature file
 const createCucumber = (filePath, cucumberJson, spec, toRequire, name) =>
@@ -13,7 +15,7 @@ const createCucumber = (filePath, cucumberJson, spec, toRequire, name) =>
   window.cucumberJson = ${JSON.stringify(cucumberJson)};
   describe(\`${name}\`, function() {
     ${toRequire.join("\n")}
-    createTestsFromFeature('${filePath}', \`${spec}\`);
+    createTestsFromFeature('${filePath}', \`${jsStringEscape(spec)}\`);
   });
   `;
 
diff --git a/lib/resolveStepDefinition.js b/lib/resolveStepDefinition.js
index bd2c148..83ef4f3 100644
--- a/lib/resolveStepDefinition.js
+++ b/lib/resolveStepDefinition.js
@@ -31,11 +31,21 @@ class StepDefinitionRegistry {
           this.options.parameterTypeRegistry
         );
       }
-      this.definitions.push({ implementation, expression });
+
+      this.definitions.push({
+        implementation,
+        expression,
+        featureName: window.currentFeatureName || "___GLOBAL_EXECUTION___"
+      });
     };
 
-    this.resolve = (type, text) =>
-      this.definitions.filter(({ expression }) => expression.match(text))[0];
+    this.resolve = (type, text, runningFeatureName) =>
+      this.definitions.filter(
+        ({ expression, featureName }) =>
+          expression.match(text) &&
+          (runningFeatureName === featureName ||
+            featureName === "___GLOBAL_EXECUTION___")
+      )[0];
   }
 }
 
@@ -45,15 +55,21 @@ class HookRegistry {
     this.runtime = {};
 
     this.runtime = (tags, implementation) => {
-      this.definitions.push({ tags, implementation });
+      this.definitions.push({
+        tags,
+        implementation,
+        featureName: window.currentFeatureName || "___GLOBAL_EXECUTION___"
+      });
     };
 
-    this.resolve = scenarioTags =>
+    this.resolve = (scenarioTags, runningFeatureName) =>
       this.definitions.filter(
-        ({ tags }) =>
-          !tags ||
-          tags.length === 0 ||
-          shouldProceedCurrentStep(scenarioTags, tags)
+        ({ tags, featureName }) =>
+          (!tags ||
+            tags.length === 0 ||
+            shouldProceedCurrentStep(scenarioTags, tags)) &&
+          (runningFeatureName === featureName ||
+            featureName === "___GLOBAL_EXECUTION___")
       );
   }
 }
@@ -62,10 +78,11 @@ const stepDefinitionRegistry = new StepDefinitionRegistry();
 const beforeHookRegistry = new HookRegistry();
 const afterHookRegistry = new HookRegistry();
 
-function resolveStepDefinition(step) {
+function resolveStepDefinition(step, featureName) {
   const stepDefinition = stepDefinitionRegistry.resolve(
     step.keyword.toLowerCase().trim(),
-    step.text
+    step.text,
+    featureName
   );
   return stepDefinition || {};
 }
@@ -126,9 +143,9 @@ function resolveStepArgument(argument, exampleRowData, replaceParameterTags) {
   return argument;
 }
 
-function resolveAndRunHooks(hookRegistry, scenarioTags) {
+function resolveAndRunHooks(hookRegistry, scenarioTags, featureName) {
   return window.Cypress.Promise.each(
-    hookRegistry.resolve(scenarioTags),
+    hookRegistry.resolve(scenarioTags, featureName),
     ({ implementation }) => implementation.call(this)
   );
 }
@@ -161,15 +178,23 @@ function parseHookArgs(args) {
 }
 
 module.exports = {
-  resolveAndRunBeforeHooks(scenarioTags) {
-    return resolveAndRunHooks(beforeHookRegistry, scenarioTags);
+  resolveAndRunBeforeHooks(scenarioTags, featureName) {
+    return resolveAndRunHooks(beforeHookRegistry, scenarioTags, featureName);
   },
-  resolveAndRunAfterHooks(scenarioTags) {
-    return resolveAndRunHooks(afterHookRegistry, scenarioTags);
+  resolveAndRunAfterHooks(scenarioTags, featureName) {
+    return resolveAndRunHooks(afterHookRegistry, scenarioTags, featureName);
   },
   // eslint-disable-next-line func-names
-  resolveAndRunStepDefinition(step, replaceParameterTags, exampleRowData) {
-    const { expression, implementation } = resolveStepDefinition(step);
+  resolveAndRunStepDefinition(
+    step,
+    replaceParameterTags,
+    exampleRowData,
+    featureName
+  ) {
+    const { expression, implementation } = resolveStepDefinition(
+      step,
+      featureName
+    );
     const stepText = step.text;
     if (expression && implementation) {
       const argument = resolveStepArgument(
diff --git a/package-lock.json b/package-lock.json
index d26f262..0fbfe94 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -3224,7 +3224,6 @@
       "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz",
       "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=",
       "dev": true,
-      "optional": true,
       "requires": {
         "kind-of": "^3.0.2",
         "longest": "^1.0.1",
@@ -5825,7 +5824,7 @@
       "dependencies": {
         "minimist": {
           "version": "1.2.0",
-          "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+          "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
           "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ="
         }
       }
@@ -5843,7 +5842,7 @@
     },
     "diffie-hellman": {
       "version": "5.0.3",
-      "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz",
+      "resolved": "http://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz",
       "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==",
       "requires": {
         "bn.js": "^4.1.0",
@@ -7647,8 +7646,7 @@
         "ansi-regex": {
           "version": "2.1.1",
           "resolved": false,
-          "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
-          "optional": true
+          "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8="
         },
         "aproba": {
           "version": "1.2.0",
@@ -7669,14 +7667,12 @@
         "balanced-match": {
           "version": "1.0.0",
           "resolved": false,
-          "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
-          "optional": true
+          "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
         },
         "brace-expansion": {
           "version": "1.1.11",
           "resolved": false,
           "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
-          "optional": true,
           "requires": {
             "balanced-match": "^1.0.0",
             "concat-map": "0.0.1"
@@ -7691,20 +7687,17 @@
         "code-point-at": {
           "version": "1.1.0",
           "resolved": false,
-          "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
-          "optional": true
+          "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c="
         },
         "concat-map": {
           "version": "0.0.1",
           "resolved": false,
-          "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
-          "optional": true
+          "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
         },
         "console-control-strings": {
           "version": "1.1.0",
           "resolved": false,
-          "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=",
-          "optional": true
+          "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4="
         },
         "core-util-is": {
           "version": "1.0.2",
@@ -7821,8 +7814,7 @@
         "inherits": {
           "version": "2.0.3",
           "resolved": false,
-          "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
-          "optional": true
+          "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
         },
         "ini": {
           "version": "1.3.5",
@@ -7834,7 +7826,6 @@
           "version": "1.0.0",
           "resolved": false,
           "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
-          "optional": true,
           "requires": {
             "number-is-nan": "^1.0.0"
           }
@@ -7849,7 +7840,6 @@
           "version": "3.0.4",
           "resolved": false,
           "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
-          "optional": true,
           "requires": {
             "brace-expansion": "^1.1.7"
           }
@@ -7857,14 +7847,12 @@
         "minimist": {
           "version": "0.0.8",
           "resolved": false,
-          "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
-          "optional": true
+          "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0="
         },
         "minipass": {
           "version": "2.2.4",
           "resolved": false,
           "integrity": "sha512-hzXIWWet/BzWhYs2b+u7dRHlruXhwdgvlTMDKC6Cb1U7ps6Ac6yQlR39xsbjWJE377YTCtKwIXIpJ5oP+j5y8g==",
-          "optional": true,
           "requires": {
             "safe-buffer": "^5.1.1",
             "yallist": "^3.0.0"
@@ -7883,7 +7871,6 @@
           "version": "0.5.1",
           "resolved": false,
           "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
-          "optional": true,
           "requires": {
             "minimist": "0.0.8"
           }
@@ -7964,8 +7951,7 @@
         "number-is-nan": {
           "version": "1.0.1",
           "resolved": false,
-          "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
-          "optional": true
+          "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0="
         },
         "object-assign": {
           "version": "4.1.1",
@@ -7977,7 +7963,6 @@
           "version": "1.4.0",
           "resolved": false,
           "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
-          "optional": true,
           "requires": {
             "wrappy": "1"
           }
@@ -8063,8 +8048,7 @@
         "safe-buffer": {
           "version": "5.1.1",
           "resolved": false,
-          "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==",
-          "optional": true
+          "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg=="
         },
         "safer-buffer": {
           "version": "2.1.2",
@@ -8100,7 +8084,6 @@
           "version": "1.0.2",
           "resolved": false,
           "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
-          "optional": true,
           "requires": {
             "code-point-at": "^1.0.0",
             "is-fullwidth-code-point": "^1.0.0",
@@ -8120,7 +8103,6 @@
           "version": "3.0.1",
           "resolved": false,
           "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
-          "optional": true,
           "requires": {
             "ansi-regex": "^2.0.0"
           }
@@ -8164,14 +8146,12 @@
         "wrappy": {
           "version": "1.0.2",
           "resolved": false,
-          "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
-          "optional": true
+          "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
         },
         "yallist": {
           "version": "3.0.2",
           "resolved": false,
-          "integrity": "sha1-hFK0u36Dx8GI2AQcGoN8dz1ti7k=",
-          "optional": true
+          "integrity": "sha1-hFK0u36Dx8GI2AQcGoN8dz1ti7k="
         }
       }
     },
@@ -8560,7 +8540,7 @@
     },
     "htmlescape": {
       "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/htmlescape/-/htmlescape-1.1.1.tgz",
+      "resolved": "http://registry.npmjs.org/htmlescape/-/htmlescape-1.1.1.tgz",
       "integrity": "sha1-OgPtwiFLyjtmQko+eVk0lQnLA1E="
     },
     "http-proxy-agent": {
@@ -10538,8 +10518,7 @@
               "version": "2.1.1",
               "resolved": false,
               "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
-              "dev": true,
-              "optional": true
+              "dev": true
             },
             "aproba": {
               "version": "1.2.0",
@@ -10563,15 +10542,13 @@
               "version": "1.0.0",
               "resolved": false,
               "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
-              "dev": true,
-              "optional": true
+              "dev": true
             },
             "brace-expansion": {
               "version": "1.1.11",
               "resolved": false,
               "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
               "dev": true,
-              "optional": true,
               "requires": {
                 "balanced-match": "^1.0.0",
                 "concat-map": "0.0.1"
@@ -10588,22 +10565,19 @@
               "version": "1.1.0",
               "resolved": false,
               "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
-              "dev": true,
-              "optional": true
+              "dev": true
             },
             "concat-map": {
               "version": "0.0.1",
               "resolved": false,
               "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
-              "dev": true,
-              "optional": true
+              "dev": true
             },
             "console-control-strings": {
               "version": "1.1.0",
               "resolved": false,
               "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=",
-              "dev": true,
-              "optional": true
+              "dev": true
             },
             "core-util-is": {
               "version": "1.0.2",
@@ -10734,8 +10708,7 @@
               "version": "2.0.3",
               "resolved": false,
               "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
-              "dev": true,
-              "optional": true
+              "dev": true
             },
             "ini": {
               "version": "1.3.5",
@@ -10749,7 +10722,6 @@
               "resolved": false,
               "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
               "dev": true,
-              "optional": true,
               "requires": {
                 "number-is-nan": "^1.0.0"
               }
@@ -10766,7 +10738,6 @@
               "resolved": false,
               "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
               "dev": true,
-              "optional": true,
               "requires": {
                 "brace-expansion": "^1.1.7"
               }
@@ -10775,15 +10746,13 @@
               "version": "0.0.8",
               "resolved": false,
               "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
-              "dev": true,
-              "optional": true
+              "dev": true
             },
             "minipass": {
               "version": "2.3.5",
               "resolved": false,
               "integrity": "sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA==",
               "dev": true,
-              "optional": true,
               "requires": {
                 "safe-buffer": "^5.1.2",
                 "yallist": "^3.0.0"
@@ -10804,7 +10773,6 @@
               "resolved": false,
               "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
               "dev": true,
-              "optional": true,
               "requires": {
                 "minimist": "0.0.8"
               }
@@ -10893,8 +10861,7 @@
               "version": "1.0.1",
               "resolved": false,
               "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
-              "dev": true,
-              "optional": true
+              "dev": true
             },
             "object-assign": {
               "version": "4.1.1",
@@ -10908,7 +10875,6 @@
               "resolved": false,
               "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
               "dev": true,
-              "optional": true,
               "requires": {
                 "wrappy": "1"
               }
@@ -11004,8 +10970,7 @@
               "version": "5.1.2",
               "resolved": false,
               "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
-              "dev": true,
-              "optional": true
+              "dev": true
             },
             "safer-buffer": {
               "version": "2.1.2",
@@ -11047,7 +11012,6 @@
               "resolved": false,
               "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
               "dev": true,
-              "optional": true,
               "requires": {
                 "code-point-at": "^1.0.0",
                 "is-fullwidth-code-point": "^1.0.0",
@@ -11069,7 +11033,6 @@
               "resolved": false,
               "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
               "dev": true,
-              "optional": true,
               "requires": {
                 "ansi-regex": "^2.0.0"
               }
@@ -11118,15 +11081,13 @@
               "version": "1.0.2",
               "resolved": false,
               "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
-              "dev": true,
-              "optional": true
+              "dev": true
             },
             "yallist": {
               "version": "3.0.3",
               "resolved": false,
               "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==",
-              "dev": true,
-              "optional": true
+              "dev": true
             }
           }
         },
@@ -12223,6 +12184,11 @@
       "resolved": "https://registry.npmjs.org/js-levenshtein/-/js-levenshtein-1.1.6.tgz",
       "integrity": "sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g=="
     },
+    "js-string-escape": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/js-string-escape/-/js-string-escape-1.0.1.tgz",
+      "integrity": "sha1-4mJbrbwNZ8dTPp7cEGjFh65BN+8="
+    },
     "js-tokens": {
       "version": "3.0.2",
       "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz",
@@ -13256,8 +13222,7 @@
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz",
       "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=",
-      "dev": true,
-      "optional": true
+      "dev": true
     },
     "loose-envify": {
       "version": "1.4.0",
@@ -17513,7 +17478,7 @@
     },
     "ora": {
       "version": "0.2.3",
-      "resolved": "https://registry.npmjs.org/ora/-/ora-0.2.3.tgz",
+      "resolved": "http://registry.npmjs.org/ora/-/ora-0.2.3.tgz",
       "integrity": "sha1-N1J9Igrc1Tw5tzVx11QVbV22V6Q=",
       "dev": true,
       "requires": {
@@ -17530,7 +17495,7 @@
     },
     "os-homedir": {
       "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
+      "resolved": "http://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
       "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=",
       "dev": true
     },
@@ -18296,7 +18261,7 @@
       "dependencies": {
         "jsesc": {
           "version": "0.5.0",
-          "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz",
+          "resolved": "http://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz",
           "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0="
         }
       }
@@ -19367,7 +19332,7 @@
     },
     "sha.js": {
       "version": "2.4.11",
-      "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz",
+      "resolved": "http://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz",
       "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==",
       "requires": {
         "inherits": "^2.0.1",
@@ -19376,7 +19341,7 @@
     },
     "shasum": {
       "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/shasum/-/shasum-1.0.2.tgz",
+      "resolved": "http://registry.npmjs.org/shasum/-/shasum-1.0.2.tgz",
       "integrity": "sha1-5wEjENj0F/TetXEhUOVni4euVl8=",
       "requires": {
         "json-stable-stringify": "~0.0.0",
@@ -19960,7 +19925,7 @@
       "dependencies": {
         "minimist": {
           "version": "1.2.0",
-          "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+          "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
           "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ="
         }
       }
@@ -20836,8 +20801,7 @@
             },
             "ansi-regex": {
               "version": "2.1.1",
-              "bundled": true,
-              "optional": true
+              "bundled": true
             },
             "aproba": {
               "version": "1.2.0",
@@ -20855,13 +20819,11 @@
             },
             "balanced-match": {
               "version": "1.0.0",
-              "bundled": true,
-              "optional": true
+              "bundled": true
             },
             "brace-expansion": {
               "version": "1.1.11",
               "bundled": true,
-              "optional": true,
               "requires": {
                 "balanced-match": "^1.0.0",
                 "concat-map": "0.0.1"
@@ -20874,18 +20836,15 @@
             },
             "code-point-at": {
               "version": "1.1.0",
-              "bundled": true,
-              "optional": true
+              "bundled": true
             },
             "concat-map": {
               "version": "0.0.1",
-              "bundled": true,
-              "optional": true
+              "bundled": true
             },
             "console-control-strings": {
               "version": "1.1.0",
-              "bundled": true,
-              "optional": true
+              "bundled": true
             },
             "core-util-is": {
               "version": "1.0.2",
@@ -20988,8 +20947,7 @@
             },
             "inherits": {
               "version": "2.0.3",
-              "bundled": true,
-              "optional": true
+              "bundled": true
             },
             "ini": {
               "version": "1.3.5",
@@ -20999,7 +20957,6 @@
             "is-fullwidth-code-point": {
               "version": "1.0.0",
               "bundled": true,
-              "optional": true,
               "requires": {
                 "number-is-nan": "^1.0.0"
               }
@@ -21012,20 +20969,17 @@
             "minimatch": {
               "version": "3.0.4",
               "bundled": true,
-              "optional": true,
               "requires": {
                 "brace-expansion": "^1.1.7"
               }
             },
             "minimist": {
               "version": "0.0.8",
-              "bundled": true,
-              "optional": true
+              "bundled": true
             },
             "minipass": {
               "version": "2.3.5",
               "bundled": true,
-              "optional": true,
               "requires": {
                 "safe-buffer": "^5.1.2",
                 "yallist": "^3.0.0"
@@ -21042,7 +20996,6 @@
             "mkdirp": {
               "version": "0.5.1",
               "bundled": true,
-              "optional": true,
               "requires": {
                 "minimist": "0.0.8"
               }
@@ -21115,8 +21068,7 @@
             },
             "number-is-nan": {
               "version": "1.0.1",
-              "bundled": true,
-              "optional": true
+              "bundled": true
             },
             "object-assign": {
               "version": "4.1.1",
@@ -21126,7 +21078,6 @@
             "once": {
               "version": "1.4.0",
               "bundled": true,
-              "optional": true,
               "requires": {
                 "wrappy": "1"
               }
@@ -21202,8 +21153,7 @@
             },
             "safe-buffer": {
               "version": "5.1.2",
-              "bundled": true,
-              "optional": true
+              "bundled": true
             },
             "safer-buffer": {
               "version": "2.1.2",
@@ -21233,7 +21183,6 @@
             "string-width": {
               "version": "1.0.2",
               "bundled": true,
-              "optional": true,
               "requires": {
                 "code-point-at": "^1.0.0",
                 "is-fullwidth-code-point": "^1.0.0",
@@ -21251,7 +21200,6 @@
             "strip-ansi": {
               "version": "3.0.1",
               "bundled": true,
-              "optional": true,
               "requires": {
                 "ansi-regex": "^2.0.0"
               }
@@ -21290,13 +21238,11 @@
             },
             "wrappy": {
               "version": "1.0.2",
-              "bundled": true,
-              "optional": true
+              "bundled": true
             },
             "yallist": {
               "version": "3.0.3",
-              "bundled": true,
-              "optional": true
+              "bundled": true
             }
           }
         },
diff --git a/package.json b/package.json
index 3e95614..84737eb 100644
--- a/package.json
+++ b/package.json
@@ -53,6 +53,7 @@
     "debug": "^3.0.1",
     "gherkin": "^5.1.0",
     "glob": "^7.1.2",
+    "js-string-escape": "^1.0.1",
     "through": "^2.3.8"
   },
   "devDependencies": {


Test patch:
diff --git a/lib/createTestFromScenario.js b/lib/createTestFromScenario.js
index 300a000..6086a4a 100644
--- a/lib/createTestFromScenario.js
+++ b/lib/createTestFromScenario.js
@@ -21,7 +21,8 @@ const stepTest = function(state, stepDetails, exampleRowData) {
         this,
         stepDetails,
         replaceParameterTags,
-        exampleRowData
+        exampleRowData,
+        state.feature.name
       )
     )
     .then(() => state.onFinishStep(stepDetails, statuses.PASSED));
@@ -37,11 +38,15 @@ const runTest = (scenario, stepsToRun, rowData) => {
     const state = window.testState;
     return cy
       .then(() => state.onStartScenario(scenario, indexedSteps))
-      .then(() => resolveAndRunBeforeHooks.call(this, scenario.tags))
+      .then(() =>
+        resolveAndRunBeforeHooks.call(this, scenario.tags, state.feature.name)
+      )
       .then(() =>
         indexedSteps.forEach(step => stepTest.call(this, state, step, rowData))
       )
-      .then(() => resolveAndRunAfterHooks.call(this, scenario.tags))
+      .then(() =>
+        resolveAndRunAfterHooks.call(this, scenario.tags, state.feature.name)
+      )
       .then(() => state.onFinishScenario(scenario));
   });
 };