Skip to content

Commit 1384c1b

Browse files
committed
Calculate and use an implicit integration folder
This is similar to what Cypress does with some of their stuff [1]. More importantly, it allows Cypress v10-users to continue with hierarchies they had pre-v10. Fixes #748. [1] https://docs.cypress.io/guides/references/migration-guide#Generated-Files
1 parent 30f93e6 commit 1384c1b

11 files changed

+131
-113
lines changed

CHANGELOG.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,34 @@ All notable changes to this project will be documented in this file.
44

55
## Unreleased
66

7+
Breaking changes:
8+
9+
- A minor change to step definitions has been introduced, affecting users of Cypress v10 or higher. When upgrading to v11.0.0 of the processor, users was instructed to [remove certain prefixes](https://github.com/badeball/cypress-cucumber-preprocessor/releases/tag/v11.0.0) from their step definitions. This is no longer required and said prefixes can be re-introduced when upgrading to v12.0.0 of the preprocessor. In other words, if your configuration looks like this
10+
11+
```json
12+
{
13+
"stepDefinitions": [
14+
"[filepath].{js,ts}",
15+
"cypress/support/step_definitions/**/*.{js,ts}"
16+
]
17+
}
18+
```
19+
20+
.. then it should now look like this (notice the addition of `cypress/e2e`)
21+
22+
```json
23+
{
24+
"stepDefinitions": [
25+
"cypress/e2e/[filepath].{js,ts}",
26+
"cypress/support/step_definitions/**/*.{js,ts}"
27+
]
28+
}
29+
```
30+
31+
Note: Step definitions doesn't necessarily have to be put in `cypress/e2e` and alongside your feature files. They can be contained in an entirely separate directory, if desired. This fixes [#748](https://github.com/badeball/cypress-cucumber-preprocessor/issues/748).
32+
33+
Other changes:
34+
735
- Updated all `@cucumber/*` dependencies.
836

937
- Added native support for HTML reports using `@cucumber/html-formatter`, fixes [#780](https://github.com/badeball/cypress-cucumber-preprocessor/issues/780).

docs/step-definitions.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ Step definitions are resolved using search paths that are configurable through t
55
```json
66
{
77
"stepDefinitions": [
8-
"[filepath]/**/*.{js,ts}",
9-
"[filepath].{js,ts}",
8+
"cypress/e2e/[filepath]/**/*.{js,ts}",
9+
"cypress/e2e/[filepath].{js,ts}",
1010
"cypress/support/step_definitions/**/*.{js,ts}",
1111
]
1212
}

features/step_definitions/cli_steps.ts

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -142,24 +142,6 @@ Then("the output should contain", function (content) {
142142
);
143143
});
144144

145-
Then("if pre-v10, the output should contain", function (content) {
146-
if (isPre10()) {
147-
assert.match(
148-
this.lastRun.stdout.replaceAll("\\", "/"),
149-
new RegExp(rescape(content))
150-
);
151-
}
152-
});
153-
154-
Then("if post-v10, the output should contain", function (content) {
155-
if (isPost10()) {
156-
assert.match(
157-
this.lastRun.stdout.replaceAll("\\", "/"),
158-
new RegExp(rescape(content))
159-
);
160-
}
161-
});
162-
163145
Then(
164146
"it should appear to have skipped the scenario {string}",
165147
function (scenarioName) {

features/undefined_step.feature

Lines changed: 2 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ Feature: undefined Steps
99
"""
1010
When I run cypress
1111
Then it fails
12-
And if pre-v10, the output should contain
12+
And the output should contain
1313
"""
1414
Step implementation missing for "an undefined step".
1515
@@ -27,24 +27,6 @@ Feature: undefined Steps
2727
2828
These patterns matched **no files** containing step definitions. This almost certainly means that you have misconfigured `stepDefinitions`.
2929
"""
30-
And if post-v10, the output should contain
31-
"""
32-
Step implementation missing for "an undefined step".
33-
34-
We tried searching for files containing step definitions using the following search pattern templates:
35-
36-
- [filepath]/**/*.{js,mjs,ts,tsx}
37-
- [filepath].{js,mjs,ts,tsx}
38-
- cypress/support/step_definitions/**/*.{js,mjs,ts,tsx}
39-
40-
These templates resolved to the following search patterns:
41-
42-
- cypress/e2e/a/**/*.{js,mjs,ts,tsx}
43-
- cypress/e2e/a.{js,mjs,ts,tsx}
44-
- cypress/support/step_definitions/**/*.{js,mjs,ts,tsx}
45-
46-
These patterns matched **no files** containing step definitions. This almost certainly means that you have misconfigured `stepDefinitions`.
47-
"""
4830

4931
Scenario: step definitions exist, but none matching
5032
Given a file named "cypress/e2e/a.feature" with:
@@ -60,7 +42,7 @@ Feature: undefined Steps
6042
"""
6143
When I run cypress
6244
Then it fails
63-
And if pre-v10, the output should contain
45+
And the output should contain
6446
"""
6547
Step implementation missing for "an undefined step".
6648
@@ -82,25 +64,3 @@ Feature: undefined Steps
8264
8365
However, none of these files contained a step definition matching "an undefined step".
8466
"""
85-
And if post-v10, the output should contain
86-
"""
87-
Step implementation missing for "an undefined step".
88-
89-
We tried searching for files containing step definitions using the following search pattern templates:
90-
91-
- [filepath]/**/*.{js,mjs,ts,tsx}
92-
- [filepath].{js,mjs,ts,tsx}
93-
- cypress/support/step_definitions/**/*.{js,mjs,ts,tsx}
94-
95-
These templates resolved to the following search patterns:
96-
97-
- cypress/e2e/a/**/*.{js,mjs,ts,tsx}
98-
- cypress/e2e/a.{js,mjs,ts,tsx}
99-
- cypress/support/step_definitions/**/*.{js,mjs,ts,tsx}
100-
101-
These patterns matched the following files:
102-
103-
- cypress/support/step_definitions/steps.js
104-
105-
However, none of these files contained a step definition matching "an undefined step".
106-
"""

lib/add-cucumber-preprocessor-plugin.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ let currentTestStepStartedId: string;
7171
let currentSpecMessages: messages.Envelope[];
7272

7373
export async function beforeRunHandler(config: Cypress.PluginConfigOptions) {
74-
const preprocessor = await resolve(config, config.env);
74+
const preprocessor = await resolve(config, config.env, "/");
7575

7676
if (!preprocessor.messages.enabled) {
7777
return;
@@ -86,7 +86,7 @@ export async function beforeRunHandler(config: Cypress.PluginConfigOptions) {
8686
}
8787

8888
export async function afterRunHandler(config: Cypress.PluginConfigOptions) {
89-
const preprocessor = await resolve(config, config.env);
89+
const preprocessor = await resolve(config, config.env, "/");
9090

9191
if (!preprocessor.json.enabled && !preprocessor.html.enabled) {
9292
return;
@@ -191,7 +191,7 @@ export async function afterSpecHandler(
191191
spec: Cypress.Spec,
192192
results: CypressCommandLine.RunResult
193193
) {
194-
const preprocessor = await resolve(config, config.env);
194+
const preprocessor = await resolve(config, config.env, "/");
195195

196196
const messagesPath = ensureIsAbsolute(
197197
config.projectRoot,
@@ -231,7 +231,7 @@ export async function afterScreenshotHandler(
231231
config: Cypress.PluginConfigOptions,
232232
details: Cypress.ScreenshotDetails
233233
) {
234-
const preprocessor = await resolve(config, config.env);
234+
const preprocessor = await resolve(config, config.env, "/");
235235

236236
if (!preprocessor.messages.enabled || !currentSpecMessages) {
237237
return details;
@@ -273,7 +273,7 @@ export default async function addCucumberPreprocessorPlugin(
273273
config: Cypress.PluginConfigOptions,
274274
options: AddOptions = {}
275275
) {
276-
const preprocessor = await resolve(config, config.env);
276+
const preprocessor = await resolve(config, config.env, "/");
277277

278278
if (!options.omitBeforeRunHandler) {
279279
on("before:run", () => beforeRunHandler(config));

lib/preprocessor-configuration.test.ts

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ describe("resolve()", () => {
1616
const { stepDefinitions } = await resolve(
1717
DUMMY_POST10_CONFIG,
1818
{ stepDefinitions: "foo/bar/**" },
19+
"/",
1920
() => null
2021
);
2122

@@ -25,19 +26,29 @@ describe("resolve()", () => {
2526
it("overriding messages.enabled (1)", async () => {
2627
const {
2728
messages: { enabled },
28-
} = await resolve(DUMMY_POST10_CONFIG, { messagesEnabled: "" }, () => ({
29-
messages: { enabled: true },
30-
}));
29+
} = await resolve(
30+
DUMMY_POST10_CONFIG,
31+
{ messagesEnabled: "" },
32+
"/",
33+
() => ({
34+
messages: { enabled: true },
35+
})
36+
);
3137

3238
assert.strictEqual(enabled, true);
3339
});
3440

3541
it("overriding messages.enabled (2)", async () => {
3642
const {
3743
messages: { enabled },
38-
} = await resolve(DUMMY_POST10_CONFIG, { messagesEnabled: "true" }, () => ({
39-
messages: { enabled: false },
40-
}));
44+
} = await resolve(
45+
DUMMY_POST10_CONFIG,
46+
{ messagesEnabled: "true" },
47+
"/",
48+
() => ({
49+
messages: { enabled: false },
50+
})
51+
);
4152

4253
assert.strictEqual(enabled, true);
4354
});
@@ -48,6 +59,7 @@ describe("resolve()", () => {
4859
} = await resolve(
4960
DUMMY_POST10_CONFIG,
5061
{ messagesEnabled: "foobar" },
62+
"/",
5163
() => ({
5264
messages: { enabled: false },
5365
})
@@ -59,9 +71,14 @@ describe("resolve()", () => {
5971
it("overriding messages.enabled (4)", async () => {
6072
const {
6173
messages: { enabled },
62-
} = await resolve(DUMMY_POST10_CONFIG, { messagesEnabled: true }, () => ({
63-
messages: { enabled: false },
64-
}));
74+
} = await resolve(
75+
DUMMY_POST10_CONFIG,
76+
{ messagesEnabled: true },
77+
"/",
78+
() => ({
79+
messages: { enabled: false },
80+
})
81+
);
6582

6683
assert.strictEqual(enabled, true);
6784
});
@@ -72,6 +89,7 @@ describe("resolve()", () => {
7289
} = await resolve(
7390
DUMMY_POST10_CONFIG,
7491
{ messagesEnabled: "false" },
92+
"/",
7593
() => ({
7694
messages: { enabled: true },
7795
})
@@ -86,6 +104,7 @@ describe("resolve()", () => {
86104
} = await resolve(
87105
DUMMY_POST10_CONFIG,
88106
{ messagesEnabled: "false" },
107+
"/",
89108
() => ({
90109
messages: { enabled: true },
91110
})
@@ -97,9 +116,14 @@ describe("resolve()", () => {
97116
it("overriding messages.enabled (7)", async () => {
98117
const {
99118
messages: { enabled },
100-
} = await resolve(DUMMY_POST10_CONFIG, { messagesEnabled: false }, () => ({
101-
messages: { enabled: true },
102-
}));
119+
} = await resolve(
120+
DUMMY_POST10_CONFIG,
121+
{ messagesEnabled: false },
122+
"/",
123+
() => ({
124+
messages: { enabled: true },
125+
})
126+
);
103127

104128
assert.strictEqual(enabled, false);
105129
});

lib/preprocessor-configuration.ts

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,7 @@ export interface IPreprocessorConfiguration {
365365
};
366366
readonly filterSpecs?: boolean;
367367
readonly omitFiltered?: boolean;
368+
readonly implicitIntegrationFolder: string;
368369
}
369370

370371
export interface IEnvironmentOverrides {
@@ -381,23 +382,18 @@ export interface IEnvironmentOverrides {
381382
omitFiltered?: boolean;
382383
}
383384

384-
export const DEFAULT_PRE_10_STEP_DEFINITIONS = [
385+
export const DEFAULT_STEP_DEFINITIONS = [
385386
"[integration-directory]/[filepath]/**/*.{js,mjs,ts,tsx}",
386387
"[integration-directory]/[filepath].{js,mjs,ts,tsx}",
387388
"cypress/support/step_definitions/**/*.{js,mjs,ts,tsx}",
388389
];
389390

390-
export const DEFAULT_POST_10_STEP_DEFINITIONS = [
391-
"[filepath]/**/*.{js,mjs,ts,tsx}",
392-
"[filepath].{js,mjs,ts,tsx}",
393-
"cypress/support/step_definitions/**/*.{js,mjs,ts,tsx}",
394-
];
395-
396391
export class PreprocessorConfiguration implements IPreprocessorConfiguration {
397392
constructor(
398393
private explicitValues: Partial<IPreprocessorConfiguration>,
399394
private environmentOverrides: IEnvironmentOverrides,
400-
private cypressConfiguration: ICypressConfiguration
395+
private cypressConfiguration: ICypressConfiguration,
396+
public implicitIntegrationFolder: string
401397
) {}
402398

403399
get stepDefinitions() {
@@ -411,16 +407,17 @@ export class PreprocessorConfiguration implements IPreprocessorConfiguration {
411407

412408
const config = this.cypressConfiguration;
413409

414-
if ("specPattern" in config) {
415-
return DEFAULT_POST_10_STEP_DEFINITIONS;
416-
} else {
417-
return DEFAULT_PRE_10_STEP_DEFINITIONS.map((pattern) =>
418-
pattern.replace(
419-
"[integration-directory]",
420-
ensureIsRelative(config.projectRoot, config.integrationFolder)
410+
return DEFAULT_STEP_DEFINITIONS.map((pattern) =>
411+
pattern.replace(
412+
"[integration-directory]",
413+
ensureIsRelative(
414+
config.projectRoot,
415+
"integrationFolder" in config
416+
? config.integrationFolder
417+
: this.implicitIntegrationFolder
421418
)
422-
);
423-
}
419+
)
420+
);
424421
}
425422

426423
get messages() {
@@ -503,6 +500,7 @@ export type ConfigurationFileResolver = (
503500
export async function resolve(
504501
cypressConfig: ICypressConfiguration,
505502
environment: Record<string, unknown>,
503+
implicitIntegrationFolder: string,
506504
configurationFileResolver: ConfigurationFileResolver = cosmiconfigResolver
507505
) {
508506
const result = await configurationFileResolver(cypressConfig.projectRoot);
@@ -530,15 +528,17 @@ export async function resolve(
530528
return new PreprocessorConfiguration(
531529
config,
532530
environmentOverrides,
533-
cypressConfig
531+
cypressConfig,
532+
implicitIntegrationFolder
534533
);
535534
} else {
536535
debug("resolved no configuration");
537536

538537
return new PreprocessorConfiguration(
539538
{},
540539
environmentOverrides,
541-
cypressConfig
540+
cypressConfig,
541+
implicitIntegrationFolder
542542
);
543543
}
544544
}

0 commit comments

Comments
 (0)