Skip to content

Commit bfdb5af

Browse files
authored
fix(featuresloader): make bundling feature work with repeated non-glo… (#234)
* fix(featuresloader): make bundling feature work with repeated non-global steps * fix(featuresloader): work with hooks fixes #230
1 parent 25e31ac commit bfdb5af

File tree

4 files changed

+71
-25
lines changed

4 files changed

+71
-25
lines changed

.scripts/runOnExample.bash

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@ cd cypress-cucumber-example
55
npm install
66
rm -rf node_modules/cypress-cucumber-preprocessor
77
npm link cypress-cucumber-preprocessor
8-
npm run test
8+
npm run test:all

lib/createTestFromScenario.js

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ const stepTest = function(state, stepDetails, exampleRowData) {
2121
this,
2222
stepDetails,
2323
replaceParameterTags,
24-
exampleRowData
24+
exampleRowData,
25+
state.feature.name
2526
)
2627
)
2728
.then(() => state.onFinishStep(stepDetails, statuses.PASSED));
@@ -37,11 +38,15 @@ const runTest = (scenario, stepsToRun, rowData) => {
3738
const state = window.testState;
3839
return cy
3940
.then(() => state.onStartScenario(scenario, indexedSteps))
40-
.then(() => resolveAndRunBeforeHooks.call(this, scenario.tags))
41+
.then(() =>
42+
resolveAndRunBeforeHooks.call(this, scenario.tags, state.feature.name)
43+
)
4144
.then(() =>
4245
indexedSteps.forEach(step => stepTest.call(this, state, step, rowData))
4346
)
44-
.then(() => resolveAndRunAfterHooks.call(this, scenario.tags))
47+
.then(() =>
48+
resolveAndRunAfterHooks.call(this, scenario.tags, state.feature.name)
49+
)
4550
.then(() => state.onFinishScenario(scenario));
4651
});
4752
};

lib/featuresLoader.js

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,31 @@ const createCucumber = (
2020
) =>
2121
`
2222
${cucumberTemplate}
23-
2423
window.cucumberJson = ${JSON.stringify(cucumberJson)};
2524
25+
var moduleCache = arguments[5];
26+
27+
// Stolen from https://github.com/browserify/browserify/issues/1444
28+
function clearFromCache(instance)
29+
{
30+
for(var key in moduleCache)
31+
{
32+
if(moduleCache[key].exports == instance)
33+
{
34+
delete moduleCache[key];
35+
return;
36+
}
37+
}
38+
throw "could not clear instance from module cache";
39+
}
40+
2641
${globalToRequire.join("\n")}
2742
2843
${specs
2944
.map(
3045
({ spec, filePath, name }) => `
3146
describe(\`${name}\`, function() {
47+
window.currentFeatureName = \`${name}\`
3248
${nonGlobalToRequire &&
3349
nonGlobalToRequire
3450
.find(fileSteps => fileSteps[filePath])
@@ -54,7 +70,7 @@ module.exports = function(_, filePath) {
5470
if (isNonGlobalStepDefinitionsMode()) {
5571
nonGlobalStepDefinitionsToRequire = features.map(featurePath => ({
5672
[featurePath]: getStepDefinitionsPaths(featurePath).map(
57-
sdPath => `require('${sdPath}')`
73+
sdPath => `clearFromCache(require('${sdPath}'))`
5874
)
5975
}));
6076
} else {

lib/resolveStepDefinition.js

Lines changed: 44 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,21 @@ class StepDefinitionRegistry {
3131
this.options.parameterTypeRegistry
3232
);
3333
}
34-
this.definitions.push({ implementation, expression });
34+
35+
this.definitions.push({
36+
implementation,
37+
expression,
38+
featureName: window.currentFeatureName || "___GLOBAL_EXECUTION___"
39+
});
3540
};
3641

37-
this.resolve = (type, text) =>
38-
this.definitions.filter(({ expression }) => expression.match(text))[0];
42+
this.resolve = (type, text, runningFeatureName) =>
43+
this.definitions.filter(
44+
({ expression, featureName }) =>
45+
expression.match(text) &&
46+
(runningFeatureName === featureName ||
47+
featureName === "___GLOBAL_EXECUTION___")
48+
)[0];
3949
}
4050
}
4151

@@ -45,15 +55,21 @@ class HookRegistry {
4555
this.runtime = {};
4656

4757
this.runtime = (tags, implementation) => {
48-
this.definitions.push({ tags, implementation });
58+
this.definitions.push({
59+
tags,
60+
implementation,
61+
featureName: window.currentFeatureName || "___GLOBAL_EXECUTION___"
62+
});
4963
};
5064

51-
this.resolve = scenarioTags =>
65+
this.resolve = (scenarioTags, runningFeatureName) =>
5266
this.definitions.filter(
53-
({ tags }) =>
54-
!tags ||
55-
tags.length === 0 ||
56-
shouldProceedCurrentStep(scenarioTags, tags)
67+
({ tags, featureName }) =>
68+
(!tags ||
69+
tags.length === 0 ||
70+
shouldProceedCurrentStep(scenarioTags, tags)) &&
71+
(runningFeatureName === featureName ||
72+
featureName === "___GLOBAL_EXECUTION___")
5773
);
5874
}
5975
}
@@ -62,10 +78,11 @@ const stepDefinitionRegistry = new StepDefinitionRegistry();
6278
const beforeHookRegistry = new HookRegistry();
6379
const afterHookRegistry = new HookRegistry();
6480

65-
function resolveStepDefinition(step) {
81+
function resolveStepDefinition(step, featureName) {
6682
const stepDefinition = stepDefinitionRegistry.resolve(
6783
step.keyword.toLowerCase().trim(),
68-
step.text
84+
step.text,
85+
featureName
6986
);
7087
return stepDefinition || {};
7188
}
@@ -126,9 +143,9 @@ function resolveStepArgument(argument, exampleRowData, replaceParameterTags) {
126143
return argument;
127144
}
128145

129-
function resolveAndRunHooks(hookRegistry, scenarioTags) {
146+
function resolveAndRunHooks(hookRegistry, scenarioTags, featureName) {
130147
return window.Cypress.Promise.each(
131-
hookRegistry.resolve(scenarioTags),
148+
hookRegistry.resolve(scenarioTags, featureName),
132149
({ implementation }) => implementation.call(this)
133150
);
134151
}
@@ -161,15 +178,23 @@ function parseHookArgs(args) {
161178
}
162179

163180
module.exports = {
164-
resolveAndRunBeforeHooks(scenarioTags) {
165-
return resolveAndRunHooks(beforeHookRegistry, scenarioTags);
181+
resolveAndRunBeforeHooks(scenarioTags, featureName) {
182+
return resolveAndRunHooks(beforeHookRegistry, scenarioTags, featureName);
166183
},
167-
resolveAndRunAfterHooks(scenarioTags) {
168-
return resolveAndRunHooks(afterHookRegistry, scenarioTags);
184+
resolveAndRunAfterHooks(scenarioTags, featureName) {
185+
return resolveAndRunHooks(afterHookRegistry, scenarioTags, featureName);
169186
},
170187
// eslint-disable-next-line func-names
171-
resolveAndRunStepDefinition(step, replaceParameterTags, exampleRowData) {
172-
const { expression, implementation } = resolveStepDefinition(step);
188+
resolveAndRunStepDefinition(
189+
step,
190+
replaceParameterTags,
191+
exampleRowData,
192+
featureName
193+
) {
194+
const { expression, implementation } = resolveStepDefinition(
195+
step,
196+
featureName
197+
);
173198
const stepText = step.text;
174199
if (expression && implementation) {
175200
const argument = resolveStepArgument(

0 commit comments

Comments
 (0)