Repository: TheBrainFamily/cypress-cucumber-preprocessor
Pull request #138 (2019-01-28 10:11:33)

feat(step_definition): Add option to define path for the common folder
#136

lgandecki: Cool. I like your approach, with tests and all. Looks like we need to fill the missing parts of the documentation still before we can merge it, so we don't release with a confusing doc. 
Do you want to take a stab at filling it in? Don't stress it too much - we will merge it with whatever you propose (as long as it's not technically incorrect ;-) ), and we will tweak it later if needed be. 
lgandecki: cool, thank you so much!
EmmanuelDemey: I have to difficulty to define the goal of the `nonGlobalStepDefinitions` option. Do you have an idea ? 
lgandecki: It's the difference between using the Cypress Cucumber Preprocessor Style pattern for placing step definitions files, and the "oldschool" (everything is global) Cucumber style 
EmmanuelDemey: updated

Patch:
diff --git a/.eslintrc b/.eslintrc
index 404c6ef..e13d78b 100644
--- a/.eslintrc
+++ b/.eslintrc
@@ -1,12 +1,10 @@
 {
   "extends": ["airbnb-base", "plugin:prettier/recommended"],
-  "plugins": [
-    "cypress",
-    "prettier"
-  ],
+  "plugins": ["cypress", "prettier"],
   "env": {
     "browser": true,
-    "cypress/globals": true
+    "cypress/globals": true,
+    "jest": true
   },
   "rules": {
     "prettier/prettier": "error"
diff --git a/README.md b/README.md
index 6f98cfc..9b73c0b 100644
--- a/README.md
+++ b/README.md
@@ -59,6 +59,12 @@ First please use [cosmiconfig](https://github.com/davidtheclark/cosmiconfig) to
 ``` 
 inside your package.json. (this will become the default option in a future version)
 
+Option | Default value | Description
+------------ | ------------- | -------------
+commonPath | a common folder inside the step_definitions folder | Define the path to a folder containing all common step definitions of your tests
+nonGlobalStepDefinitions | true | If true use the Cypress Cucumber Preprocessor Style pattern for placing step definitions files. If false, we will use the "oldschool" (everything is global) Cucumber style
+step_definitions | | Path to the folder containing our step definitions
+
 ###### Step definitions creation
 Then put your step definitions in cypress/integration with the folder name matching the .feature filename.
 Easier to show than to explain, so, assuming the feature file is in cypress/integration/Google.feature , as proposed above, the preprocessor will read all the files inside cypress/integration/Google/, so: 
diff --git a/lib/getStepDefinitionsPaths.js b/lib/getStepDefinitionsPaths.js
index eb440f4..51cd840 100644
--- a/lib/getStepDefinitionsPaths.js
+++ b/lib/getStepDefinitionsPaths.js
@@ -11,7 +11,10 @@ const getStepDefinitionsPaths = filePath => {
     const nonGlobalPattern = `${getStepDefinitionPathsFrom(
       filePath
     )}/**/*.+(js|ts)`;
-    const commonDefinitionsPattern = `${stepDefinitionPath()}/common/**/*.+(js|ts)`;
+
+    const commonPath =
+      loaded.config.commonPath || `${stepDefinitionPath()}/common/`;
+    const commonDefinitionsPattern = `${commonPath}**/*.+(js|ts)`;
     paths = paths.concat(glob.sync(nonGlobalPattern));
     paths = paths.concat(glob.sync(commonDefinitionsPattern));
   } else {
diff --git a/package-lock.json b/package-lock.json
index dee1361..ea76273 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -5146,6 +5146,16 @@
         "minimatch": "^3.0.3"
       }
     },
+    "fill-keys": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/fill-keys/-/fill-keys-1.0.2.tgz",
+      "integrity": "sha1-mo+jb06K1jTjv2tPPIiCVRRS6yA=",
+      "dev": true,
+      "requires": {
+        "is-object": "~1.0.1",
+        "merge-descriptors": "~1.0.0"
+      }
+    },
     "fill-range": {
       "version": "2.2.4",
       "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz",
@@ -6745,6 +6755,12 @@
       "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=",
       "dev": true
     },
+    "is-object": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.1.tgz",
+      "integrity": "sha1-iVJojF7C/9awPsyF52ngKQMINHA=",
+      "dev": true
+    },
     "is-observable": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/is-observable/-/is-observable-1.1.0.tgz",
@@ -9173,6 +9189,12 @@
       "integrity": "sha512-VjFo4P5Whtj4vsLzsYBu5ayHhoHJ0UqNm7ibvShmbmoz7tGi0vXaoJbGdB+GmDMLUdg8DpQXEIeVDAe8MaABvQ==",
       "dev": true
     },
+    "merge-descriptors": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
+      "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=",
+      "dev": true
+    },
     "merge-stream": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-1.0.1.tgz",
@@ -9332,6 +9354,12 @@
         "xtend": "^4.0.0"
       }
     },
+    "module-not-found-error": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/module-not-found-error/-/module-not-found-error-1.0.1.tgz",
+      "integrity": "sha1-z4tP9PKWQGdNbN0CsOO8UjwrvcA=",
+      "dev": true
+    },
     "moment": {
       "version": "2.22.2",
       "resolved": "https://registry.npmjs.org/moment/-/moment-2.22.2.tgz",
@@ -13255,6 +13283,17 @@
         "sisteransi": "^0.1.1"
       }
     },
+    "proxyquire": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/proxyquire/-/proxyquire-2.1.0.tgz",
+      "integrity": "sha512-kptdFArCfGRtQFv3Qwjr10lwbEV0TBJYvfqzhwucyfEXqVgmnAkyEw/S3FYzR5HI9i5QOq4rcqQjZ6AlknlCDQ==",
+      "dev": true,
+      "requires": {
+        "fill-keys": "^1.0.2",
+        "module-not-found-error": "^1.0.0",
+        "resolve": "~1.8.1"
+      }
+    },
     "pseudomap": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
diff --git a/package.json b/package.json
index 198b497..aae3891 100644
--- a/package.json
+++ b/package.json
@@ -56,8 +56,8 @@
     "eslint-plugin-cypress": "^2.0.1",
     "eslint-plugin-import": "^2.12.0",
     "eslint-plugin-prettier": "^2.6.0",
-    "jest": "^23.6.0",
     "husky": "^1.1.1",
+    "jest": "^23.6.0",
     "lint-staged": "^7.3.0",
     "prettier": "^1.13.5",
     "semantic-release": "^15.12.3"


Test patch:
diff --git a/lib/getStepDefinitionsPaths.test.js b/lib/getStepDefinitionsPaths.test.js
new file mode 100644
index 0000000..34c3e70
--- /dev/null
+++ b/lib/getStepDefinitionsPaths.test.js
@@ -0,0 +1,44 @@
+jest.mock("./stepDefinitionPath.js", () => () => "stepDefinitionPath");
+jest.mock("glob", () => ({
+  sync(pattern) {
+    return pattern;
+  }
+}));
+
+describe("getStepDefinitionsPaths", () => {
+  it("should return the default common folder", () => {
+    jest.resetModules();
+    jest.mock("cosmiconfig", () => () => ({
+      load: () => ({
+        config: {
+          nonGlobalStepDefinitions: true
+        }
+      })
+    }));
+    // eslint-disable-next-line global-require
+    const { getStepDefinitionsPaths } = require("./getStepDefinitionsPaths");
+
+    const actual = getStepDefinitionsPaths("/path");
+    const expected = "stepDefinitionPath/common/**/*.+(js|ts)";
+
+    expect(actual).to.include(expected);
+  });
+  it("should return the common folder defined by the developper", () => {
+    jest.resetModules();
+    jest.mock("cosmiconfig", () => () => ({
+      load: () => ({
+        config: {
+          nonGlobalStepDefinitions: true,
+          commonPath: "myPath/"
+        }
+      })
+    }));
+    // eslint-disable-next-line global-require
+    const { getStepDefinitionsPaths } = require("./getStepDefinitionsPaths");
+
+    const actual = getStepDefinitionsPaths("/path");
+    const expected = "myPath/**/*.+(js|ts)";
+
+    expect(actual).to.include(expected);
+  });
+});