@g_package/jest-cucumber-fusion 3.0.4 → 3.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +137 -436
- package/dist/index.d.cts +4 -4
- package/package.json +21 -5
- package/src/index.d.ts +4 -4
package/README.md
CHANGED
|
@@ -3,43 +3,41 @@
|
|
|
3
3
|
Write Cucumber feature files and run them as Jest tests, without the scaffolding.
|
|
4
4
|
|
|
5
5
|
[](https://github.com/gotreasa/jest-cucumber-fusion/actions?query=workflow%3A%22Continuous+Integration%22)
|
|
6
|
-
[](https://codecov.io/gh/gotreasa/jest-cucumber-fusion)
|
|
7
7
|
|
|
8
8
|
[](https://www.npmjs.com/package/@g_package/jest-cucumber-fusion)
|
|
9
9
|
[](https://www.npmjs.com/package/@g_package/jest-cucumber-fusion)
|
|
10
10
|
[](https://github.com/semantic-release/semantic-release)
|
|
11
11
|
|
|
12
|
-
|
|
13
12
|
## Overview
|
|
14
|
-
Jest Cucumber Fusion runs your Cucumber feature files as Jest tests. You write the feature file in Gherkin, and a step definition file with a `Given`, `When`, `Then`, `And` or `But` definition for each step. A `Fusion` call at the end of the step definition file links the two: Fusion reads the feature and creates one Jest test per scenario, so you write no `describe` or `it` blocks yourself. Everything else is plain Jest: `expect`, mocks, coverage and reporting.
|
|
15
|
-
|
|
16
|
-
The style of this package began with [Jest-cucumber](https://github.com/bencompton/jest-cucumber), which it was originally built on top of. Since version 3 it no longer depends on that package: it runs on Jest and [@cucumber/gherkin](https://github.com/cucumber/gherkin) directly, and owns the whole test lifecycle itself.
|
|
17
13
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
## Motivation
|
|
14
|
+
Jest Cucumber Fusion runs your Cucumber feature files as Jest tests. You write the feature file in Gherkin, and a step definition file with a `Given`, `When`, `Then`, `And` or `But` definition for each step. A `Fusion` call at the end of the step definition file links the two: Fusion reads the feature and creates one Jest test per scenario, so you write no `describe` or `it` blocks yourself. Everything else is plain Jest: `expect`, mocks, coverage and reporting.
|
|
21
15
|
|
|
22
|
-
|
|
23
|
-
- a Cucumber Feature file with gherkin sentences
|
|
24
|
-
- a Cucumber Step definition file with your javascript validation code, ended with the `Fusion` function to link the two
|
|
16
|
+
**New to Gherkin?** A feature file describes behaviour in plain sentences. Each feature file holds one `Feature`, and each `Scenario` in it is one example of that behaviour. Each line of a scenario starting with `Given`, `When`, `Then`, `And` or `But` is a step, and a step definition is the code that runs for one step. The [Gherkin reference](https://cucumber.io/docs/gherkin/reference/) covers the full syntax.
|
|
25
17
|
|
|
18
|
+
**Upgrading** from version 2, or from `jest-cucumber-fusion` 0.8.x? Your feature and step definition files keep their shape, and step files written as CommonJS keep their `require`. [Migrating to version 3](./docs/Migrating.md) lists what changes.
|
|
26
19
|
|
|
20
|
+
**Know Cucumber already?** [If you know Cucumber](#if-you-know-cucumber) lists what differs.
|
|
27
21
|
|
|
28
22
|
## Getting Started
|
|
29
23
|
|
|
30
|
-
These steps set up a project whose files are ES modules (they use `import` and `export`), which is the recommended way to use Fusion. If your project is CommonJS (it uses `require`), or you need Node 18, follow
|
|
24
|
+
These steps set up a project whose files are ES modules (they use `import` and `export`), which is the recommended way to use Fusion: ES modules are the module format Node and Jest are moving to, and Fusion's own source is written in them. If your project is CommonJS (it uses `require`), or you need Node 18 (CommonJS runs from Node 18.14), follow these steps with the changes in [Using CommonJS](./docs/CommonJS.md). For step files written in TypeScript, see [Using TypeScript](./docs/TypeScript.md).
|
|
31
25
|
|
|
32
|
-
|
|
26
|
+
### Start a project
|
|
33
27
|
|
|
34
|
-
|
|
28
|
+
Check that `node --version` prints 20.11 or newer (for CommonJS, 18.14: see [Using CommonJS](./docs/CommonJS.md)), then:
|
|
35
29
|
|
|
36
30
|
```
|
|
31
|
+
mkdir my-project
|
|
32
|
+
cd my-project
|
|
33
|
+
npm init -y
|
|
37
34
|
npm install --save-dev jest @g_package/jest-cucumber-fusion
|
|
35
|
+
npm pkg set type=module
|
|
36
|
+
npm pkg set scripts.test="node --experimental-vm-modules node_modules/jest/bin/jest.js"
|
|
37
|
+
npm pkg set "jest.testMatch[0]=**/*.steps.js"
|
|
38
38
|
```
|
|
39
39
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
### Set these keys in your package.json:
|
|
40
|
+
The last three commands set these keys in your `package.json`, replacing any that `npm init` wrote:
|
|
43
41
|
|
|
44
42
|
```json
|
|
45
43
|
"type": "module",
|
|
@@ -47,10 +45,8 @@ Coming from `jest-cucumber-fusion` 0.8.x or from version 2 of this package? Your
|
|
|
47
45
|
"jest": { "testMatch": [ "**/*.steps.js" ] }
|
|
48
46
|
```
|
|
49
47
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
- `"type": "module"` makes Node read your `.js` files as ES modules. If you would rather not set it, name your files `.mjs` instead, and change `testMatch` to `[ "**/*.steps.mjs" ]`.
|
|
53
|
-
- Jest runs ES modules only in its ES module mode, which Node's `--experimental-vm-modules` flag turns on. This form of the `test` script is the one Jest's own documentation gives, and it does not depend on your shell's syntax. Node prints an `ExperimentalWarning` about the flag on each run. That is expected.
|
|
48
|
+
- `"type": "module"` makes Node read your `.js` files as ES modules. If you would rather not set it, skip `npm pkg set type=module` and name your step files and the code they import `.mjs` instead (and import them by that name, for example `'../../src/basket.mjs'`), and change `testMatch` to `[ "**/*.steps.mjs" ]`.
|
|
49
|
+
- Jest runs ES modules only in its ES module mode, which Node's `--experimental-vm-modules` flag turns on, so always run the tests with `npm test`, not `npx jest`. Node prints an `ExperimentalWarning` about the flag on each run. That is expected.
|
|
54
50
|
- `testMatch` tells Jest that your step definition files are the test files.
|
|
55
51
|
|
|
56
52
|
### Lay out your project
|
|
@@ -58,139 +54,83 @@ Replace any `type` and `scripts.test` that are already there rather than adding
|
|
|
58
54
|
The examples below use this layout. Any layout works, as long as each `import` path and each `Fusion` path matches where your files are.
|
|
59
55
|
|
|
60
56
|
```
|
|
61
|
-
|
|
57
|
+
my-project/
|
|
62
58
|
├── package.json
|
|
63
59
|
├── src/
|
|
64
|
-
│ └──
|
|
60
|
+
│ └── basket.js the code under test
|
|
65
61
|
└── test/
|
|
66
62
|
└── features/
|
|
67
|
-
├──
|
|
68
|
-
└──
|
|
63
|
+
├── shopping-basket.feature
|
|
64
|
+
└── shopping-basket.steps.js
|
|
69
65
|
```
|
|
70
66
|
|
|
71
67
|
The code under test in these examples is a small class of your own:
|
|
72
68
|
|
|
73
69
|
```javascript
|
|
74
|
-
//filename: src/
|
|
75
|
-
export class
|
|
70
|
+
// filename: src/basket.js
|
|
71
|
+
export class Basket {
|
|
76
72
|
constructor() {
|
|
77
|
-
this.
|
|
78
|
-
this.boostersLanded = false
|
|
73
|
+
this.products = []
|
|
79
74
|
}
|
|
80
75
|
|
|
81
|
-
|
|
82
|
-
this.
|
|
83
|
-
this.boostersLanded = true
|
|
76
|
+
add( product ) {
|
|
77
|
+
this.products.push( product )
|
|
84
78
|
}
|
|
85
79
|
}
|
|
86
80
|
```
|
|
87
81
|
|
|
88
|
-
###
|
|
82
|
+
### Write the feature file
|
|
89
83
|
|
|
90
84
|
```gherkin
|
|
91
|
-
|
|
92
|
-
Feature:
|
|
93
|
-
|
|
94
|
-
Scenario: Launching a SpaceX rocket
|
|
95
|
-
Given I am Elon Musk attempting to launch a rocket into space
|
|
96
|
-
When I launch the rocket
|
|
97
|
-
Then the rocket should end up in space
|
|
98
|
-
And the booster(s) should land back on the launch pad
|
|
99
|
-
And nobody should doubt me ever again
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
### Add a Cucumber step definition file and load Fusion
|
|
103
|
-
```javascript
|
|
104
|
-
//filename: test/features/rocket-launching.steps.js
|
|
105
|
-
import { Given, When, Then, And, Fusion } from '@g_package/jest-cucumber-fusion'
|
|
85
|
+
# filename: test/features/shopping-basket.feature
|
|
86
|
+
Feature: Shopping basket
|
|
106
87
|
|
|
88
|
+
Scenario: Adding a product to an empty basket
|
|
89
|
+
Given my basket is empty
|
|
90
|
+
When I add a coffee mug to my basket
|
|
91
|
+
Then my basket holds 1 product
|
|
92
|
+
And the product in my basket is a coffee mug
|
|
107
93
|
```
|
|
108
94
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
**A step binds only to a definition registered with its own keyword.** An `And` step needs an `And(...)` definition, and a `Then(...)` definition with the same text does not serve it. That is why the steps below define `And` for the two `And` lines of the feature. When one definition should serve several keywords, chain it: `Then( And( 'text', fn ) )` registers the same definition under both. A step with no definition makes Fusion refuse the file, naming the step and suggesting the code to add.
|
|
112
|
-
|
|
113
|
-
### Load any dependency you need to do your test
|
|
114
|
-
|
|
115
|
-
```javascript
|
|
116
|
-
//filename: test/features/rocket-launching.steps.js
|
|
117
|
-
import { Given, When, Then, And, Fusion } from '@g_package/jest-cucumber-fusion'
|
|
118
|
-
|
|
119
|
-
import { Rocket } from '../../src/rocket.js'
|
|
120
|
-
let rocket
|
|
121
|
-
|
|
122
|
-
```
|
|
95
|
+
### Write the step definitions
|
|
123
96
|
|
|
124
|
-
|
|
97
|
+
Each step needs a definition registered with **the same keyword the step uses**. The last step of the feature starts with `And`, so its definition, in the file below, is `And(...)`: a `Then(...)` with the same text would not match it, and Fusion would report the step as having no definition. A `But` step likewise needs a `But(...)` definition: [Rule](./docs/Rule.md) shows one.
|
|
125
98
|
|
|
126
|
-
|
|
99
|
+
The step definition file registers a definition for each step, then calls `Fusion` with the feature file's path:
|
|
127
100
|
|
|
128
101
|
```javascript
|
|
129
|
-
//filename: test/features/
|
|
102
|
+
// filename: test/features/shopping-basket.steps.js
|
|
130
103
|
import { Given, When, Then, And, Fusion } from '@g_package/jest-cucumber-fusion'
|
|
131
104
|
|
|
132
|
-
import {
|
|
133
|
-
let rocket
|
|
105
|
+
import { Basket } from '../../src/basket.js'
|
|
134
106
|
|
|
135
|
-
|
|
136
|
-
rocket = new Rocket()
|
|
137
|
-
} )
|
|
107
|
+
let basket
|
|
138
108
|
|
|
139
|
-
|
|
140
|
-
|
|
109
|
+
Given( 'my basket is empty', () => {
|
|
110
|
+
basket = new Basket()
|
|
141
111
|
} )
|
|
142
112
|
|
|
143
|
-
|
|
144
|
-
|
|
113
|
+
When( 'I add a coffee mug to my basket', () => {
|
|
114
|
+
basket.add( 'coffee mug' )
|
|
145
115
|
} )
|
|
146
116
|
|
|
147
|
-
|
|
148
|
-
expect(
|
|
117
|
+
Then( 'my basket holds 1 product', () => {
|
|
118
|
+
expect( basket.products ).toHaveLength( 1 )
|
|
149
119
|
} )
|
|
150
120
|
|
|
151
|
-
And( '
|
|
152
|
-
expect(
|
|
121
|
+
And( 'the product in my basket is a coffee mug', () => {
|
|
122
|
+
expect( basket.products[ 0 ] ).toBe( 'coffee mug' )
|
|
153
123
|
} )
|
|
154
|
-
```
|
|
155
124
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
```javascript
|
|
159
|
-
import { jest } from '@jest/globals'
|
|
125
|
+
Fusion( 'shopping-basket.feature' )
|
|
160
126
|
```
|
|
161
127
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
import { Rocket } from '../../src/rocket.js'
|
|
169
|
-
let rocket
|
|
170
|
-
|
|
171
|
-
Given( 'I am Elon Musk attempting to launch a rocket into space', () => {
|
|
172
|
-
rocket = new Rocket()
|
|
173
|
-
} )
|
|
174
|
-
|
|
175
|
-
When( 'I launch the rocket', () => {
|
|
176
|
-
rocket.launch()
|
|
177
|
-
} )
|
|
178
|
-
|
|
179
|
-
Then( 'the rocket should end up in space', () => {
|
|
180
|
-
expect(rocket.isInSpace).toBe(true)
|
|
181
|
-
} )
|
|
182
|
-
|
|
183
|
-
And( /^the booster\(s\) should land back on the launch pad$/, () => {
|
|
184
|
-
expect(rocket.boostersLanded).toBe(true)
|
|
185
|
-
} )
|
|
186
|
-
|
|
187
|
-
And( 'nobody should doubt me ever again', () => {
|
|
188
|
-
expect('people').not.toBe('haters')
|
|
189
|
-
} )
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
Fusion( 'rocket-launching.feature' )
|
|
193
|
-
```
|
|
128
|
+
- **A string matches a step whose text is exactly that string.** To capture a value from a step, such as a number, match it with a regular expression instead: see [Step definition arguments](./docs/StepDefinitionArguments.md).
|
|
129
|
+
- **`Fusion` comes last**, after every definition, and its path is relative to the step definition file, so a feature file beside it is named on its own.
|
|
130
|
+
- **A relative `import` names the file in full**, extension included: `'../../src/basket.js'`, not `'../../src/basket'`.
|
|
131
|
+
- **A step may be `async`.** Fusion waits for each step before running the next. A scenario is one Jest test, so Jest's timeout, 5 seconds by default, covers all of its steps together: raise it with `"testTimeout"` in the `jest` key if your steps are slow.
|
|
132
|
+
- **`expect` and Jest's other test functions work as usual.** The `jest` object is the exception in ES module mode: see [Troubleshooting](#troubleshooting).
|
|
133
|
+
- **Import only the keywords your steps use.** `But` is also available.
|
|
194
134
|
|
|
195
135
|
### Run the tests
|
|
196
136
|
|
|
@@ -198,375 +138,136 @@ Fusion( 'rocket-launching.feature' )
|
|
|
198
138
|
npm test
|
|
199
139
|
```
|
|
200
140
|
|
|
201
|
-
Jest reports one test for the scenario, named after it
|
|
202
|
-
|
|
203
|
-
Writing your steps in TypeScript? See [Using TypeScript](#using-typescript).
|
|
204
|
-
|
|
205
|
-
## Adding coverage
|
|
206
|
-
Fusion's tests are Jest tests, so Jest's coverage works as usual. Set these keys in your `package.json`:
|
|
207
|
-
```json
|
|
208
|
-
"jest": {
|
|
209
|
-
"testMatch": [
|
|
210
|
-
"**/*.steps.js"
|
|
211
|
-
],
|
|
212
|
-
"coveragePathIgnorePatterns": [
|
|
213
|
-
"/node_modules/",
|
|
214
|
-
"/test/"
|
|
215
|
-
],
|
|
216
|
-
"coverageDirectory": "./coverage/",
|
|
217
|
-
"collectCoverage": true
|
|
218
|
-
}
|
|
219
|
-
```
|
|
220
|
-
|
|
221
|
-
For TypeScript step files, match `**/*.steps.ts` instead (see [Using TypeScript](#using-typescript)).
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
## Setting options once for a whole run
|
|
141
|
+
Jest reports one test for the scenario, named after it:
|
|
225
142
|
|
|
226
|
-
|
|
143
|
+
```text
|
|
144
|
+
PASS test/features/shopping-basket.steps.js
|
|
145
|
+
Shopping basket
|
|
146
|
+
✓ Adding a product to an empty basket (2 ms)
|
|
227
147
|
|
|
228
|
-
|
|
229
|
-
|
|
148
|
+
Test Suites: 1 passed, 1 total
|
|
149
|
+
Tests: 1 passed, 1 total
|
|
230
150
|
```
|
|
231
151
|
|
|
232
|
-
|
|
152
|
+
If Jest prints only the summary, without the list of tests, see [Troubleshooting](#troubleshooting). A test fails at the first step that fails, and names that step. If a step has no definition at all, Fusion refuses the whole file before any test runs, and gives you the code to add. Without the `And` definition above, for example:
|
|
233
153
|
|
|
234
|
-
```
|
|
235
|
-
|
|
236
|
-
|
|
154
|
+
```text
|
|
155
|
+
FAIL test/features/shopping-basket.steps.js
|
|
156
|
+
● Test suite failed to run
|
|
237
157
|
|
|
238
|
-
|
|
158
|
+
Fusion found 1 step in the feature "Shopping basket" that no registered step definition matches.
|
|
159
|
+
...
|
|
160
|
+
1. No step definition matches: "the product in my basket is a coffee mug"
|
|
161
|
+
And("the product in my basket is a coffee mug", () => {});
|
|
239
162
|
```
|
|
240
163
|
|
|
241
|
-
|
|
242
|
-
"jest": {
|
|
243
|
-
"testMatch": [ "**/*.steps.js" ],
|
|
244
|
-
"setupFiles": [ "./jest-fusion-config.js" ]
|
|
245
|
-
}
|
|
246
|
-
```
|
|
247
|
-
|
|
248
|
-
A per-call option still wins for its own file. See [Configuration options](./docs/AdditionalConfiguration.md) for every option and for the merge order.
|
|
249
|
-
|
|
250
|
-
If you are coming from version 2, global configuration used to go through `jest-cucumber`'s own `setJestCucumberConfiguration`. That package is no longer a dependency, so the import moves to `setFusionConfiguration` from this package; the options object is the same shape.
|
|
251
|
-
|
|
252
|
-
## Linting with ESLint
|
|
253
|
-
|
|
254
|
-
[eslint-plugin-jest](https://github.com/jest-community/eslint-plugin-jest) gives ESLint Jest's globals, such as `expect`, and its rules. One rule needs to be told about Fusion. `jest/no-standalone-expect` reports every `expect` that is not inside a `test` or `it` block, and in a step definition file every `expect` sits inside `Then`, `And` or another step function instead. Each step function and each `Before` and `After` hook runs inside the test that Fusion makes for its scenario, so tell the rule to treat them as test blocks.
|
|
164
|
+
### Run one scenario
|
|
255
165
|
|
|
256
|
-
|
|
166
|
+
While you work on one scenario, you can run it alone. Each scenario is a Jest test named after it, so Jest's `-t` option selects it by name; the other tests are reported as skipped. `-t` takes a regular expression and matches it anywhere in the test's full name, so a short phrase can select several tests:
|
|
257
167
|
|
|
258
168
|
```
|
|
259
|
-
npm
|
|
169
|
+
npm test -- -t "Adding a product"
|
|
260
170
|
```
|
|
261
171
|
|
|
262
|
-
|
|
172
|
+
To pick scenarios by tag instead, pass the tag filter from an environment variable:
|
|
263
173
|
|
|
264
174
|
```javascript
|
|
265
|
-
|
|
266
|
-
import js from '@eslint/js'
|
|
267
|
-
import globals from 'globals'
|
|
268
|
-
import jest from 'eslint-plugin-jest'
|
|
269
|
-
|
|
270
|
-
export default [
|
|
271
|
-
js.configs.recommended,
|
|
272
|
-
{
|
|
273
|
-
languageOptions: { sourceType: 'module', globals: globals.node },
|
|
274
|
-
},
|
|
275
|
-
{
|
|
276
|
-
files: [ '**/*.steps.js' ],
|
|
277
|
-
...jest.configs[ 'flat/recommended' ],
|
|
278
|
-
rules: {
|
|
279
|
-
...jest.configs[ 'flat/recommended' ].rules,
|
|
280
|
-
// Fusion runs each step and hook inside the test it makes for the scenario.
|
|
281
|
-
'jest/no-standalone-expect': [ 'error', {
|
|
282
|
-
additionalTestBlockFunctions: [ 'Given', 'When', 'Then', 'And', 'But', 'Before', 'After' ],
|
|
283
|
-
} ],
|
|
284
|
-
},
|
|
285
|
-
},
|
|
286
|
-
]
|
|
175
|
+
Fusion( 'shopping-basket.feature', { tagFilter: process.env.TAGS } )
|
|
287
176
|
```
|
|
288
177
|
|
|
289
|
-
|
|
178
|
+
Then tag the scenario, on the line above it:
|
|
290
179
|
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
Fusion ships a CommonJS build beside its ES modules: `require` gets the CommonJS build and `import` gets the ES modules. Use CommonJS if your project already is CommonJS, if you need Node 18 (CommonJS runs on Node 18.14 and newer), or if you would rather not run Jest's experimental ES module mode. CommonJS needs no Jest set-up at all.
|
|
296
|
-
|
|
297
|
-
The steps in [Getting Started](#getting-started) work with these changes.
|
|
298
|
-
|
|
299
|
-
**package.json.** Leave out `"type": "module"`, and run Jest directly:
|
|
300
|
-
|
|
301
|
-
```json
|
|
302
|
-
"scripts": { "test": "jest" },
|
|
303
|
-
"jest": { "testMatch": [ "**/*.steps.js" ] }
|
|
180
|
+
```gherkin
|
|
181
|
+
@wip
|
|
182
|
+
Scenario: Adding a product to an empty basket
|
|
304
183
|
```
|
|
305
184
|
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
```javascript
|
|
309
|
-
//filename: src/rocket.js
|
|
310
|
-
class Rocket {
|
|
311
|
-
constructor() {
|
|
312
|
-
this.isInSpace = false
|
|
313
|
-
this.boostersLanded = false
|
|
314
|
-
}
|
|
185
|
+
and run `TAGS=@wip npm test`. That form of setting a variable works in macOS and Linux shells; in Windows PowerShell, set `$env:TAGS = '@wip'` first, then run `npm test`. With `TAGS` unset, this call adds no filter of its own, so every scenario runs unless a [global configuration](./docs/AdditionalConfiguration.md#global-configuration) sets one. [Tag filtering](./docs/AdditionalConfiguration.md#tag-filtering) covers the expressions you can use, such as `@wip and not @slow`.
|
|
315
186
|
|
|
316
|
-
|
|
317
|
-
this.isInSpace = true
|
|
318
|
-
this.boostersLanded = true
|
|
319
|
-
}
|
|
320
|
-
}
|
|
187
|
+
## Hooks
|
|
321
188
|
|
|
322
|
-
|
|
323
|
-
```
|
|
324
|
-
|
|
325
|
-
**Step definition files** `require` the same names. A relative `require` may leave the extension out:
|
|
189
|
+
`Before` and `After` run a function before or after every scenario of the `Fusion` call that follows them, which is the place to give each scenario a fresh start. With a `Before` hook, the steps above no longer need to create the basket:
|
|
326
190
|
|
|
327
191
|
```javascript
|
|
328
|
-
|
|
329
|
-
const { Given, When, Then, And, Fusion } = require( '@g_package/jest-cucumber-fusion' )
|
|
192
|
+
import { Before, Given, When, Then, And, Fusion } from '@g_package/jest-cucumber-fusion'
|
|
330
193
|
|
|
331
|
-
|
|
332
|
-
let rocket
|
|
194
|
+
import { Basket } from '../../src/basket.js'
|
|
333
195
|
|
|
334
|
-
|
|
335
|
-
rocket = new Rocket()
|
|
336
|
-
} )
|
|
196
|
+
let basket
|
|
337
197
|
|
|
338
|
-
|
|
339
|
-
|
|
198
|
+
Before( () => {
|
|
199
|
+
basket = new Basket()
|
|
340
200
|
} )
|
|
341
201
|
|
|
342
|
-
|
|
343
|
-
expect(
|
|
202
|
+
Given( 'my basket is empty', () => {
|
|
203
|
+
expect( basket.products ).toHaveLength( 0 )
|
|
344
204
|
} )
|
|
345
205
|
|
|
346
|
-
|
|
347
|
-
|
|
206
|
+
When( 'I add a coffee mug to my basket', () => {
|
|
207
|
+
basket.add( 'coffee mug' )
|
|
348
208
|
} )
|
|
349
209
|
|
|
350
|
-
|
|
351
|
-
expect(
|
|
210
|
+
Then( 'my basket holds 1 product', () => {
|
|
211
|
+
expect( basket.products ).toHaveLength( 1 )
|
|
352
212
|
} )
|
|
353
213
|
|
|
214
|
+
And( 'the product in my basket is a coffee mug', () => {
|
|
215
|
+
expect( basket.products[ 0 ] ).toBe( 'coffee mug' )
|
|
216
|
+
} )
|
|
354
217
|
|
|
355
|
-
Fusion( '
|
|
356
|
-
```
|
|
357
|
-
|
|
358
|
-
The `jest` object is a global, as in any CommonJS Jest project.
|
|
359
|
-
|
|
360
|
-
**A global configuration script** `require`s `setFusionConfiguration`:
|
|
361
|
-
|
|
362
|
-
```javascript
|
|
363
|
-
//filename: jest-fusion-config.js
|
|
364
|
-
const { setFusionConfiguration } = require( '@g_package/jest-cucumber-fusion' )
|
|
365
|
-
|
|
366
|
-
setFusionConfiguration( { tagFilter: '@smoke and not @slow' } )
|
|
367
|
-
```
|
|
368
|
-
|
|
369
|
-
**ESLint.** The configuration file is CommonJS too, with `sourceType: 'commonjs'`:
|
|
370
|
-
|
|
371
|
-
```javascript
|
|
372
|
-
//filename: eslint.config.js
|
|
373
|
-
const js = require( '@eslint/js' )
|
|
374
|
-
const globals = require( 'globals' )
|
|
375
|
-
const jest = require( 'eslint-plugin-jest' )
|
|
376
|
-
|
|
377
|
-
module.exports = [
|
|
378
|
-
js.configs.recommended,
|
|
379
|
-
{
|
|
380
|
-
languageOptions: { sourceType: 'commonjs', globals: globals.node },
|
|
381
|
-
},
|
|
382
|
-
{
|
|
383
|
-
files: [ '**/*.steps.js' ],
|
|
384
|
-
...jest.configs[ 'flat/recommended' ],
|
|
385
|
-
rules: {
|
|
386
|
-
...jest.configs[ 'flat/recommended' ].rules,
|
|
387
|
-
// Fusion runs each step and hook inside the test it makes for the scenario.
|
|
388
|
-
'jest/no-standalone-expect': [ 'error', {
|
|
389
|
-
additionalTestBlockFunctions: [ 'Given', 'When', 'Then', 'And', 'But', 'Before', 'After' ],
|
|
390
|
-
} ],
|
|
391
|
-
},
|
|
392
|
-
},
|
|
393
|
-
]
|
|
394
|
-
```
|
|
395
|
-
|
|
396
|
-
**Mixing the two styles** works. A CommonJS shared step library can serve ES module step files, and a CommonJS setup script can configure ES module steps: both styles share one set of step definitions and one global configuration. An ES module imports a CommonJS file by its full name, for example `import './shared-steps.cjs'`.
|
|
397
|
-
|
|
398
|
-
The other pages in this documentation show ES modules. To use one of their examples in CommonJS, turn each `import { … } from '…'` into `const { … } = require( '…' )` and each `export` into `module.exports`.
|
|
399
|
-
|
|
400
|
-
## Using TypeScript
|
|
401
|
-
|
|
402
|
-
Fusion ships its type definitions, and TypeScript finds the right ones for ES modules and CommonJS with no configuration. To run step definition files written in TypeScript, Jest needs a transform. [ts-jest](https://kulshekhar.github.io/ts-jest/) is the usual one.
|
|
403
|
-
|
|
404
|
-
```
|
|
405
|
-
npm install --save-dev jest ts-jest typescript @types/jest @g_package/jest-cucumber-fusion
|
|
406
|
-
```
|
|
407
|
-
|
|
408
|
-
### ES modules (recommended)
|
|
409
|
-
|
|
410
|
-
```json
|
|
411
|
-
"type": "module",
|
|
412
|
-
"scripts": {
|
|
413
|
-
"test": "node --experimental-vm-modules node_modules/jest/bin/jest.js",
|
|
414
|
-
"typecheck": "tsc --noEmit"
|
|
415
|
-
}
|
|
416
|
-
```
|
|
417
|
-
|
|
418
|
-
```json
|
|
419
|
-
//filename: tsconfig.json
|
|
420
|
-
{
|
|
421
|
-
"compilerOptions": {
|
|
422
|
-
"target": "ES2022",
|
|
423
|
-
"module": "NodeNext",
|
|
424
|
-
"moduleResolution": "NodeNext",
|
|
425
|
-
"isolatedModules": true,
|
|
426
|
-
"strict": true,
|
|
427
|
-
"types": [ "jest" ]
|
|
428
|
-
}
|
|
429
|
-
}
|
|
430
|
-
```
|
|
431
|
-
|
|
432
|
-
```javascript
|
|
433
|
-
//filename: jest.config.js
|
|
434
|
-
export default {
|
|
435
|
-
preset: 'ts-jest/presets/default-esm',
|
|
436
|
-
testMatch: [ '**/*.steps.ts' ],
|
|
437
|
-
moduleNameMapper: { '^(\\.{1,2}/.*)\\.js$': '$1' },
|
|
438
|
-
}
|
|
439
|
-
```
|
|
440
|
-
|
|
441
|
-
**Run `npm run typecheck` as well as `npm test`, for example in CI.** In ES module mode ts-jest only strips the types and does not check them, so a type error does not fail `npm test`; `tsc --noEmit` is what reports it. (`isolatedModules` tells ts-jest that this is expected. Without it, ts-jest warns `TS151002` and still does not check.)
|
|
442
|
-
|
|
443
|
-
`moduleNameMapper` lets your imports keep the `.js` extension that ES modules need, while Jest loads the `.ts` file: `import { Rocket } from '../../src/rocket.js'` loads `src/rocket.ts`.
|
|
444
|
-
|
|
445
|
-
### CommonJS
|
|
446
|
-
|
|
447
|
-
Leave out `"type": "module"`, compile to CommonJS, and use ts-jest's default preset:
|
|
448
|
-
|
|
449
|
-
```json
|
|
450
|
-
"scripts": {
|
|
451
|
-
"test": "jest",
|
|
452
|
-
"typecheck": "tsc --noEmit"
|
|
453
|
-
}
|
|
454
|
-
```
|
|
455
|
-
|
|
456
|
-
```json
|
|
457
|
-
{
|
|
458
|
-
"compilerOptions": {
|
|
459
|
-
"target": "ES2022",
|
|
460
|
-
"module": "CommonJS",
|
|
461
|
-
"strict": true,
|
|
462
|
-
"types": [ "jest" ]
|
|
463
|
-
}
|
|
464
|
-
}
|
|
465
|
-
```
|
|
466
|
-
|
|
467
|
-
`"module": "CommonJS"` is what lets ts-jest check types here. With `NodeNext` or `Node16`, ts-jest warns `TS151002` and asks for `isolatedModules`, which would switch its checking off.
|
|
468
|
-
|
|
469
|
-
```javascript
|
|
470
|
-
//filename: jest.config.js
|
|
471
|
-
module.exports = {
|
|
472
|
-
preset: 'ts-jest',
|
|
473
|
-
testMatch: [ '**/*.steps.ts' ],
|
|
474
|
-
moduleNameMapper: { '^(\\.{1,2}/.*)\\.js$': '$1' },
|
|
475
|
-
}
|
|
476
|
-
```
|
|
477
|
-
|
|
478
|
-
Here ts-jest checks types while it runs the tests, so a type error fails `npm test` too.
|
|
479
|
-
|
|
480
|
-
### Typed step definitions
|
|
481
|
-
|
|
482
|
-
To move the [Getting Started](#getting-started) example to TypeScript, renaming its files to `.ts` is not enough under `strict`: `tsc --noEmit` then reports the `Rocket` class's fields as undeclared (`TS2339`) and `let rocket` as an implicit `any` (`TS7034`). Declare the fields in the class and write `let rocket: Rocket`, as the example below does. A step may also declare the type of each argument it receives: a capture or a docstring arrives as a `string`, and a data table as an `Array<Record<string, string>>` of its rows. For example, with this feature:
|
|
483
|
-
|
|
484
|
-
```gherkin
|
|
485
|
-
###filename: test/features/launch.feature
|
|
486
|
-
Feature: Launch
|
|
487
|
-
|
|
488
|
-
Scenario: Launching a batch of rockets
|
|
489
|
-
Given I am launching 3 rockets
|
|
490
|
-
When the countdown says
|
|
491
|
-
"""
|
|
492
|
-
ignition
|
|
493
|
-
"""
|
|
494
|
-
Then the manifest has
|
|
495
|
-
| name |
|
|
496
|
-
| Falcon |
|
|
497
|
-
```
|
|
498
|
-
|
|
499
|
-
and this code under test:
|
|
500
|
-
|
|
501
|
-
```typescript
|
|
502
|
-
//filename: src/launch.ts
|
|
503
|
-
export class Launch {
|
|
504
|
-
launched = 0
|
|
505
|
-
count: number
|
|
506
|
-
|
|
507
|
-
constructor( count: number ) {
|
|
508
|
-
this.count = count
|
|
509
|
-
}
|
|
510
|
-
|
|
511
|
-
countdown( word: string ): void {
|
|
512
|
-
if ( word === 'ignition' ) this.launched = this.count
|
|
513
|
-
}
|
|
514
|
-
}
|
|
218
|
+
Fusion( 'shopping-basket.feature' )
|
|
515
219
|
```
|
|
516
220
|
|
|
517
|
-
|
|
221
|
+
Register hooks, like step definitions, before the `Fusion` call. A hook may be `async`, and it receives nothing, so declare no parameters: Jest treats a declared parameter as a `done` callback and waits for it to be called.
|
|
518
222
|
|
|
519
|
-
|
|
520
|
-
//filename: test/features/launch.steps.ts
|
|
521
|
-
import { Given, When, Then, Fusion } from '@g_package/jest-cucumber-fusion'
|
|
223
|
+
## If you know Cucumber
|
|
522
224
|
|
|
523
|
-
|
|
225
|
+
Most of Gherkin works as you expect: [`Background`](./docs/Background.md), [`Rule`](./docs/Rule.md), `Scenario Outline` with `Examples`, data tables, docstrings, tags and [80 languages](./docs/Language.md). The differences:
|
|
524
226
|
|
|
525
|
-
|
|
227
|
+
- **Steps bind by keyword.** An `And` step needs an `And` definition, as above. When one definition should serve several keywords, chain it: `Then( And( 'text', fn ) )` registers it under both.
|
|
228
|
+
- **No Cucumber Expressions.** A string is compared as plain text, so `'I add {int} coffee mugs to my basket'` matches only that exact text. Use a regular expression to capture values: `/^I add (\d+) coffee mugs to my basket$/`.
|
|
229
|
+
- **No `*` steps.** Because a step binds by its keyword, Fusion refuses a `*` step and asks you to write it with `Given`, `When`, `Then`, `And` or `But`.
|
|
230
|
+
- **No World.** Steps are plain functions with no shared `this`. Share state through variables in the step definition file, and reset it in a `Before` hook.
|
|
231
|
+
- **Hooks take no tags, and there is no `BeforeAll` or `AfterAll`.** `Before` and `After` run around every scenario of their `Fusion` call. For once-per-file set-up, use Jest's own `beforeAll` and `afterAll` at the top of the step definition file.
|
|
232
|
+
- **Tags select scenarios through an option**, `tagFilter`, rather than a command-line flag: see [Configuration options](./docs/AdditionalConfiguration.md#tag-filtering). Jest's own `-t` filter also works, on scenario names.
|
|
526
233
|
|
|
527
|
-
|
|
528
|
-
launch = new Launch( Number( count ) )
|
|
529
|
-
} )
|
|
234
|
+
## Where next
|
|
530
235
|
|
|
531
|
-
|
|
532
|
-
launch.countdown( words.trim() )
|
|
533
|
-
} )
|
|
236
|
+
The [documentation index](./docs/README.md) suggests an order to read the guides in. In short:
|
|
534
237
|
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
238
|
+
| To | Read |
|
|
239
|
+
|---|---|
|
|
240
|
+
| capture values from a step, or read a docstring | [Step definition arguments](./docs/StepDefinitionArguments.md) |
|
|
241
|
+
| give every scenario the same first steps | [Background](./docs/Background.md) |
|
|
242
|
+
| use a data table | [Gherkin tables](./docs/GherkinTables.md) |
|
|
243
|
+
| run one scenario for every row of an `Examples` table | [Scenario outlines](./docs/ScenarioOutlines.md) |
|
|
244
|
+
| group scenarios under a business rule | [Rule](./docs/Rule.md) |
|
|
245
|
+
| share steps between feature files | [Re-using step definitions](./docs/ReusingStepDefinitions.md) |
|
|
246
|
+
| filter by tag, name tests, or set options once for every file | [Configuration options](./docs/AdditionalConfiguration.md) |
|
|
247
|
+
| use CommonJS, or Node 18 | [Using CommonJS](./docs/CommonJS.md) |
|
|
248
|
+
| write step definitions in TypeScript | [Using TypeScript](./docs/TypeScript.md) |
|
|
249
|
+
| lint step files with ESLint | [Linting with ESLint](./docs/ESLint.md) |
|
|
250
|
+
| write feature files in another language | [Language](./docs/Language.md) |
|
|
251
|
+
| upgrade from version 2 or 0.8.x | [Migrating to version 3](./docs/Migrating.md) |
|
|
539
252
|
|
|
540
|
-
|
|
541
|
-
```
|
|
253
|
+
## Coverage
|
|
542
254
|
|
|
543
|
-
|
|
255
|
+
Coverage works as in any Jest project, because Fusion's tests are Jest tests: run `npm test -- --coverage`. Jest already leaves the `*.steps.js` files out of the report; to leave out shared step files under `test/` as well, add `"coveragePathIgnorePatterns": [ "/node_modules/", "/test/" ]` to the `jest` key.
|
|
544
256
|
|
|
545
257
|
## Troubleshooting
|
|
546
258
|
|
|
547
|
-
- **`
|
|
548
|
-
- **`
|
|
549
|
-
-
|
|
550
|
-
- **`
|
|
259
|
+
- **`Must use import to load ES Module`**: Jest ran without `--experimental-vm-modules`, so run the tests with `npm test`, not `npx jest`. If you did use `npm test`, a `.cjs` file `require`s an ES module, which Node before 24.9 cannot do (see [Mixing the two styles](./docs/CommonJS.md#mixing-the-two-styles)).
|
|
260
|
+
- **`Cannot use import statement outside a module`**: `package.json` has no `"type": "module"`. Set it (see [Start a project](#start-a-project)), or name your files `.mjs`. On Jest 29 and older, Jest run without `--experimental-vm-modules` gives this message too: run the tests with `npm test`.
|
|
261
|
+
- **`SyntaxError: Unexpected token 'with'`** when Jest loads your ES module steps: your Node cannot parse the import attributes in Fusion's ES modules (Node 18.19 and 20.9 fail; 20.11 is the oldest measured to work). Upgrade Node, or [use CommonJS](./docs/CommonJS.md), which runs from Node 18.14.
|
|
262
|
+
- **`jest is not defined`**: in Jest's ES module mode the `jest` object (for `jest.fn()` and friends) is not a global. Add `@jest/globals` to your `devDependencies` and write `import { jest } from '@jest/globals'`.
|
|
263
|
+
- **`No step definition matches`** for a step you did define: the step's keyword decides which definitions it can bind to. An `And` step needs an `And(...)` definition (see [Write the step definitions](#write-the-step-definitions)).
|
|
264
|
+
- **`Your test suite must contain at least one test`**: the feature file is empty, or has a `Feature:` but no scenarios. Add a `Scenario`.
|
|
265
|
+
- **`Error parsing feature Gherkin`**, with `expected: ... #FeatureLine`: the file has scenarios but no `Feature:` line. Add one before the first scenario.
|
|
266
|
+
- **`Feature file not found`**: the path passed to `Fusion` is wrong. It is relative to the step definition file.
|
|
267
|
+
- **`Exceeded timeout of 5000 ms for a test`**: the scenario's steps together took longer than Jest's timeout. Raise `"testTimeout"` in the `jest` key.
|
|
268
|
+
- **A `Before` or `After` hook times out waiting for `done()`**: the hook declares a parameter. Remove it (see [Hooks](#hooks)).
|
|
269
|
+
- **`Multiple configurations found`**: Jest found both a `jest` key in `package.json` and a `jest.config.js`. Keep one: see [Using TypeScript](./docs/TypeScript.md).
|
|
270
|
+
- **`npm WARN EBADENGINE` on Node 18**, naming `brace-expansion` or `lru-cache`: these come from Jest 30's own dependencies, not from Fusion. CommonJS steps still run on Node 18.14 and newer.
|
|
551
271
|
- **Jest prints only the summary, without the list of tests:** Jest shortens its output when it detects an AI agent's environment variables, such as `AI_AGENT` or `CLAUDECODE`. Run it from a terminal that does not have them.
|
|
552
272
|
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
Using the package:
|
|
556
|
-
|
|
557
|
-
* [Step definition arguments](./docs/StepDefinitionArguments.md)
|
|
558
|
-
* [Gherkin tables](./docs/GherkinTables.md)
|
|
559
|
-
* [Scenario outlines](./docs/ScenarioOutlines.md)
|
|
560
|
-
* [Re-using step definitions](./docs/ReusingStepDefinitions.md)
|
|
561
|
-
* [Language](./docs/Language.md)
|
|
562
|
-
* [Configuration options](./docs/AdditionalConfiguration.md): every export and option
|
|
563
|
-
* [Migrating to version 3](./docs/Migrating.md)
|
|
564
|
-
|
|
565
|
-
Working on the package:
|
|
566
|
-
|
|
567
|
-
* [Running the examples](./docs/RunningTheExamples.md)
|
|
568
|
-
* [Architecture](./docs/Architecture.md)
|
|
569
|
-
|
|
570
|
-
Every example on the guide pages above runs as written: the repository's tests copy each one into a fresh project and run it.
|
|
571
|
-
|
|
572
|
-
The [documentation index](./docs/README.md) lists all of these pages, and says what the delivery records under `docs/feature/` are.
|
|
273
|
+
Still stuck, or found a bug? [Open an issue](https://github.com/gotreasa/jest-cucumber-fusion/issues/new/choose).
|
package/dist/index.d.cts
CHANGED
|
@@ -92,10 +92,10 @@ export interface FusionOptions {
|
|
|
92
92
|
* they are compared, so the operators may be written in any case too.
|
|
93
93
|
*
|
|
94
94
|
* A scenario is selected on the tags its compiled pickle carries, which is the union of the
|
|
95
|
-
* scenario's own tags, its feature's tags and, for a Scenario Outline row,
|
|
96
|
-
* set's tags. A scenario the expression excludes is registered through `test.skip`
|
|
97
|
-
* own unannotated name, so Jest reports it as skipped: never run, and never absent from
|
|
98
|
-
* report. Its steps are also exempt from the unmatched-step check, because a scenario you
|
|
95
|
+
* scenario's own tags, its `Rule`'s tags, its feature's tags and, for a Scenario Outline row,
|
|
96
|
+
* that Examples set's tags. A scenario the expression excludes is registered through `test.skip`
|
|
97
|
+
* under its own unannotated name, so Jest reports it as skipped: never run, and never absent from
|
|
98
|
+
* the report. Its steps are also exempt from the unmatched-step check, because a scenario you
|
|
99
99
|
* excluded is not one you are asking to have wired. They are still read, so a step with an
|
|
100
100
|
* unsupported keyword (`*`) or one that matches two definitions is refused all the same.
|
|
101
101
|
*
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@g_package/jest-cucumber-fusion",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.5",
|
|
4
4
|
"description": "Write cucumber test as part of a jest run (including coverage)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.cjs",
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"scripts": {
|
|
17
17
|
"pretest": "npm run build",
|
|
18
18
|
"test": "node --experimental-vm-modules node_modules/jest/bin/jest.js --color",
|
|
19
|
-
"test-d": "
|
|
19
|
+
"test-d": "tstyche",
|
|
20
20
|
"test:baseline": "node test/specs/baseline/run-all.js",
|
|
21
21
|
"coverage": "node --experimental-vm-modules node_modules/jest/bin/jest.js --coverage",
|
|
22
22
|
"lint": "eslint . --max-warnings 0",
|
|
@@ -51,6 +51,7 @@
|
|
|
51
51
|
"@eslint/js": "^10.0.1",
|
|
52
52
|
"@secretlint/secretlint-rule-pattern": "^13.0.7",
|
|
53
53
|
"@secretlint/secretlint-rule-preset-recommend": "^13.0.7",
|
|
54
|
+
"@semantic-release/exec": "^7.1.0",
|
|
54
55
|
"@types/jest": "^30.0.0",
|
|
55
56
|
"@types/node": "^18.19.130",
|
|
56
57
|
"czg": "1.14.0",
|
|
@@ -62,16 +63,19 @@
|
|
|
62
63
|
"husky": "^9.1.7",
|
|
63
64
|
"jest": "^30.4.2",
|
|
64
65
|
"lint-staged": "^17.6.0",
|
|
65
|
-
"prettier": "3.9.
|
|
66
|
+
"prettier": "3.9.10",
|
|
66
67
|
"secretlint": "^13.0.7",
|
|
67
68
|
"semantic-release": "^25.0.5",
|
|
68
|
-
"
|
|
69
|
+
"tstyche": "^7.2.5",
|
|
69
70
|
"typescript": "^6.0.3"
|
|
70
71
|
},
|
|
71
72
|
"publishConfig": {
|
|
72
73
|
"access": "public"
|
|
73
74
|
},
|
|
74
75
|
"release": {
|
|
76
|
+
"branches": [
|
|
77
|
+
"main"
|
|
78
|
+
],
|
|
75
79
|
"plugins": [
|
|
76
80
|
"@semantic-release/commit-analyzer",
|
|
77
81
|
"@semantic-release/release-notes-generator",
|
|
@@ -79,7 +83,13 @@
|
|
|
79
83
|
"@semantic-release/github",
|
|
80
84
|
{
|
|
81
85
|
"successComment": false,
|
|
82
|
-
"failComment": false
|
|
86
|
+
"failComment": false,
|
|
87
|
+
"assets": [
|
|
88
|
+
{
|
|
89
|
+
"path": "release/*.cdx.json",
|
|
90
|
+
"label": "SBOM (CycloneDX)"
|
|
91
|
+
}
|
|
92
|
+
]
|
|
83
93
|
}
|
|
84
94
|
],
|
|
85
95
|
[
|
|
@@ -88,6 +98,12 @@
|
|
|
88
98
|
"npmPublish": false,
|
|
89
99
|
"tarballDir": "release"
|
|
90
100
|
}
|
|
101
|
+
],
|
|
102
|
+
[
|
|
103
|
+
"@semantic-release/exec",
|
|
104
|
+
{
|
|
105
|
+
"prepareCmd": "npm sbom --sbom-format cyclonedx --omit dev --package-lock-only > release/jest-cucumber-fusion-${nextRelease.version}.cdx.json"
|
|
106
|
+
}
|
|
91
107
|
]
|
|
92
108
|
],
|
|
93
109
|
"parserOpts": {
|
package/src/index.d.ts
CHANGED
|
@@ -92,10 +92,10 @@ export interface FusionOptions {
|
|
|
92
92
|
* they are compared, so the operators may be written in any case too.
|
|
93
93
|
*
|
|
94
94
|
* A scenario is selected on the tags its compiled pickle carries, which is the union of the
|
|
95
|
-
* scenario's own tags, its feature's tags and, for a Scenario Outline row,
|
|
96
|
-
* set's tags. A scenario the expression excludes is registered through `test.skip`
|
|
97
|
-
* own unannotated name, so Jest reports it as skipped: never run, and never absent from
|
|
98
|
-
* report. Its steps are also exempt from the unmatched-step check, because a scenario you
|
|
95
|
+
* scenario's own tags, its `Rule`'s tags, its feature's tags and, for a Scenario Outline row,
|
|
96
|
+
* that Examples set's tags. A scenario the expression excludes is registered through `test.skip`
|
|
97
|
+
* under its own unannotated name, so Jest reports it as skipped: never run, and never absent from
|
|
98
|
+
* the report. Its steps are also exempt from the unmatched-step check, because a scenario you
|
|
99
99
|
* excluded is not one you are asking to have wired. They are still read, so a step with an
|
|
100
100
|
* unsupported keyword (`*`) or one that matches two definitions is refused all the same.
|
|
101
101
|
*
|