Thank you for building this preprocessor and latest update to define nonGlobalStepBaseDir is very helpful.
With the current setup tests are working well. Configurations are set as following with feature files placed in the cypress/integration directory:
"cypress-cucumber-preprocessor": {
"nonGlobalStepDefinitions": true,
"commonPath":"../../../shared",
"nonGlobalStepBaseDir": "cypress/integration/steps/onboarding/customer"
}
}
I would like to move the feature files to another directory say:
cypress/integration/features/onboarding/customer
Moving the feature files from cypress/integration to another path gives step implementation missing error.
Is it possible move the feature files to another directory with nonGlobalStepBaseDir path defined?
To be able to define feature file location similar to step definitions.
This still seems to be an issue after #319 was merged.
With default cypress/integration path as integrationFolder in cypress.json (that is NOT specifying one). Then using
"cypress-cucumber-preprocessor": {
"nonGlobalStepDefinitions": true,
"nonGlobalStepBaseDir": "test/cypress/integration"
}
}
will result in .feature files being found correctly in cypress/integration with step definitions found in test/cypress/integration.
However, with test/cypress/integration path as integrationFolder in cypress.json and using
"cypress-cucumber-preprocessor": {
"nonGlobalStepDefinitions": true,
"nonGlobalStepBaseDir": "cypress/integration"
}
}
Then .feature files are found correctly but step definitions are NOT found. Unless "nonGlobalStepDefinitions": false
So it seems if feature files are not in the default cypress folder then step files can not be located away from the same folder.
It should be possible to have feature files in an arbitrary location and specify a separate arbitrary location for the base dir of step definitions whilst still using "nonGlobalStepDefinitions": true
cypress
-Integration
-sign-in
-sign-in.js <-- step definition
tests
-features
- sign-in.feature <-- feature file
cypress.json
{
"integrationFolder": "tests/features",
"testFiles": ["**/*.feature"]
}
package.json
"cypress-cucumber-preprocessor": {
"nonGlobalStepDefinitions": true,
"nonGlobalStepBaseDir": "cypress/integration"
}
@bkapadia01 are you still having difficulty with your original question?
to have .feature files in a different directory with the step definition, set the stepDefinitions exacly the same as your cypress integrationFolder and nonGlobalStepBaseDir to path to step definition folder.
See last section for example
@goesbysteve I think I found the problem to the current behavior. There is this block of code in cypress-cucumber-preprocessor/lib/getStepDefinitionsPaths.js file which will list all the files the modules need to require (which is the step definitions)
const getStepDefinitionsPaths = (filePath) => {
const appRoot = process.cwd();
let paths = [];
const config = getConfig();
if (config && config.nonGlobalStepDefinitions) {
let nonGlobalPath = getStepDefinitionPathsFrom(filePath);
// nonGlobalPath == feature file path without .feature
let commonPath = config.commonPath || `${stepDefinitionPath()}/common/`;
if (config.commonPath) {
commonPath = path.resolve(appRoot, commonPath);
}
if (config.nonGlobalStepBaseDir) {
const stepBase = `${appRoot}/${config.nonGlobalStepBaseDir}`;
nonGlobalPath = nonGlobalPath.replace(stepDefinitionPath(), stepBase);
commonPath = `${stepBase}/${config.commonPath || "common/"}`;
}
const nonGlobalPattern = `${nonGlobalPath}/**/*.+(js|ts)`;
const commonDefinitionsPattern = `${commonPath}**/*.+(js|ts)`;
paths = paths.concat(
glob.sync(nonGlobalPattern),
glob.sync(commonDefinitionsPattern)
);
} else {
const pattern = `${stepDefinitionPath()}/**/*.+(js|ts)`;
paths = paths.concat(glob.sync(pattern));
}
return paths;
};
the problem is in this block of code
if (config.nonGlobalStepBaseDir) {
const stepBase = `${appRoot}/${config.nonGlobalStepBaseDir}`;
nonGlobalPath = nonGlobalPath.replace(stepDefinitionPath(), stepBase);
commonPath = `${stepBase}/${config.commonPath || "common/"}`;
}
that code will run when we specify nonGlobalStepBaseDir in the config. What that code does is get the path to your nonGlobalstepBaseDir change your step definitions path to that and also change the common folder path.
But here's the problem, the second line in the if block replace the current nonGlobalPath path that match with the result of stepDefinitionPath() to stepBase. The value in nonGlobalPath is the path to the .feature file without the extension.
The stepDefinitionPath function supposed to return the path to step definitions. But currently this function will return
nonGlobalStepDefinitions is true, then return cwd + config.stepDefinitions if it is not undefined or return cwd + /cypress/integrationnonGlobalStepDefinitions is false, then return cwd + config.stepDefinitions if it is not undefined/cypress/support/step_definitionsSo basically it will return cwd + stepDefinitions or /cypress/integration or /cypress/support/step_definitions, but the nonGlobalPath in the if block might not have all these value if our feature files is not in /cypress/integration or /cypress/support/step_definitions or in the directory we specify in the stepDefinitions (which supposed to be our step definitions folder), so the .replace function won't change anything and the nonGlobalPath will still have the path to your feature files without the extension. But the common folder is correct since it use the stepBase which is from the nonGlobalStepBaseDir.
To have the .feature files in a complete different directory with the step definitions, all we need to do is to specify the path to the root of step definitions file in nonGlobalStepBaseDir and the path to the root of .feature files in stepDefinitions.
Make sure the path to step definition still follow the cypress-cucumber-preprocessor convention
# feature file location
path/to/you/project/test/feature_files/feature_a/interesting_feature.feature
# step definition file location
path/to/your/project/implementations/step_definitions/feature_a/interesting_feature/folder-1/step_a.step.js
# common step definition file location
path/to/your/project/implementations/step_definitions/common/common.step.js
your cypress-cucumber-preprocessor config would looks like this:
"cypress-cucumber-preprocessor": {
"nonGlobalStepDefinitions": true,
"nonGlobalStepBaseDir": "implementations/step_definitions",
"stepDefinitions": "test/feature_files"
}
your cypress config would looks like this:
{
...
"integrationFolder": "test/feature_files",
...
}
the ... means there is other configs there.
You can check the stepDefinitionPath function at cypress-cucumber-preprocessor/lib/stepDefinitionPath.js
I did not open a PR since I'm not sure which solution to use. My solution is:
stepDefinitions to featureFilesPath but not sure if it will break anyintegrationFolder config value and use that for the .replace valueAny solution for this? I'm stuck too with same need: feature files in a totally different path of steps.
update:
I solved in this way:
// package.json
"cypress-cucumber-preprocessor": {
"nonGlobalStepDefinitions": true,
"nonGlobalStepBaseDir": "cypress/integration",
"step_definitions": "path/to/feature/files"
}
// cypress.json
{
"testFiles": "**/*.{feature,features}",
"integrationFolder": "path/to/feature/files"
}
with this configuration you can put feature files and step definition files in two totally different paths