Skip to content

Commit c08fb58

Browse files
authored
Merge pull request #219 from TheBrainFamily/pr/217
Add Ability to combine multiple feature files into one spec by Darrinholst
2 parents 4527d7a + c3db0c7 commit c08fb58

File tree

13 files changed

+157
-49
lines changed

13 files changed

+157
-49
lines changed

circle.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ jobs:
1717
- run:
1818
name: run tests
1919
command: npm test
20+
- run:
21+
name: slow test run, for sanity
22+
command: npm run test:each
2023
- run:
2124
name: release
2225
command: npm run semantic-release || true

cypress/integration/All.features

Whitespace-only changes.

cypress/integration/AndAndButSteps.feature

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
Feature: Using And and but
2-
Scenario: With an And everything is find
1+
Feature: Using And and But
2+
Scenario: With an And everything is fine
33
Given I do something
44
And Something else
55
Then I happily work
66

7-
Scenario: With a But also the step definition
7+
Scenario: With a But
88
Given I dont do something
99
And it is sunday
1010
Then I stream on twitch

cypress/integration/UsingAnd.feature

Lines changed: 0 additions & 5 deletions
This file was deleted.

cypress/support/step_definitions/usingAnd.js

Lines changed: 0 additions & 15 deletions
This file was deleted.

lib/cucumberTemplate.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
exports.cucumberTemplate = `
2+
const {
3+
resolveAndRunStepDefinition,
4+
defineParameterType,
5+
given,
6+
when,
7+
then,
8+
and,
9+
but,
10+
Before,
11+
After,
12+
defineStep
13+
} = require("cypress-cucumber-preprocessor/lib/resolveStepDefinition");
14+
const Given = (window.Given = window.given = given);
15+
const When = (window.When = window.when = when);
16+
const Then = (window.Then = window.then = then);
17+
const And = (window.And = window.and = and);
18+
const But = (window.But = window.but = but);
19+
window.defineParameterType = defineParameterType;
20+
window.defineStep = defineStep;
21+
const {
22+
createTestsFromFeature
23+
} = require("cypress-cucumber-preprocessor/lib/createTestsFromFeature");
24+
`;

lib/featuresLoader.js

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
const glob = require("glob");
2+
const path = require("path");
3+
const fs = require("fs");
4+
const { Parser } = require("gherkin");
5+
const log = require("debug")("cypress:cucumber");
6+
7+
const { getStepDefinitionsPaths } = require("./getStepDefinitionsPaths");
8+
const { cucumberTemplate } = require("./cucumberTemplate");
9+
const { getCucumberJsonConfig } = require("./getCucumberJsonConfig");
10+
const {
11+
isNonGlobalStepDefinitionsMode
12+
} = require("./isNonGlobalStepDefinitionsMode");
13+
14+
const createCucumber = (
15+
specs,
16+
globalToRequire,
17+
nonGlobalToRequire,
18+
cucumberJson
19+
) =>
20+
`
21+
${cucumberTemplate}
22+
23+
window.cucumberJson = ${JSON.stringify(cucumberJson)};
24+
25+
${globalToRequire.join("\n")}
26+
27+
${specs
28+
.map(
29+
({ spec, filePath, name }) => `
30+
describe(\`${name}\`, function() {
31+
${nonGlobalToRequire &&
32+
nonGlobalToRequire
33+
.find(fileSteps => fileSteps[filePath])
34+
[filePath].join("\n")}
35+
36+
createTestsFromFeature('${path.basename(filePath)}', \`${spec}\`);
37+
})
38+
`
39+
)
40+
.join("\n")}
41+
`;
42+
43+
module.exports = function(_, filePath) {
44+
log("compiling", filePath);
45+
46+
const features = glob.sync(`${path.dirname(filePath)}/**/*.feature`);
47+
48+
let globalStepDefinitionsToRequire = [];
49+
let nonGlobalStepDefinitionsToRequire;
50+
51+
if (isNonGlobalStepDefinitionsMode()) {
52+
nonGlobalStepDefinitionsToRequire = features.map(featurePath => ({
53+
[featurePath]: getStepDefinitionsPaths(featurePath).map(
54+
sdPath => `require('${sdPath}')`
55+
)
56+
}));
57+
} else {
58+
globalStepDefinitionsToRequire = [
59+
...new Set(
60+
features.reduce(
61+
requires =>
62+
requires.concat(
63+
getStepDefinitionsPaths(filePath).map(
64+
sdPath => `require('${sdPath}')`
65+
)
66+
),
67+
[]
68+
)
69+
)
70+
];
71+
}
72+
73+
const specs = features
74+
.map(featurePath => ({
75+
spec: fs.readFileSync(featurePath).toString(),
76+
filePath: featurePath
77+
}))
78+
.map(feature =>
79+
Object.assign({}, feature, {
80+
name: new Parser().parse(feature.spec.toString()).feature.name
81+
})
82+
);
83+
84+
return createCucumber(
85+
specs,
86+
globalStepDefinitionsToRequire,
87+
nonGlobalStepDefinitionsToRequire,
88+
getCucumberJsonConfig()
89+
);
90+
};

lib/getCucumberJsonConfig.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
const cosmiconfig = require("cosmiconfig");
2+
const log = require("debug")("cypress:cucumber");
3+
4+
exports.getCucumberJsonConfig = () => {
5+
const explorer = cosmiconfig("cypress-cucumber-preprocessor", { sync: true });
6+
const loaded = explorer.load();
7+
8+
const cucumberJson =
9+
loaded && loaded.config && loaded.config.cucumberJson
10+
? loaded.config.cucumberJson
11+
: { generate: false };
12+
log("cucumber.json", JSON.stringify(cucumberJson));
13+
14+
return cucumberJson;
15+
};

lib/getStepDefinitionsPaths.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ const getStepDefinitionsPaths = filePath => {
1111
const nonGlobalPattern = `${getStepDefinitionPathsFrom(
1212
filePath
1313
)}/**/*.+(js|ts)`;
14-
1514
const commonPath =
1615
loaded.config.commonPath || `${stepDefinitionPath()}/common/`;
1716
const commonDefinitionsPattern = `${commonPath}**/*.+(js|ts)`;

lib/index.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ const browserify = require("@cypress/browserify-preprocessor");
55
const log = require("debug")("cypress:cucumber");
66
const chokidar = require("chokidar");
77
const compile = require("./loader.js");
8+
const compileFeatures = require("./featuresLoader.js");
89
const stepDefinitionPath = require("./stepDefinitionPath.js");
910

1011
const transform = file => {
@@ -15,7 +16,10 @@ const transform = file => {
1516
}
1617

1718
function end() {
18-
if (file.match(".feature$")) {
19+
if (file.match(".features$")) {
20+
log("compiling features ", file);
21+
this.queue(compileFeatures(data, file));
22+
} else if (file.match(".feature$")) {
1923
log("compiling feature ", file);
2024
this.queue(compile(data, file));
2125
} else {

0 commit comments

Comments
 (0)