Repository: TheBrainFamily/cypress-cucumber-preprocessor
Pull request #351 (2020-03-28 19:27:48)

Pr/338


Patch:
diff --git a/lib/getConfig.js b/lib/getConfig.js
new file mode 100644
index 0000000..e3f5ca7
--- /dev/null
+++ b/lib/getConfig.js
@@ -0,0 +1,15 @@
+const cosmiconfig = require("cosmiconfig");
+
+let explorer;
+
+exports.getConfig = () => {
+  if (!explorer) {
+    explorer = cosmiconfig("cypress-cucumber-preprocessor", {
+      sync: true,
+      rcExtensions: true
+    });
+  }
+
+  const loaded = explorer.load();
+  return loaded && loaded.config;
+};
diff --git a/lib/getCucumberJsonConfig.js b/lib/getCucumberJsonConfig.js
index 4d27235..93e9226 100644
--- a/lib/getCucumberJsonConfig.js
+++ b/lib/getCucumberJsonConfig.js
@@ -1,14 +1,10 @@
-const cosmiconfig = require("cosmiconfig");
 const log = require("debug")("cypress:cucumber");
+const { getConfig } = require("./getConfig");
 
 exports.getCucumberJsonConfig = () => {
-  const explorer = cosmiconfig("cypress-cucumber-preprocessor", { sync: true });
-  const loaded = explorer.load();
-
+  const config = getConfig();
   const cucumberJson =
-    loaded && loaded.config && loaded.config.cucumberJson
-      ? loaded.config.cucumberJson
-      : { generate: false };
+    config && config.cucumberJson ? config.cucumberJson : { generate: false };
   log("cucumber.json", JSON.stringify(cucumberJson));
 
   return cucumberJson;
diff --git a/lib/getStepDefinitionsPaths.js b/lib/getStepDefinitionsPaths.js
index d35401d..42ada5f 100644
--- a/lib/getStepDefinitionsPaths.js
+++ b/lib/getStepDefinitionsPaths.js
@@ -1,18 +1,16 @@
 const glob = require("glob");
-const cosmiconfig = require("cosmiconfig");
+const { getConfig } = require("./getConfig");
 const stepDefinitionPath = require("./stepDefinitionPath.js");
 const { getStepDefinitionPathsFrom } = require("./getStepDefinitionPathsFrom");
 
 const getStepDefinitionsPaths = filePath => {
   let paths = [];
-  const explorer = cosmiconfig("cypress-cucumber-preprocessor", { sync: true });
-  const loaded = explorer.load();
-  if (loaded && loaded.config && loaded.config.nonGlobalStepDefinitions) {
+  const config = getConfig();
+  if (config && config.nonGlobalStepDefinitions) {
     const nonGlobalPattern = `${getStepDefinitionPathsFrom(
       filePath
     )}/**/*.+(js|ts)`;
-    const commonPath =
-      loaded.config.commonPath || `${stepDefinitionPath()}/common/`;
+    const commonPath = config.commonPath || `${stepDefinitionPath()}/common/`;
     const commonDefinitionsPattern = `${commonPath}**/*.+(js|ts)`;
     paths = paths.concat(glob.sync(nonGlobalPattern));
     paths = paths.concat(glob.sync(commonDefinitionsPattern));
diff --git a/lib/isNonGlobalStepDefinitionsMode.js b/lib/isNonGlobalStepDefinitionsMode.js
index 11173c5..d7a53a7 100644
--- a/lib/isNonGlobalStepDefinitionsMode.js
+++ b/lib/isNonGlobalStepDefinitionsMode.js
@@ -1,7 +1,6 @@
-const cosmiconfig = require("cosmiconfig");
+const { getConfig } = require("./getConfig");
 
 exports.isNonGlobalStepDefinitionsMode = () => {
-  const explorer = cosmiconfig("cypress-cucumber-preprocessor", { sync: true });
-  const loaded = explorer.load();
-  return loaded && loaded.config && loaded.config.nonGlobalStepDefinitions;
+  const config = getConfig();
+  return config && config.nonGlobalStepDefinitions;
 };
diff --git a/lib/stepDefinitionPath.js b/lib/stepDefinitionPath.js
index ffa9382..fb4a790 100644
--- a/lib/stepDefinitionPath.js
+++ b/lib/stepDefinitionPath.js
@@ -1,15 +1,11 @@
 const path = require("path");
-const cosmiconfig = require("cosmiconfig");
 const fs = require("fs");
+const { getConfig } = require("./getConfig");
 
 module.exports = () => {
   const appRoot = process.cwd();
-
-  const explorer = cosmiconfig("cypress-cucumber-preprocessor", { sync: true });
-  const loaded = explorer.load();
-  if (loaded && loaded.config) {
-    const { config, filepath } = loaded;
-
+  const config = getConfig();
+  if (config) {
     // left for backward compability, but we need the consistency with other configuration options
     const confStepDefinitions = config.step_definitions
       ? config.step_definitions
@@ -21,7 +17,7 @@ module.exports = () => {
 
       if (!fs.existsSync(stepsPath)) {
         throw new Error(
-          `We've tried to resolve your step definitions at ${relativePath}, but that doesn't seem to exist. As of version 2.0.0 it's required to set step_definitions in your cypress-cucumber-preprocessor configuration. Currently your configuration is in: ${filepath}. Look for nonGlobalStepDefinitions and add stepDefinitions right next to it. It should match your cypress configuration has set for integrationFolder. We no longer rely on getting information from that file as it was unreliable and problematic across Linux/MacOS/Windows especially since the config file could have been passed as an argument to cypress.`
+          `We've tried to resolve your step definitions at ${relativePath}, but that doesn't seem to exist. As of version 2.0.0 it's required to set step_definitions in your cypress-cucumber-preprocessor configuration. Look for nonGlobalStepDefinitions and add stepDefinitions right next to it. It should match your cypress configuration has set for integrationFolder. We no longer rely on getting information from that file as it was unreliable and problematic across Linux/MacOS/Windows especially since the config file could have been passed as an argument to cypress.`
         );
       }
       return stepsPath;


Test patch:
diff --git a/lib/stepDefinitionPath.test.js b/lib/stepDefinitionPath.test.js
index f4402a0..f88cd5c 100644
--- a/lib/stepDefinitionPath.test.js
+++ b/lib/stepDefinitionPath.test.js
@@ -1,66 +1,46 @@
 const fs = require("fs");
-const cosmiconfig = require("cosmiconfig");
-const stepDefinitionPath = require("./stepDefinitionPath.js");
+const { getConfig } = require("./getConfig");
+const stepDefinitionPath = require("./stepDefinitionPath");
 
+jest.mock("./getConfig");
 jest.mock("fs", () => ({
   existsSync: jest.fn()
 }));
 
-jest.mock("cosmiconfig");
-
 const defaultNonGlobalStepDefinitionsPath = "cypress/integration";
 
 describe("load path from step definitions", () => {
   beforeEach(() => {
-    cosmiconfig.mockReset();
+    getConfig.mockReset();
     fs.existsSync.mockReset();
   });
 
   test("Should throw an error if nonGlobalStepDefinitions and stepDefinitions are not set and the default is wrong", () => {
-    const COMICONFIG_FILEPATH = "package.json";
-    const loadMock = jest.fn().mockReturnValue({
-      config: {
-        nonGlobalStepDefinitions: true
-      },
-      filepath: COMICONFIG_FILEPATH
-    });
-    cosmiconfig.mockReturnValue({
-      load: loadMock
+    getConfig.mockReturnValue({
+      nonGlobalStepDefinitions: true
     });
     fs.existsSync.mockReturnValue(false);
 
-    const errorMessage = `We've tried to resolve your step definitions at ${defaultNonGlobalStepDefinitionsPath}, but that doesn't seem to exist. As of version 2.0.0 it's required to set step_definitions in your cypress-cucumber-preprocessor configuration. Currently your configuration is in: ${COMICONFIG_FILEPATH}. Look for nonGlobalStepDefinitions and add stepDefinitions right next to it. It should match your cypress configuration has set for integrationFolder. We no longer rely on getting information from that file as it was unreliable and problematic across Linux/MacOS/Windows especially since the config file could have been passed as an argument to cypress.`;
+    const errorMessage = `We've tried to resolve your step definitions at ${defaultNonGlobalStepDefinitionsPath}, but that doesn't seem to exist. As of version 2.0.0 it's required to set step_definitions in your cypress-cucumber-preprocessor configuration. Look for nonGlobalStepDefinitions and add stepDefinitions right next to it. It should match your cypress configuration has set for integrationFolder. We no longer rely on getting information from that file as it was unreliable and problematic across Linux/MacOS/Windows especially since the config file could have been passed as an argument to cypress.`;
     expect(stepDefinitionPath).throw(errorMessage);
   });
 
   test("Should throw an error if nonGlobalStepDefinitions and stepDefinitions are set but the folder doesn't exist", () => {
-    const COMICONFIG_FILEPATH = "package.json";
     const stepDefinitions = "cypress/stepDefinitions";
-    const loadMock = jest.fn().mockReturnValue({
-      config: {
-        nonGlobalStepDefinitions: true,
-        stepDefinitions
-      },
-      filepath: COMICONFIG_FILEPATH
-    });
-    cosmiconfig.mockReturnValue({
-      load: loadMock
+    getConfig.mockReturnValue({
+      nonGlobalStepDefinitions: true,
+      stepDefinitions
     });
     fs.existsSync.mockReturnValue(false);
 
-    const errorMessage = `We've tried to resolve your step definitions at ${stepDefinitions}, but that doesn't seem to exist. As of version 2.0.0 it's required to set step_definitions in your cypress-cucumber-preprocessor configuration. Currently your configuration is in: ${COMICONFIG_FILEPATH}. Look for nonGlobalStepDefinitions and add stepDefinitions right next to it. It should match your cypress configuration has set for integrationFolder. We no longer rely on getting information from that file as it was unreliable and problematic across Linux/MacOS/Windows especially since the config file could have been passed as an argument to cypress.`;
+    const errorMessage = `We've tried to resolve your step definitions at ${stepDefinitions}, but that doesn't seem to exist. As of version 2.0.0 it's required to set step_definitions in your cypress-cucumber-preprocessor configuration. Look for nonGlobalStepDefinitions and add stepDefinitions right next to it. It should match your cypress configuration has set for integrationFolder. We no longer rely on getting information from that file as it was unreliable and problematic across Linux/MacOS/Windows especially since the config file could have been passed as an argument to cypress.`;
     expect(stepDefinitionPath).throw(errorMessage);
   });
 
   test("should use the default stepDefinitions path for nonGlobalStepDefinitions", () => {
     const appRoot = process.cwd();
-    const loadMock = jest.fn().mockReturnValue({
-      config: {
-        nonGlobalStepDefinitions: true
-      }
-    });
-    cosmiconfig.mockReturnValue({
-      load: loadMock
+    getConfig.mockReturnValue({
+      nonGlobalStepDefinitions: true
     });
     fs.existsSync.mockReturnValue(true);
 
@@ -71,16 +51,9 @@ describe("load path from step definitions", () => {
 
   test("should use the stepDefinitions path for nonGlobalStepDefinitions", () => {
     const appRoot = process.cwd();
-    const loadMock = jest.fn().mockReturnValue({
-      config: {
-        stepDefinitions: "./e2e/support/step-definitions",
-        nonGlobalStepDefinitions: true
-      }
-    });
-    cosmiconfig.mockReturnValue({
-      load: loadMock
+    getConfig.mockReturnValue({
+      step_definitions: "./e2e/support/step-definitions"
     });
-    fs.existsSync.mockReturnValue(true);
 
     expect(stepDefinitionPath()).to.equal(
       `${appRoot}/e2e/support/step-definitions`
@@ -89,15 +62,9 @@ describe("load path from step definitions", () => {
 
   test("should use the stepDefinitions path", () => {
     const appRoot = process.cwd();
-    const loadMock = jest.fn().mockReturnValue({
-      config: {
-        stepDefinitions: "./e2e/support/step-definitions"
-      }
+    getConfig.mockReturnValue({
+      step_definitions: "./e2e/support/step-definitions"
     });
-    cosmiconfig.mockReturnValue({
-      load: loadMock
-    });
-    fs.existsSync.mockReturnValue(true);
 
     expect(stepDefinitionPath()).to.equal(
       `${appRoot}/e2e/support/step-definitions`
@@ -106,10 +73,6 @@ describe("load path from step definitions", () => {
 
   test("should return default path if stepDefinition are not configured and nonGlobalStepDefinitions are not set", () => {
     const appRoot = process.cwd();
-    cosmiconfig.mockReturnValue({
-      load: jest.fn()
-    });
-
     expect(stepDefinitionPath()).to.equal(
       `${appRoot}/cypress/support/step_definitions`
     );
@@ -117,15 +80,9 @@ describe("load path from step definitions", () => {
 
   test("should allow the backward compatible use of step_definitions in cosmiconfig", () => {
     const appRoot = process.cwd();
-    const loadMock = jest.fn().mockReturnValue({
-      config: {
-        step_definitions: "./e2e/support/step-definitions"
-      }
-    });
-    cosmiconfig.mockReturnValue({
-      load: loadMock
+    getConfig.mockReturnValue({
+      step_definitions: "./e2e/support/step-definitions"
     });
-    fs.existsSync.mockReturnValue(true);
 
     expect(stepDefinitionPath()).to.equal(
       `${appRoot}/e2e/support/step-definitions`