@lynxwall/cucumber-tsflow 7.5.5 → 7.7.0
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 +287 -234
- package/lib/api/convert-configuration.d.ts +1 -0
- package/lib/api/convert-configuration.js +2 -0
- package/lib/api/convert-configuration.js.map +1 -1
- package/lib/api/load-configuration.js +22 -33
- package/lib/api/load-configuration.js.map +1 -1
- package/lib/api/load-support.d.ts +24 -1
- package/lib/api/load-support.js +140 -3
- package/lib/api/load-support.js.map +1 -1
- package/lib/api/loader-worker.d.ts +25 -0
- package/lib/api/loader-worker.js +70 -0
- package/lib/api/loader-worker.js.map +1 -0
- package/lib/api/parallel-loader.d.ts +31 -0
- package/lib/api/parallel-loader.js +169 -0
- package/lib/api/parallel-loader.js.map +1 -0
- package/lib/api/run-cucumber.js +42 -12
- package/lib/api/run-cucumber.js.map +1 -1
- package/lib/api/support.js +3 -0
- package/lib/api/support.js.map +1 -1
- package/lib/api/wrapper.mjs +1 -0
- package/lib/bindings/binding-decorator.d.ts +6 -0
- package/lib/bindings/binding-decorator.js +14 -0
- package/lib/bindings/binding-decorator.js.map +1 -1
- package/lib/bindings/binding-registry.d.ts +31 -1
- package/lib/bindings/binding-registry.js +95 -47
- package/lib/bindings/binding-registry.js.map +1 -1
- package/lib/bindings/step-binding.d.ts +37 -0
- package/lib/bindings/step-binding.js +23 -0
- package/lib/bindings/step-binding.js.map +1 -1
- package/lib/bindings/types.js.map +1 -1
- package/lib/cli/argv-parser.d.ts +1 -0
- package/lib/cli/argv-parser.js +6 -0
- package/lib/cli/argv-parser.js.map +1 -1
- package/lib/formatter/{step-definition-snippit-syntax → step-definition-snippet-syntax}/tsflow-snippet-syntax.js.map +1 -1
- package/lib/index.d.ts +1 -1
- package/lib/index.js +1 -1
- package/lib/index.js.map +1 -1
- package/lib/runtime/coordinator.d.ts +2 -1
- package/lib/runtime/coordinator.js +4 -2
- package/lib/runtime/coordinator.js.map +1 -1
- package/lib/runtime/make-runtime.d.ts +3 -1
- package/lib/runtime/make-runtime.js +5 -4
- package/lib/runtime/make-runtime.js.map +1 -1
- package/lib/runtime/managed-scenario-context.js +2 -32
- package/lib/runtime/managed-scenario-context.js.map +1 -1
- package/lib/runtime/parallel/adapter.d.ts +4 -1
- package/lib/runtime/parallel/adapter.js +10 -2
- package/lib/runtime/parallel/adapter.js.map +1 -1
- package/lib/runtime/serial/adapter.d.ts +2 -1
- package/lib/runtime/serial/adapter.js +13 -3
- package/lib/runtime/serial/adapter.js.map +1 -1
- package/lib/runtime/test-case-runner.d.ts +4 -1
- package/lib/runtime/test-case-runner.js +4 -5
- package/lib/runtime/test-case-runner.js.map +1 -1
- package/lib/runtime/types.d.ts +2 -0
- package/lib/runtime/types.js.map +1 -1
- package/lib/runtime/utils.js +0 -6
- package/lib/runtime/utils.js.map +1 -1
- package/lib/runtime/worker.d.ts +14 -3
- package/lib/runtime/worker.js +91 -12
- package/lib/runtime/worker.js.map +1 -1
- package/lib/snippet.js +1 -1
- package/lib/snippet.js.map +1 -1
- package/lib/transpilers/esm/vue-sfc-compiler.mjs +14 -333
- package/lib/transpilers/esvue.js +6 -9
- package/lib/transpilers/esvue.js.map +1 -1
- package/lib/transpilers/tsvue-exp.js +6 -9
- package/lib/transpilers/tsvue-exp.js.map +1 -1
- package/lib/transpilers/tsvue.js +5 -8
- package/lib/transpilers/tsvue.js.map +1 -1
- package/lib/transpilers/vue-sfc-compiler.d.ts +23 -0
- package/lib/transpilers/vue-sfc-compiler.js +242 -0
- package/lib/transpilers/vue-sfc-compiler.js.map +1 -0
- package/lib/tsconfig.node.tsbuildinfo +1 -1
- package/lib/version.d.ts +1 -1
- package/lib/version.js +1 -1
- package/lib/version.js.map +1 -1
- package/package.json +8 -9
- package/lib/transpilers/vue-sfc/compiler.d.ts +0 -7
- package/lib/transpilers/vue-sfc/compiler.js +0 -22
- package/lib/transpilers/vue-sfc/compiler.js.map +0 -1
- package/lib/transpilers/vue-sfc/index.d.ts +0 -23
- package/lib/transpilers/vue-sfc/index.js +0 -46
- package/lib/transpilers/vue-sfc/index.js.map +0 -1
- package/lib/transpilers/vue-sfc/main.d.ts +0 -8
- package/lib/transpilers/vue-sfc/main.js +0 -258
- package/lib/transpilers/vue-sfc/main.js.map +0 -1
- package/lib/transpilers/vue-sfc/script.d.ts +0 -5
- package/lib/transpilers/vue-sfc/script.js +0 -41
- package/lib/transpilers/vue-sfc/script.js.map +0 -1
- package/lib/transpilers/vue-sfc/template.d.ts +0 -8
- package/lib/transpilers/vue-sfc/template.js +0 -101
- package/lib/transpilers/vue-sfc/template.js.map +0 -1
- package/lib/transpilers/vue-sfc/types.d.ts +0 -55
- package/lib/transpilers/vue-sfc/types.js +0 -3
- package/lib/transpilers/vue-sfc/types.js.map +0 -1
- package/lib/transpilers/vue-sfc/utils/descriptorCache.d.ts +0 -13
- package/lib/transpilers/vue-sfc/utils/descriptorCache.js +0 -68
- package/lib/transpilers/vue-sfc/utils/descriptorCache.js.map +0 -1
- package/lib/transpilers/vue-sfc/utils/error.d.ts +0 -3
- package/lib/transpilers/vue-sfc/utils/error.js +0 -23
- package/lib/transpilers/vue-sfc/utils/error.js.map +0 -1
- package/lib/transpilers/vue-sfc/utils/query.d.ts +0 -13
- package/lib/transpilers/vue-sfc/utils/query.js +0 -36
- package/lib/transpilers/vue-sfc/utils/query.js.map +0 -1
- /package/lib/formatter/{step-definition-snippit-syntax → step-definition-snippet-syntax}/tsflow-snippet-syntax.d.ts +0 -0
- /package/lib/formatter/{step-definition-snippit-syntax → step-definition-snippet-syntax}/tsflow-snippet-syntax.js +0 -0
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
# cucumber-tsflow
|
|
4
4
|
|
|
5
|
-
Provides 'specflow' like bindings for Cucumber-JS 12.
|
|
5
|
+
Provides 'specflow' like bindings for Cucumber-JS 12.7.0 in TypeScript 5.9+.
|
|
6
6
|
|
|
7
7
|
Supports Vue3 files in cucumber tests.
|
|
8
8
|
|
|
@@ -12,13 +12,63 @@ This is a detached fork of <https://github.com/timjroberts/cucumber-js-tsflow>.
|
|
|
12
12
|
|
|
13
13
|
This fork has been drastically modified from the original and will eventually be moved to a new project. In addition, the SpecFlow project has reached [end of life](https://reqnroll.net/news/2025/01/specflow-end-of-life-has-been-announced/), and this project will be rebranded. Further details will be provided in future updates. However, the new project will support the same functionality as cucumber-tsflow while providing additional tools and extensions.
|
|
14
14
|
|
|
15
|
+
## Release Updates (7.7.0)
|
|
16
|
+
|
|
17
|
+
This release focuses on correctness, performance, and code quality improvements across the codebase.
|
|
18
|
+
|
|
19
|
+
### Bug Fixes
|
|
20
|
+
|
|
21
|
+
- **`throw error()` in `test-case-runner.ts`** — four instances used `console.error()` (which returns `void`) instead of `new Error()`, meaning thrown errors were always `undefined`.
|
|
22
|
+
- **Broken `escapeRegExp` in `runtime/utils.ts`** — the function was a no-op and double-processed intentionally constructed regex syntax. Removed entirely.
|
|
23
|
+
- **Missing hook failure checks in serial adapter** — `runBeforeAllHooks()` and `runAfterAllHooks()` return values were ignored. Added failure propagation so hook errors are reported correctly.
|
|
24
|
+
- **Package exports typo** — trailing apostrophe on the `esbuild-transpiler` export key.
|
|
25
|
+
- **Misspelled folder name** — renamed `step-definition-snippit-syntax` to `step-definition-snippet-syntax` and updated all import references.
|
|
26
|
+
|
|
27
|
+
### New Features
|
|
28
|
+
|
|
29
|
+
- **Parallel preload** (`parallelLoad` configuration option) — warms transpiler on-disk caches in parallel `worker_threads` before the main support-code load phase. Each worker loads a subset of support files, triggering transpilation and populating the filesystem cache. The main thread's subsequent load (and any parallel child processes) then hit warm caches, significantly reducing startup time for large projects. Set `parallelLoad: true` for automatic thread count or provide an explicit number.
|
|
30
|
+
|
|
31
|
+
### Performance and Efficiency
|
|
32
|
+
|
|
33
|
+
- **Replaced `underscore` with native methods** — removed all `_.map()`, `_.flatten()`, and `_.filter()` calls in favour of native `Array.prototype` equivalents.
|
|
34
|
+
- **O(1) binding lookup** — added a `Map` index to `BindingRegistry` for constant-time `getStepBindingByCucumberKey()` and `hasBindingForKey()` lookups, replacing linear scans.
|
|
35
|
+
- **Collapsed `updateSupportCodeLibrary` switch** — replaced a 9-case `switch` with a lookup map.
|
|
36
|
+
- **Simplified constructor injection** — replaced a 10-case `switch` in `ManagedScenarioContext` with a single spread call, removing the previous limit of nine context objects.
|
|
37
|
+
- **Extracted `replaceFormatAlias` helper** — deduplicated two identical format-replacement loops in `load-configuration.ts`.
|
|
38
|
+
|
|
39
|
+
### Removed
|
|
40
|
+
|
|
41
|
+
- `underscore` runtime dependency and `@types/underscore` dev dependency.
|
|
42
|
+
- Empty `src/support_code_library_builder/` directory.
|
|
43
|
+
- Legacy `tslint:disable` comments.
|
|
44
|
+
|
|
45
|
+
### Documentation
|
|
46
|
+
|
|
47
|
+
- Added `Architecture.md` describing the project's architectural design, execution flow, and component relationships.
|
|
48
|
+
|
|
49
|
+
## Release Updates (7.6.0)
|
|
50
|
+
|
|
51
|
+
This release adds a new API function for incremental support-code reloading and consolidates the internal Vue SFC compiler.
|
|
52
|
+
|
|
53
|
+
### `reloadSupport` API
|
|
54
|
+
|
|
55
|
+
- **`reloadSupport(options, changedPaths, environment?)`** — evicts only the changed files (and their dependents) from Node's `require.cache`, then re-requires all support files. Unchanged files resolve instantly from transpiler cache; only changed files pay the full compilation cost. Pass an empty `changedPaths` array to evict and reload all support modules.
|
|
56
|
+
- Designed for use by persistent worker processes such as the companion [VS Code Extension](https://marketplace.visualstudio.com/items?itemName=lynxwall.cucumber-tsflow-vscode), which can call `reloadSupport` when a step file is saved instead of doing a full `loadSupport` on every run.
|
|
57
|
+
|
|
58
|
+
### Vue SFC compiler consolidation
|
|
59
|
+
|
|
60
|
+
- The CJS Vue SFC compiler (previously a 9-file Vite-plugin-derived implementation in `vue-sfc/`) has been replaced by a single shared `vue-sfc-compiler.ts` that both the CJS transpilers and the ESM loaders delegate to.
|
|
61
|
+
- Removed the `rollup` and `@rollup/pluginutils` dependencies, which were only used by the old CJS implementation.
|
|
62
|
+
- Fixed a bug where image assets referenced in Vue templates (e.g. `<img src="...">`) caused a `SyntaxError: Invalid or unexpected token` in CJS mode. Asset URL transforms are now disabled — `src` attributes remain as literal strings, which is the correct behaviour for unit testing Vue components with `@vue/test-utils`.
|
|
63
|
+
- Fixed duplicate **"Using Experimental Decorators."** console message that appeared twice when `experimentalDecorators: true` was set.
|
|
64
|
+
|
|
15
65
|
## Release Updates (7.3.0)
|
|
16
66
|
|
|
17
67
|
With this release, we've finally added support for ESM Modules. For details on the new transpilers/loaders please see: [cucumber-tsflow ESM implementation](https://github.com/LynxWall/cucumber-js-tsflow/blob/master/cucumber-tsflow/src/transpilers/esm/README.md).
|
|
18
68
|
|
|
19
69
|
Along with ESM support, additional updates include:
|
|
20
70
|
|
|
21
|
-
- Cucumber-JS updated to version 12.2.0
|
|
71
|
+
- Cucumber-JS updated to version 12.2.0 (later updated to 12.7.0 in 7.7.0)
|
|
22
72
|
- Typescript updated to version 5.9.2
|
|
23
73
|
- ts-node replaced with ts-node-maintained. For more information, please see the section titled **Node 22+ and ts-node** in the [cucumber-tsflow ESM implementation](https://github.com/LynxWall/cucumber-js-tsflow/blob/master/cucumber-tsflow/src/transpilers/esm/README.md).
|
|
24
74
|
- Other package updates.
|
|
@@ -75,6 +125,8 @@ This fork of cucumber-tsflow provides the following features that extend the ori
|
|
|
75
125
|
|
|
76
126
|
- Support for Parallel execution of tests.
|
|
77
127
|
|
|
128
|
+
- Parallel preload of transpiler caches via the `parallelLoad` configuration option, reducing startup time for large projects.
|
|
129
|
+
|
|
78
130
|
- A behave-json-formatter that fixes json so it can be used with Behave Pro.
|
|
79
131
|
|
|
80
132
|
- A junit-bamboo formatter that generates xml compatible with the Bamboo JUnit plugin.
|
|
@@ -126,9 +178,9 @@ Feature: Example Feature
|
|
|
126
178
|
This is an example feature
|
|
127
179
|
|
|
128
180
|
Scenario: Adding two numbers
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
181
|
+
Given I enter 2 and 8
|
|
182
|
+
When checking the results
|
|
183
|
+
Then I receive the result 10
|
|
132
184
|
```
|
|
133
185
|
|
|
134
186
|
### Create the Support Files to support the Feature
|
|
@@ -144,27 +196,27 @@ Create a new 'ArithmeticSteps.ts' file:
|
|
|
144
196
|
```javascript
|
|
145
197
|
// features/ArithmeticSteps.ts
|
|
146
198
|
|
|
147
|
-
import { binding, given, then } from "@lynxwall/cucumber-tsflow";
|
|
199
|
+
import { binding, given, when, then } from "@lynxwall/cucumber-tsflow";
|
|
148
200
|
|
|
149
201
|
@binding()
|
|
150
202
|
export default class ArithmeticSteps {
|
|
151
203
|
private computedResult = 0;
|
|
152
204
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
205
|
+
@given('I enter {int} and {int}')
|
|
206
|
+
iEnterintAndint(int: number, int2: number): any {
|
|
207
|
+
this.computedResult = int + int2;
|
|
156
208
|
}
|
|
157
209
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
210
|
+
@when('checking the results')
|
|
211
|
+
checkingTheResults(): any {
|
|
212
|
+
expect(this.computedResult).to.be.greaterThan(0);
|
|
213
|
+
}
|
|
162
214
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
215
|
+
@then('I receive the result {int}')
|
|
216
|
+
iReceiveTheResultint(int: number): any {
|
|
217
|
+
if (int !== this.computedResult) {
|
|
218
|
+
throw new Error('Arithmetic Error');
|
|
219
|
+
}
|
|
168
220
|
}
|
|
169
221
|
}
|
|
170
222
|
```
|
|
@@ -175,7 +227,7 @@ export default class ArithmeticSteps {
|
|
|
175
227
|
|
|
176
228
|
All support code, which includes your step definition files along with any test fixtures, utilities and references to source code are transpiled on the fly using transpilers that are included with cucumber-tsflow. This eliminates the requirement to prebuild any test code along with associated management of those builds.
|
|
177
229
|
|
|
178
|
-
If not using one of the [transpilers](#transpiler-and-vue3-supported) listed below you'll need to implement your own transpiler using guidance found in Cucumber-JS documentation: [Transpiling](https://github.com/cucumber/cucumber-js/blob/v12.
|
|
230
|
+
If not using one of the [transpilers](#transpiler-and-vue3-supported) listed below you'll need to implement your own transpiler using guidance found in Cucumber-JS documentation: [Transpiling](https://github.com/cucumber/cucumber-js/blob/v12.7.0/docs/transpiling.md)
|
|
179
231
|
|
|
180
232
|
## Transpilers and TypeScript
|
|
181
233
|
|
|
@@ -198,35 +250,35 @@ There are two different bundlers, or transpilers, used in cucumber-tsflow: **ts-
|
|
|
198
250
|
The following typescript configuration is used in the ts-node transpilers configured for official decorators:
|
|
199
251
|
|
|
200
252
|
```typescript
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
```
|
|
214
|
-
|
|
215
|
-
This next typescript configuration is used in the ts-node transpilers configured for
|
|
253
|
+
compilerOptions: {
|
|
254
|
+
module: 'nodeNext',
|
|
255
|
+
target: 'es2022',
|
|
256
|
+
strict: true,
|
|
257
|
+
allowJs: true,
|
|
258
|
+
allowSyntheticDefaultImports: true,
|
|
259
|
+
esModuleInterop: true,
|
|
260
|
+
experimentalDecorators: false,
|
|
261
|
+
resolveJsonModule: true,
|
|
262
|
+
skipLibCheck: true,
|
|
263
|
+
lib: ['es2022', 'esnext.decorators']
|
|
264
|
+
}
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
This next typescript configuration is used in the ts-node transpilers configured for experimental decorators:
|
|
216
268
|
|
|
217
269
|
```typescript
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
270
|
+
compilerOptions: {
|
|
271
|
+
module: 'nodeNext',
|
|
272
|
+
target: 'es2022',
|
|
273
|
+
strict: true,
|
|
274
|
+
allowJs: true,
|
|
275
|
+
allowSyntheticDefaultImports: true,
|
|
276
|
+
esModuleInterop: true,
|
|
277
|
+
experimentalDecorators: true,
|
|
278
|
+
resolveJsonModule: true,
|
|
279
|
+
skipLibCheck: true,
|
|
280
|
+
lib: ['es2022']
|
|
281
|
+
}
|
|
230
282
|
```
|
|
231
283
|
|
|
232
284
|
As you can see the only difference is the setting for experimentalDecorators and the lib imports.
|
|
@@ -236,19 +288,19 @@ When test runs are started, the settings from your local tsconfig.json are loade
|
|
|
236
288
|
For example, the settings from the cucumber-tsflow vue test project is shown below:
|
|
237
289
|
|
|
238
290
|
```json
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
291
|
+
"compilerOptions": {
|
|
292
|
+
"baseUrl": ".",
|
|
293
|
+
"module": "nodeNext",
|
|
294
|
+
"target": "es2022",
|
|
295
|
+
"strict": true,
|
|
296
|
+
"allowJs": true,
|
|
297
|
+
"allowSyntheticDefaultImports": true,
|
|
298
|
+
"esModuleInterop": true,
|
|
299
|
+
"resolveJsonModule": true,
|
|
300
|
+
"skipLibCheck": true,
|
|
301
|
+
"lib": ["es2022", "esnext.decorators"],
|
|
302
|
+
"typeRoots": ["../../node_modules/@types"]
|
|
303
|
+
}
|
|
252
304
|
```
|
|
253
305
|
|
|
254
306
|
These settings are similar to the default transpiler settings, which will not cause an issue.
|
|
@@ -263,11 +315,11 @@ Cucumber-tsflow provides two esbuild transpilers: one with esbuild and support f
|
|
|
263
315
|
|
|
264
316
|
```typescript
|
|
265
317
|
const commonOptions: CommonOptions = {
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
318
|
+
format: 'cjs',
|
|
319
|
+
logLevel: 'info',
|
|
320
|
+
target: [`es2022`],
|
|
321
|
+
minify: false,
|
|
322
|
+
sourcemap: 'external'
|
|
271
323
|
};
|
|
272
324
|
```
|
|
273
325
|
|
|
@@ -281,10 +333,10 @@ When using official decorators the following settings are added using the esbuil
|
|
|
281
333
|
|
|
282
334
|
```typescript
|
|
283
335
|
commonOptions.tsconfigRaw = {
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
336
|
+
compilerOptions: {
|
|
337
|
+
importsNotUsedAsValues: 'remove',
|
|
338
|
+
strict: true
|
|
339
|
+
}
|
|
288
340
|
};
|
|
289
341
|
```
|
|
290
342
|
|
|
@@ -294,11 +346,11 @@ When using experimental decorators the experimentalDecorators setting is added t
|
|
|
294
346
|
|
|
295
347
|
```typescript
|
|
296
348
|
commonOptions.tsconfigRaw = {
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
349
|
+
compilerOptions: {
|
|
350
|
+
experimentalDecorators: true,
|
|
351
|
+
importsNotUsedAsValues: 'remove',
|
|
352
|
+
strict: true
|
|
353
|
+
}
|
|
302
354
|
};
|
|
303
355
|
```
|
|
304
356
|
|
|
@@ -338,7 +390,7 @@ You can also add a script to package.json to execute the tests as shown below:
|
|
|
338
390
|
|
|
339
391
|
```json
|
|
340
392
|
"scripts": {
|
|
341
|
-
|
|
393
|
+
"test": "cucumber-tsflow -p esnode"
|
|
342
394
|
}
|
|
343
395
|
```
|
|
344
396
|
|
|
@@ -396,20 +448,21 @@ echo $?
|
|
|
396
448
|
|
|
397
449
|
## New Configuration options
|
|
398
450
|
|
|
399
|
-
As mentioned, when using cucumber-tsflow to execute tests all of the configuration options documented here are supported: <https://github.com/cucumber/cucumber-js/blob/v12.
|
|
451
|
+
As mentioned, when using cucumber-tsflow to execute tests all of the configuration options documented here are supported: <https://github.com/cucumber/cucumber-js/blob/v12.7.0/docs/configuration.md>
|
|
400
452
|
|
|
401
453
|
In addition to cucumber configuration options the following two options have been added:
|
|
402
454
|
|
|
403
455
|
| Name | Type | Repeatable | CLI Option | Description | Default |
|
|
404
456
|
| ------------------------ | --------- | ---------- | --------------------------- | ------------------------------------------------------------ | ------- |
|
|
405
|
-
| `transpiler` | `string`
|
|
406
|
-
| `debugFile` | `string`
|
|
407
|
-
| `enableVueStyle` | `boolean`
|
|
408
|
-
| `experimentalDecorators` | `boolean`
|
|
457
|
+
| `transpiler` | `string` | No | `--transpiler` | Name of the transpiler to use: es-vue, ts-vue, es-node, ts-node, es-vue-esm, es-node-esm, ts-vue-esm, ts-node-esm | none |
|
|
458
|
+
| `debugFile` | `string` | No | `--debug-file` | Path to a file with steps for debugging | |
|
|
459
|
+
| `enableVueStyle` | `boolean` | No | `--enable-vue-style` | Enable Vue `<style>` block when compiling Vue SFC. | false |
|
|
460
|
+
| `experimentalDecorators` | `boolean` | No | `--experimental-decorators` | Enable TypeScript Experimental Decorators. | false |
|
|
461
|
+
| `parallelLoad` | `boolean \| number` | No | | Pre-warm transpiler caches in parallel worker threads before loading support code. `true` = auto thread count, number = explicit count. | false |
|
|
409
462
|
|
|
410
463
|
### Transpiler and Vue3 supported
|
|
411
464
|
|
|
412
|
-
Using TypeScript with cucumber-js requires setting tsconfig.json parameters as described here: [cucumber-js Transpiling](https://github.com/cucumber/cucumber-js/blob/v12.
|
|
465
|
+
Using TypeScript with cucumber-js requires setting tsconfig.json parameters as described here: [cucumber-js Transpiling](https://github.com/cucumber/cucumber-js/blob/v12.7.0/docs/transpiling.md). In addition, there is no support for transpiling Vue files with cucumber-js.
|
|
413
466
|
|
|
414
467
|
As a result, cucumber-tsflow adds several configurations for transpiling TypeScript code using the recommended configuration. In addition, support has been added to transform .vue files during test execution allowing you to test Vue SFC components using cucumber.
|
|
415
468
|
|
|
@@ -437,27 +490,27 @@ In the table above:
|
|
|
437
490
|
|
|
438
491
|
**NOTE:** When using Vue transpilers **jsdom** is also loaded globally to support loading and testing Vue SFC components.
|
|
439
492
|
|
|
440
|
-
|
|
493
|
+
#### Using the transpiler configuration option
|
|
441
494
|
|
|
442
495
|
When configuring cucumber to execute tests you can specify which transpiler to use with the `transpiler` configuration option as shown below:
|
|
443
496
|
|
|
444
497
|
```json
|
|
445
498
|
{
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
499
|
+
"default": {
|
|
500
|
+
"transpiler": "es-vue"
|
|
501
|
+
}
|
|
449
502
|
}
|
|
450
503
|
```
|
|
451
504
|
|
|
452
|
-
|
|
505
|
+
#### Alternate without using the transpiler option
|
|
453
506
|
|
|
454
507
|
You can also use the `requireModule` parameter to configure a transpiler. The following example shows how to configure cucumber to use the `esvue` transpiler with the `requireModule` option.
|
|
455
508
|
|
|
456
509
|
```json
|
|
457
510
|
{
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
511
|
+
"default": {
|
|
512
|
+
"requireModule": ["@lynxwall/cucumber-tsflow/esvue"]
|
|
513
|
+
}
|
|
461
514
|
}
|
|
462
515
|
```
|
|
463
516
|
|
|
@@ -467,45 +520,45 @@ The new `debugFile` configuration option allows you to specify a .ts file with s
|
|
|
467
520
|
|
|
468
521
|
If using VSCode to edit your project the following launch configurations can be used:
|
|
469
522
|
|
|
470
|
-
|
|
523
|
+
#### Debug All
|
|
471
524
|
|
|
472
525
|
```json
|
|
473
526
|
{
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
527
|
+
"name": "Debug All",
|
|
528
|
+
"type": "node",
|
|
529
|
+
"request": "launch",
|
|
530
|
+
"program": "${workspaceRoot}/node_modules/@lynxwall/cucumber-tsflow/bin/cucumber-tsflow/vue",
|
|
531
|
+
"stopOnEntry": true,
|
|
532
|
+
"args": ["-p", "esvue"],
|
|
533
|
+
"cwd": "${workspaceRoot}",
|
|
534
|
+
"runtimeExecutable": null,
|
|
535
|
+
"runtimeArgs": ["--nolazy"],
|
|
536
|
+
"env": {
|
|
537
|
+
"NODE_ENV": "development"
|
|
538
|
+
},
|
|
539
|
+
"console": "integratedTerminal",
|
|
540
|
+
"sourceMaps": true
|
|
488
541
|
}
|
|
489
542
|
```
|
|
490
543
|
|
|
491
|
-
|
|
544
|
+
#### Debug Feature
|
|
492
545
|
|
|
493
546
|
```json
|
|
494
547
|
{
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
548
|
+
"name": "Debug Feature",
|
|
549
|
+
"type": "node",
|
|
550
|
+
"request": "launch",
|
|
551
|
+
"program": "${workspaceRoot}/node_modules/@lynxwall/cucumber-tsflow/bin/cucumber-tsflow/vue",
|
|
552
|
+
"stopOnEntry": true,
|
|
553
|
+
"args": ["--debug-file", "${file}", "-p", "esvue"],
|
|
554
|
+
"cwd": "${workspaceRoot}",
|
|
555
|
+
"runtimeExecutable": null,
|
|
556
|
+
"runtimeArgs": ["--nolazy"],
|
|
557
|
+
"env": {
|
|
558
|
+
"NODE_ENV": "development"
|
|
559
|
+
},
|
|
560
|
+
"console": "integratedTerminal",
|
|
561
|
+
"sourceMaps": true
|
|
509
562
|
}
|
|
510
563
|
```
|
|
511
564
|
|
|
@@ -558,9 +611,9 @@ The following Scenario uses boolean values in the Given and Then statements:
|
|
|
558
611
|
|
|
559
612
|
```gherkin
|
|
560
613
|
Scenario: Boolean type supported
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
614
|
+
Given I pass true into a step
|
|
615
|
+
When checking the boolean value
|
|
616
|
+
Then we can see that true was passed in
|
|
564
617
|
```
|
|
565
618
|
|
|
566
619
|
The associated step definition replaces `true` in this scenario with a `{boolean}` expression as shown below:
|
|
@@ -568,17 +621,17 @@ The associated step definition replaces `true` in this scenario with a `{boolean
|
|
|
568
621
|
```typescript
|
|
569
622
|
@given('I pass {boolean} into a step')
|
|
570
623
|
iPassbooleanIntoAStep(boolean: boolean): any {
|
|
571
|
-
|
|
624
|
+
this.boolValue = boolean;
|
|
572
625
|
}
|
|
573
626
|
|
|
574
627
|
@when('checking the boolean value')
|
|
575
628
|
checkingTheBooleanValue(): any {
|
|
576
|
-
|
|
629
|
+
expect(this.boolValue).not.to.be.undefined;
|
|
577
630
|
}
|
|
578
631
|
|
|
579
632
|
@then('we can see that {boolean} was passed in')
|
|
580
633
|
weCanThatbooleanWasPassedIn(boolean: boolean): any {
|
|
581
|
-
|
|
634
|
+
expect(this.boolValue).to.equal(boolean);
|
|
582
635
|
}
|
|
583
636
|
```
|
|
584
637
|
|
|
@@ -606,7 +659,7 @@ public givenAValueBasedSearch(searchValue: string): void {
|
|
|
606
659
|
}
|
|
607
660
|
```
|
|
608
661
|
|
|
609
|
-
**Note**: Tags added to steps work the same as "Tagged Hooks" documented here: <https://github.com/cucumber/cucumber-js/blob/v12.
|
|
662
|
+
**Note**: Tags added to steps work the same as "Tagged Hooks" documented here: <https://github.com/cucumber/cucumber-js/blob/v12.7.0/docs/support_files/hooks.md>
|
|
610
663
|
|
|
611
664
|
## Hooks
|
|
612
665
|
|
|
@@ -638,12 +691,12 @@ class MySteps {
|
|
|
638
691
|
|
|
639
692
|
@beforeStep('@addNumbers')
|
|
640
693
|
public beforeStep() {
|
|
641
|
-
|
|
694
|
+
...
|
|
642
695
|
}
|
|
643
696
|
|
|
644
697
|
@afterStep('@addNumbers')
|
|
645
698
|
public afterStep() {
|
|
646
|
-
|
|
699
|
+
...
|
|
647
700
|
}
|
|
648
701
|
|
|
649
702
|
@after()
|
|
@@ -707,15 +760,15 @@ If it doesn't already exist, create a file named cucumber.json at the root of yo
|
|
|
707
760
|
|
|
708
761
|
#### Using the behave json formatter
|
|
709
762
|
|
|
710
|
-
The following example shows how to configure the behave formatter in cucumber.json. The tsflow-snippet-syntax module is configured as the default snippet syntax and does not require configuration. However, you can override the snippet syntax as documented here: <https://github.com/cucumber/cucumber-js/blob/v12.
|
|
763
|
+
The following example shows how to configure the behave formatter in cucumber.json. The tsflow-snippet-syntax module is configured as the default snippet syntax and does not require configuration. However, you can override the snippet syntax as documented here: <https://github.com/cucumber/cucumber-js/blob/v12.7.0/docs/custom_snippet_syntaxes.md>
|
|
711
764
|
|
|
712
765
|
```typescript
|
|
713
766
|
{
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
767
|
+
"default": {
|
|
768
|
+
"format": [
|
|
769
|
+
"behave:cucumber_report.json"
|
|
770
|
+
]
|
|
771
|
+
}
|
|
719
772
|
}
|
|
720
773
|
```
|
|
721
774
|
|
|
@@ -725,11 +778,11 @@ The following example shows how to configure the bamboo junit formatter in cucum
|
|
|
725
778
|
|
|
726
779
|
```typescript
|
|
727
780
|
{
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
781
|
+
"default": {
|
|
782
|
+
"format": [
|
|
783
|
+
"junitbamboo:cucumber_report.xml"
|
|
784
|
+
]
|
|
785
|
+
}
|
|
733
786
|
}
|
|
734
787
|
```
|
|
735
788
|
|
|
@@ -756,7 +809,7 @@ Each scenario in a feature will get a new instance of the _Context_ object when
|
|
|
756
809
|
- Context classes now support an `initialize()` function that can be defined synchronous or asynchronous. The `initialize()` function is called after the `BeforeAll` hook and before any other hooks or steps. This provides the ability to initialize a scenario context before any tests are executed with support for async operations.
|
|
757
810
|
- Context classes have always supported a `dispose()` function for cleanup. However, with latest updates the `dispose()` function can be defined synchronously or asynchronously.
|
|
758
811
|
- versions >= 6.4.0
|
|
759
|
-
- The current Cucumber World object is now available as a constructor parameter on all classes defined for Context Injection. For more information on the World object see: [Access to Cucumber.js World object](#access-to-
|
|
812
|
+
- The current Cucumber World object is now available as a constructor parameter on all classes defined for Context Injection. For more information on the World object see: [Access to Cucumber.js World object](#access-to-cucumberjs-world-object).
|
|
760
813
|
|
|
761
814
|
### Using Context Injection
|
|
762
815
|
|
|
@@ -773,30 +826,30 @@ import { World } from '@cucumber/cucumber';
|
|
|
773
826
|
import { EndTestCaseInfo, StartTestCaseInfo } from '@lynxwall/cucumber-tsflow';
|
|
774
827
|
|
|
775
828
|
export class ScenarioContext {
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
829
|
+
public world: World;
|
|
830
|
+
public someValue = '';
|
|
831
|
+
private id: string = '';
|
|
832
|
+
|
|
833
|
+
constructor(worldObj: World) {
|
|
834
|
+
this.world = worldObj;
|
|
835
|
+
}
|
|
836
|
+
public initialize({ pickle, gherkinDocument }: StartTestCaseInfo): void {
|
|
837
|
+
this.id = this.makeid(5);
|
|
838
|
+
console.log(`Sync init: ${this.id}`);
|
|
839
|
+
console.log(`Start Test Case: ${this.getFeatureAndScenario(gherkinDocument.uri!, pickle.name)}`);
|
|
840
|
+
}
|
|
841
|
+
public dispose({ pickle, gherkinDocument }: EndTestCaseInfo): void {
|
|
842
|
+
console.log(`Sync dispose: ${this.id}`);
|
|
843
|
+
console.log(`End Test Case: ${this.getFeatureAndScenario(gherkinDocument.uri!, pickle.name)}`);
|
|
844
|
+
}
|
|
845
|
+
private getFeatureAndScenario(path: string, scenario: string): string | undefined {
|
|
846
|
+
...
|
|
794
847
|
return `${fileName}: ${scenario.split(' ').join('-')}`;
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
848
|
+
}
|
|
849
|
+
private makeid(length: number) {
|
|
850
|
+
...
|
|
851
|
+
return result;
|
|
852
|
+
}
|
|
800
853
|
}
|
|
801
854
|
```
|
|
802
855
|
|
|
@@ -807,39 +860,39 @@ import { World } from '@cucumber/cucumber';
|
|
|
807
860
|
import { EndTestCaseInfo, StartTestCaseInfo } from '@lynxwall/cucumber-tsflow';
|
|
808
861
|
|
|
809
862
|
export class ScenarioContext {
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
863
|
+
public world: World;
|
|
864
|
+
public someValue = '';
|
|
865
|
+
private id: string = '';
|
|
866
|
+
|
|
867
|
+
constructor(worldObj: World) {
|
|
868
|
+
this.world = worldObj;
|
|
869
|
+
}
|
|
870
|
+
public async initialize({ pickle, gherkinDocument }: StartTestCaseInfo): Promise<void> {
|
|
871
|
+
this.id = this.makeid(5);
|
|
872
|
+
await this.logTest(`Async init: ${this.id}`);
|
|
873
|
+
await this.logTest(`Start Test Case: ${this.getFeatureAndScenario(gherkinDocument.uri!, pickle.name)}`);
|
|
874
|
+
}
|
|
875
|
+
public async dispose({ pickle, gherkinDocument }: EndTestCaseInfo): Promise<void> {
|
|
876
|
+
await this.logTest(`Async dispose: ${this.id}`);
|
|
877
|
+
await this.logTest(`End Test Case: ${this.getFeatureAndScenario(gherkinDocument.uri!, pickle.name)}`);
|
|
878
|
+
}
|
|
879
|
+
async logTest(text: string): Promise<void> {
|
|
880
|
+
await Promise.resolve(console.log(text));
|
|
881
|
+
}
|
|
882
|
+
private getFeatureAndScenario(path: string, scenario: string): string | undefined {
|
|
883
|
+
...
|
|
831
884
|
return `${fileName}: ${scenario.split(' ').join('-')}`;
|
|
832
|
-
|
|
885
|
+
}
|
|
833
886
|
private makeid(length: number) {
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
887
|
+
...
|
|
888
|
+
return result;
|
|
889
|
+
}
|
|
837
890
|
}
|
|
838
891
|
```
|
|
839
892
|
|
|
840
893
|
**Initialize Binding in Step class:**
|
|
841
894
|
|
|
842
|
-
- Update the `@binding()` decorator to indicate the types of context objects that are required by the 'binding' class.
|
|
895
|
+
- Update the `@binding()` decorator to indicate the types of context objects that are required by the 'binding' class. There is no limit on the number of _Context_ objects.
|
|
843
896
|
- Define a constructor on the `@binding` class with steps that need access to the shared data that accepts one or more context objects as parameters based on initialization of the `@binding` decorator.
|
|
844
897
|
|
|
845
898
|
**Single Context class example:**
|
|
@@ -851,18 +904,18 @@ import { expect } from 'chai';
|
|
|
851
904
|
|
|
852
905
|
@binding([ScenarioContext])
|
|
853
906
|
export default class InjectionTestSteps1 {
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
907
|
+
constructor(private context: ScenarioContext) {}
|
|
908
|
+
|
|
909
|
+
@given('The Workspace is available and valid')
|
|
910
|
+
theWorkspaceIsAvailableAndValid() {
|
|
911
|
+
expect(this.context).not.to.be.undefined;
|
|
912
|
+
expect(this.context.world).not.to.be.undefined;
|
|
913
|
+
}
|
|
914
|
+
|
|
915
|
+
@when('I change the workspace in one step definition class')
|
|
916
|
+
whenIChangeTheWorkspaceInOneStep() {
|
|
917
|
+
this.context.someValue = 'value changed';
|
|
918
|
+
}
|
|
866
919
|
}
|
|
867
920
|
```
|
|
868
921
|
|
|
@@ -876,24 +929,24 @@ import { expect } from 'chai';
|
|
|
876
929
|
|
|
877
930
|
@binding([ScenarioContext, SyncContext])
|
|
878
931
|
export default class InjectionTestSteps1 {
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
932
|
+
constructor(
|
|
933
|
+
private context: ScenarioContext,
|
|
934
|
+
private syncContext: SyncContext
|
|
935
|
+
) {}
|
|
936
|
+
|
|
937
|
+
@given('The Workspace is available and valid')
|
|
938
|
+
theWorkspaceIsAvailableAndValid() {
|
|
939
|
+
expect(this.context).not.to.be.undefined;
|
|
940
|
+
expect(this.context.world).not.to.be.undefined;
|
|
941
|
+
|
|
942
|
+
expect(this.syncContext).not.to.be.undefined;
|
|
943
|
+
expect(this.syncContext.world).not.to.be.undefined;
|
|
944
|
+
}
|
|
945
|
+
|
|
946
|
+
@when('I change the workspace in one step definition class')
|
|
947
|
+
whenIChangeTheWorkspaceInOneStep() {
|
|
948
|
+
this.context.someValue = 'value changed';
|
|
949
|
+
}
|
|
897
950
|
}
|
|
898
951
|
```
|
|
899
952
|
|
|
@@ -911,16 +964,16 @@ Starting with version **6.4.0** the Cucumber World object is now passed into a _
|
|
|
911
964
|
import { World } from '@cucumber/cucumber';
|
|
912
965
|
|
|
913
966
|
export class ScenarioContext {
|
|
914
|
-
|
|
915
|
-
|
|
967
|
+
public world: World;
|
|
968
|
+
public someValue = '';
|
|
916
969
|
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
970
|
+
constructor(worldObj: World) {
|
|
971
|
+
this.world = worldObj;
|
|
972
|
+
}
|
|
920
973
|
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
974
|
+
public dispose(): void {
|
|
975
|
+
this.someValue = '';
|
|
976
|
+
}
|
|
924
977
|
}
|
|
925
978
|
```
|
|
926
979
|
|
|
@@ -942,8 +995,8 @@ With this approach, you would define a world property on simple _Context_ class
|
|
|
942
995
|
import { World } from '@cucumber/cucumber';
|
|
943
996
|
|
|
944
997
|
export class ScenarioContext {
|
|
945
|
-
|
|
946
|
-
|
|
998
|
+
public world!: World;
|
|
999
|
+
public someValue = '';
|
|
947
1000
|
}
|
|
948
1001
|
```
|
|
949
1002
|
|
|
@@ -958,14 +1011,14 @@ import { World } from '@cucumber/cucumber';
|
|
|
958
1011
|
|
|
959
1012
|
@binding([ScenarioContext])
|
|
960
1013
|
export default class WorldContext {
|
|
961
|
-
|
|
1014
|
+
_worldObj?: World;
|
|
962
1015
|
|
|
963
|
-
|
|
1016
|
+
constructor(private context: ScenarioContext) {}
|
|
964
1017
|
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
1018
|
+
@before()
|
|
1019
|
+
beforeScenario() {
|
|
1020
|
+
this.context.world = this._worldObj as World;
|
|
1021
|
+
}
|
|
969
1022
|
}
|
|
970
1023
|
```
|
|
971
1024
|
|