Skip to content

Commit 9125183

Browse files
committed
Allow features in arbitrary locations
This fixes #1225 [1]. [1] #1225
1 parent c226178 commit 9125183

File tree

6 files changed

+51
-57
lines changed

6 files changed

+51
-57
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ Other changees:
2222

2323
- Support project directories containing square brackets, EG. `/home/[foo] my project/`, relates to [#1196](https://github.com/badeball/cypress-cucumber-preprocessor/discussions/1196).
2424

25+
- Allow features in arbitrary locations, fixes [#1225](https://github.com/badeball/cypress-cucumber-preprocessor/issues/1225).
26+
2527
## v20.1.2
2628

2729
- Updated all dependencies, including esbuild, relates to [#1068](https://github.com/badeball/cypress-cucumber-preprocessor/issues/1068).

docs/step-definitions.md

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
# Step definitions
44

5-
Step definitions are resolved using search paths that are configurable through the `stepDefinitions` property. The preprocessor uses [cosmiconfig](https://github.com/davidtheclark/cosmiconfig), which means you can place configuration options in EG. `.cypress-cucumber-preprocessorrc.json` or `package.json`. The default search paths are shown below.
5+
Step definitions are resolved using search paths that are configurable through the `stepDefinitions` property. The preprocessor uses [cosmiconfig](https://github.com/davidtheclark/cosmiconfig), which means you can place configuration options in EG. `.cypress-cucumber-preprocessorrc.json` or `package.json`. The default (almost true[^1]) search paths are shown below.
66

77
```json
88
{
@@ -147,3 +147,36 @@ All of these will be used to replace `[filepart]`. Thus, a single configuration
147147
The library makes use of [glob](https://github.com/isaacs/node-glob) to turn patterns into a list of files. This has some implications, explained below (list is non-exhaustive and will be expanded on demand).
148148

149149
* Single term inside braces, EG. `foo/bar.{js}`, doesn't work as you might expect, ref. https://github.com/isaacs/node-glob/issues/434.
150+
151+
[^1]: I claim that the default configuration is of that below and this is almost always true.
152+
153+
```json
154+
{
155+
"stepDefinitions": [
156+
"cypress/e2e/[filepath]/**/*.{js,ts}",
157+
"cypress/e2e/[filepath].{js,ts}",
158+
"cypress/support/step_definitions/**/*.{js,ts}",
159+
]
160+
}
161+
```
162+
163+
The reality is a bit more complex, in order to support a variety of use-cases out-of-the-box.
164+
Most users will place their feature files in `cypress/e2e` and in those cases, the default
165+
configuration will be that of my claim.
166+
167+
However, users that decide on a different location, let's say. `cypress/features` - in their
168+
case, the default behavior of the preprocessor will be _as if_ you configured `stepDefinitions`
169+
shown like below.
170+
171+
```json
172+
{
173+
"stepDefinitions": [
174+
"cypress/features/[filepath]/**/*.{js,ts}",
175+
"cypress/features/[filepath].{js,ts}",
176+
"cypress/support/step_definitions/**/*.{js,ts}",
177+
]
178+
}
179+
```
180+
181+
Essentially, the first part of the two first elements, is determined finding out the common
182+
ancestor path of all your feature files and thus the default configuration is dynamic.

lib/step-definitions.test.ts

Lines changed: 6 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -38,15 +38,12 @@ function example(
3838
cypressConfiguration.projectRoot
3939
}`, () => {
4040
const actual = getStepDefinitionPatterns(
41-
{
42-
cypress: cypressConfiguration,
43-
preprocessor: combineIntoConfiguration(
44-
preprocessorConfiguration,
45-
{},
46-
cypressConfiguration,
47-
implicitIntegrationFolder,
48-
),
49-
},
41+
combineIntoConfiguration(
42+
preprocessorConfiguration,
43+
{},
44+
cypressConfiguration,
45+
implicitIntegrationFolder,
46+
),
5047
filepath,
5148
);
5249

@@ -122,21 +119,4 @@ describe("getStepDefinitionPatterns()", () => {
122119
"cypress/e2e/step_definitions/*.ts",
123120
],
124121
);
125-
126-
it("should error when provided a path not within cwd", () => {
127-
assert.throws(() => {
128-
getStepDefinitionPatterns(
129-
{
130-
cypress: {
131-
projectRoot: "/baz",
132-
},
133-
preprocessor: {
134-
stepDefinitions: [],
135-
implicitIntegrationFolder: "/foo/bar/cypress/e2e",
136-
},
137-
},
138-
"/foo/bar/cypress/e2e/baz.feature",
139-
);
140-
}, "/foo/bar/cypress/features/baz.feature is not within /baz");
141-
});
142122
});

lib/step-definitions.ts

Lines changed: 7 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,9 @@ import util from "util";
66

77
import assert from "assert";
88

9-
import isPathInside from "is-path-inside";
10-
119
import debug from "./helpers/debug";
1210

13-
import {
14-
ICypressRuntimeConfiguration,
15-
IPreprocessorConfiguration,
16-
} from "./preprocessor-configuration";
11+
import { IPreprocessorConfiguration } from "./preprocessor-configuration";
1712

1813
export async function getStepDefinitionPaths(
1914
prjectRoot: string,
@@ -55,27 +50,15 @@ export function pathParts(relativePath: string): string[] {
5550
}
5651

5752
export function getStepDefinitionPatterns(
58-
configuration: {
59-
cypress: Pick<ICypressRuntimeConfiguration, "projectRoot">;
60-
preprocessor: Pick<
61-
IPreprocessorConfiguration,
62-
"stepDefinitions" | "implicitIntegrationFolder"
63-
>;
64-
},
53+
configuration: Pick<
54+
IPreprocessorConfiguration,
55+
"stepDefinitions" | "implicitIntegrationFolder"
56+
>,
6557
filepath: string,
6658
): string[] {
67-
const projectRoot = configuration.cypress.projectRoot;
68-
69-
if (!isPathInside(filepath, projectRoot)) {
70-
throw new Error(`${filepath} is not inside ${projectRoot}`);
71-
}
72-
7359
const filepathReplacement = glob.escape(
7460
trimFeatureExtension(
75-
path.relative(
76-
configuration.preprocessor.implicitIntegrationFolder,
77-
filepath,
78-
),
61+
path.relative(configuration.implicitIntegrationFolder, filepath),
7962
),
8063
{ windowsPathsNoEscape: true },
8164
);
@@ -86,7 +69,7 @@ export function getStepDefinitionPatterns(
8669

8770
debug(`replacing [filepart] with ${util.inspect(parts)}`);
8871

89-
const stepDefinitions = [configuration.preprocessor.stepDefinitions].flat();
72+
const stepDefinitions = [configuration.stepDefinitions].flat();
9073

9174
return stepDefinitions.flatMap((pattern) => {
9275
if (pattern.includes("[filepath]") && pattern.includes("[filepart]")) {

lib/template.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -84,14 +84,11 @@ export async function compile(
8484
const { stepDefinitions } = preprocessor;
8585

8686
debug(
87-
`resolving step definitions using template(s) ${inspect(stepDefinitions)}`,
87+
`resolving step definitio|ns using template(s) ${inspect(stepDefinitions)}`,
8888
);
8989

9090
const stepDefinitionPatterns = getStepDefinitionPatterns(
91-
{
92-
cypress: configuration,
93-
preprocessor,
94-
},
91+
preprocessor,
9592
uri,
9693
).map((pattern) => ensureIsRelative(configuration.projectRoot, pattern));
9794

package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,6 @@
7676
"error-stack-parser": "^2.1.4",
7777
"find-cypress-specs": "^1.45.2",
7878
"glob": "^10.4.5",
79-
"is-path-inside": "^3.0.3",
8079
"mocha": "^10.7.0",
8180
"seedrandom": "^3.0.5",
8281
"source-map": "^0.7.4",

0 commit comments

Comments
 (0)