@lynxwall/cucumber-tsflow 7.6.0 → 7.7.1

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.
Files changed (71) hide show
  1. package/README.md +266 -229
  2. package/lib/api/convert-configuration.d.ts +1 -0
  3. package/lib/api/convert-configuration.js +2 -0
  4. package/lib/api/convert-configuration.js.map +1 -1
  5. package/lib/api/load-configuration.js +23 -31
  6. package/lib/api/load-configuration.js.map +1 -1
  7. package/lib/api/load-support.d.ts +11 -2
  8. package/lib/api/load-support.js +31 -6
  9. package/lib/api/load-support.js.map +1 -1
  10. package/lib/api/loader-worker.d.ts +36 -0
  11. package/lib/api/loader-worker.js +74 -0
  12. package/lib/api/loader-worker.js.map +1 -0
  13. package/lib/api/parallel-loader.d.ts +31 -0
  14. package/lib/api/parallel-loader.js +169 -0
  15. package/lib/api/parallel-loader.js.map +1 -0
  16. package/lib/api/run-cucumber.js +42 -12
  17. package/lib/api/run-cucumber.js.map +1 -1
  18. package/lib/api/support.js +3 -0
  19. package/lib/api/support.js.map +1 -1
  20. package/lib/api/wrapper.mjs +1 -0
  21. package/lib/bindings/binding-decorator.d.ts +6 -0
  22. package/lib/bindings/binding-decorator.js +14 -0
  23. package/lib/bindings/binding-decorator.js.map +1 -1
  24. package/lib/bindings/binding-registry.d.ts +31 -1
  25. package/lib/bindings/binding-registry.js +95 -47
  26. package/lib/bindings/binding-registry.js.map +1 -1
  27. package/lib/bindings/step-binding.d.ts +37 -0
  28. package/lib/bindings/step-binding.js +23 -0
  29. package/lib/bindings/step-binding.js.map +1 -1
  30. package/lib/bindings/step-decorators.js.map +1 -1
  31. package/lib/bindings/types.js.map +1 -1
  32. package/lib/cli/argv-parser.d.ts +1 -0
  33. package/lib/cli/argv-parser.js +6 -0
  34. package/lib/cli/argv-parser.js.map +1 -1
  35. package/lib/formatter/{step-definition-snippit-syntax → step-definition-snippet-syntax}/tsflow-snippet-syntax.js.map +1 -1
  36. package/lib/index.d.ts +1 -1
  37. package/lib/index.js +1 -1
  38. package/lib/index.js.map +1 -1
  39. package/lib/runtime/coordinator.d.ts +2 -1
  40. package/lib/runtime/coordinator.js +4 -2
  41. package/lib/runtime/coordinator.js.map +1 -1
  42. package/lib/runtime/make-runtime.d.ts +3 -1
  43. package/lib/runtime/make-runtime.js +5 -4
  44. package/lib/runtime/make-runtime.js.map +1 -1
  45. package/lib/runtime/managed-scenario-context.js +2 -32
  46. package/lib/runtime/managed-scenario-context.js.map +1 -1
  47. package/lib/runtime/parallel/adapter.d.ts +4 -1
  48. package/lib/runtime/parallel/adapter.js +10 -2
  49. package/lib/runtime/parallel/adapter.js.map +1 -1
  50. package/lib/runtime/serial/adapter.d.ts +2 -1
  51. package/lib/runtime/serial/adapter.js +13 -3
  52. package/lib/runtime/serial/adapter.js.map +1 -1
  53. package/lib/runtime/test-case-runner.d.ts +4 -1
  54. package/lib/runtime/test-case-runner.js +4 -5
  55. package/lib/runtime/test-case-runner.js.map +1 -1
  56. package/lib/runtime/types.d.ts +2 -0
  57. package/lib/runtime/types.js.map +1 -1
  58. package/lib/runtime/utils.js +0 -6
  59. package/lib/runtime/utils.js.map +1 -1
  60. package/lib/runtime/worker.d.ts +14 -3
  61. package/lib/runtime/worker.js +91 -12
  62. package/lib/runtime/worker.js.map +1 -1
  63. package/lib/snippet.js +1 -1
  64. package/lib/snippet.js.map +1 -1
  65. package/lib/tsconfig.node.tsbuildinfo +1 -1
  66. package/lib/version.d.ts +1 -1
  67. package/lib/version.js +1 -1
  68. package/lib/version.js.map +1 -1
  69. package/package.json +8 -7
  70. /package/lib/formatter/{step-definition-snippit-syntax → step-definition-snippet-syntax}/tsflow-snippet-syntax.d.ts +0 -0
  71. /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.2.0 in TypeScript 5.9+.
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,6 +12,40 @@ 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
+
15
49
  ## Release Updates (7.6.0)
16
50
 
17
51
  This release adds a new API function for incremental support-code reloading and consolidates the internal Vue SFC compiler.
@@ -34,7 +68,7 @@ With this release, we've finally added support for ESM Modules. For details on t
34
68
 
35
69
  Along with ESM support, additional updates include:
36
70
 
37
- - 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)
38
72
  - Typescript updated to version 5.9.2
39
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).
40
74
  - Other package updates.
@@ -91,6 +125,8 @@ This fork of cucumber-tsflow provides the following features that extend the ori
91
125
 
92
126
  - Support for Parallel execution of tests.
93
127
 
128
+ - Parallel preload of transpiler caches via the `parallelLoad` configuration option, reducing startup time for large projects.
129
+
94
130
  - A behave-json-formatter that fixes json so it can be used with Behave Pro.
95
131
 
96
132
  - A junit-bamboo formatter that generates xml compatible with the Bamboo JUnit plugin.
@@ -142,9 +178,9 @@ Feature: Example Feature
142
178
  This is an example feature
143
179
 
144
180
  Scenario: Adding two numbers
145
- Given I enter 2 and 8
146
- When checking the results
147
- Then I receive the result 10
181
+ Given I enter 2 and 8
182
+ When checking the results
183
+ Then I receive the result 10
148
184
  ```
149
185
 
150
186
  ### Create the Support Files to support the Feature
@@ -160,27 +196,27 @@ Create a new 'ArithmeticSteps.ts' file:
160
196
  ```javascript
161
197
  // features/ArithmeticSteps.ts
162
198
 
163
- import { binding, given, then } from "@lynxwall/cucumber-tsflow";
199
+ import { binding, given, when, then } from "@lynxwall/cucumber-tsflow";
164
200
 
165
201
  @binding()
166
202
  export default class ArithmeticSteps {
167
203
  private computedResult = 0;
168
204
 
169
- @given('I enter {int} and {int}')
170
- iEnterintAndint(int: number, int2: number): any {
171
- this.computedResult = int + int2;
205
+ @given('I enter {int} and {int}')
206
+ iEnterintAndint(int: number, int2: number): any {
207
+ this.computedResult = int + int2;
172
208
  }
173
209
 
174
- @when('checking the results')
175
- checkingTheResults(): any {
176
- expect(this.computedResult).to.be.greaterThan(0);
177
- }
210
+ @when('checking the results')
211
+ checkingTheResults(): any {
212
+ expect(this.computedResult).to.be.greaterThan(0);
213
+ }
178
214
 
179
- @then('I receive the result {int}')
180
- iReceiveTheResultint(int: number): any {
181
- if (int !== this.computedResult) {
182
- throw new Error('Arithmetic Error');
183
- }
215
+ @then('I receive the result {int}')
216
+ iReceiveTheResultint(int: number): any {
217
+ if (int !== this.computedResult) {
218
+ throw new Error('Arithmetic Error');
219
+ }
184
220
  }
185
221
  }
186
222
  ```
@@ -191,7 +227,7 @@ export default class ArithmeticSteps {
191
227
 
192
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.
193
229
 
194
- 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.2.0/docs/transpiling.md)
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)
195
231
 
196
232
  ## Transpilers and TypeScript
197
233
 
@@ -214,35 +250,35 @@ There are two different bundlers, or transpilers, used in cucumber-tsflow: **ts-
214
250
  The following typescript configuration is used in the ts-node transpilers configured for official decorators:
215
251
 
216
252
  ```typescript
217
- compilerOptions: {
218
- module: 'nodeNext',
219
- target: 'es2022',
220
- strict: true,
221
- allowJs: true,
222
- allowSyntheticDefaultImports: true,
223
- esModuleInterop: true,
224
- experimentalDecorators: false,
225
- resolveJsonModule: true,
226
- skipLibCheck: true,
227
- lib: ['es2022', 'esnext.decorators']
228
- }
229
- ```
230
-
231
- This next typescript configuration is used in the ts-node transpilers configured for official decorators:
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:
232
268
 
233
269
  ```typescript
234
- compilerOptions: {
235
- module: 'nodeNext',
236
- target: 'es2022',
237
- strict: true,
238
- allowJs: true,
239
- allowSyntheticDefaultImports: true,
240
- esModuleInterop: true,
241
- experimentalDecorators: true,
242
- resolveJsonModule: true,
243
- skipLibCheck: true,
244
- lib: ['es2022']
245
- }
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
+ }
246
282
  ```
247
283
 
248
284
  As you can see the only difference is the setting for experimentalDecorators and the lib imports.
@@ -252,19 +288,19 @@ When test runs are started, the settings from your local tsconfig.json are loade
252
288
  For example, the settings from the cucumber-tsflow vue test project is shown below:
253
289
 
254
290
  ```json
255
- "compilerOptions": {
256
- "baseUrl": ".",
257
- "module": "nodeNext",
258
- "target": "es2022",
259
- "strict": true,
260
- "allowJs": true,
261
- "allowSyntheticDefaultImports": true,
262
- "esModuleInterop": true,
263
- "resolveJsonModule": true,
264
- "skipLibCheck": true,
265
- "lib": ["es2022", "esnext.decorators"],
266
- "typeRoots": ["../../node_modules/@types"]
267
- }
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
+ }
268
304
  ```
269
305
 
270
306
  These settings are similar to the default transpiler settings, which will not cause an issue.
@@ -279,11 +315,11 @@ Cucumber-tsflow provides two esbuild transpilers: one with esbuild and support f
279
315
 
280
316
  ```typescript
281
317
  const commonOptions: CommonOptions = {
282
- format: 'cjs',
283
- logLevel: 'info',
284
- target: [`es2022`],
285
- minify: false,
286
- sourcemap: 'external'
318
+ format: 'cjs',
319
+ logLevel: 'info',
320
+ target: [`es2022`],
321
+ minify: false,
322
+ sourcemap: 'external'
287
323
  };
288
324
  ```
289
325
 
@@ -297,10 +333,10 @@ When using official decorators the following settings are added using the esbuil
297
333
 
298
334
  ```typescript
299
335
  commonOptions.tsconfigRaw = {
300
- compilerOptions: {
301
- importsNotUsedAsValues: 'remove',
302
- strict: true
303
- }
336
+ compilerOptions: {
337
+ importsNotUsedAsValues: 'remove',
338
+ strict: true
339
+ }
304
340
  };
305
341
  ```
306
342
 
@@ -310,11 +346,11 @@ When using experimental decorators the experimentalDecorators setting is added t
310
346
 
311
347
  ```typescript
312
348
  commonOptions.tsconfigRaw = {
313
- compilerOptions: {
314
- experimentalDecorators: true,
315
- importsNotUsedAsValues: 'remove',
316
- strict: true
317
- }
349
+ compilerOptions: {
350
+ experimentalDecorators: true,
351
+ importsNotUsedAsValues: 'remove',
352
+ strict: true
353
+ }
318
354
  };
319
355
  ```
320
356
 
@@ -354,7 +390,7 @@ You can also add a script to package.json to execute the tests as shown below:
354
390
 
355
391
  ```json
356
392
  "scripts": {
357
- "test": "cucumber-tsflow -p esnode"
393
+ "test": "cucumber-tsflow -p esnode"
358
394
  }
359
395
  ```
360
396
 
@@ -412,20 +448,21 @@ echo $?
412
448
 
413
449
  ## New Configuration options
414
450
 
415
- 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.2.0/docs/configuration.md>
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>
416
452
 
417
453
  In addition to cucumber configuration options the following two options have been added:
418
454
 
419
455
  | Name | Type | Repeatable | CLI Option | Description | Default |
420
456
  | ------------------------ | --------- | ---------- | --------------------------- | ------------------------------------------------------------ | ------- |
421
- | `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 |
422
- | `debugFile` | `string` | No | `--debug-file` | Path to a file with steps for debugging | |
423
- | `enableVueStyle` | `boolean` | No | `--enable-vue-style` | Enable Vue `<style>` block when compiling Vue SFC. | false |
424
- | `experimentalDecorators` | `boolean` | No | `--experimental-decorators` | Enable TypeScript Experimental Decorators. | false |
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 |
425
462
 
426
463
  ### Transpiler and Vue3 supported
427
464
 
428
- Using TypeScript with cucumber-js requires setting tsconfig.json parameters as described here: [cucumber-js Transpiling](https://github.com/cucumber/cucumber-js/blob/v12.2.0/docs/transpiling.md). In addition, there is no support for transpiling Vue files with cucumber-js.
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.
429
466
 
430
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.
431
468
 
@@ -459,9 +496,9 @@ When configuring cucumber to execute tests you can specify which transpiler to u
459
496
 
460
497
  ```json
461
498
  {
462
- "default": {
463
- "transpiler": "es-vue"
464
- }
499
+ "default": {
500
+ "transpiler": "es-vue"
501
+ }
465
502
  }
466
503
  ```
467
504
 
@@ -471,9 +508,9 @@ You can also use the `requireModule` parameter to configure a transpiler. The fo
471
508
 
472
509
  ```json
473
510
  {
474
- "default": {
475
- "requireModule": ["@lynxwall/cucumber-tsflow/esvue"]
476
- }
511
+ "default": {
512
+ "requireModule": ["@lynxwall/cucumber-tsflow/esvue"]
513
+ }
477
514
  }
478
515
  ```
479
516
 
@@ -487,20 +524,20 @@ If using VSCode to edit your project the following launch configurations can be
487
524
 
488
525
  ```json
489
526
  {
490
- "name": "Debug All",
491
- "type": "node",
492
- "request": "launch",
493
- "program": "${workspaceRoot}/node_modules/@lynxwall/cucumber-tsflow/bin/cucumber-tsflow/vue",
494
- "stopOnEntry": true,
495
- "args": ["-p", "esvue"],
496
- "cwd": "${workspaceRoot}",
497
- "runtimeExecutable": null,
498
- "runtimeArgs": ["--nolazy"],
499
- "env": {
500
- "NODE_ENV": "development"
501
- },
502
- "console": "integratedTerminal",
503
- "sourceMaps": true
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
504
541
  }
505
542
  ```
506
543
 
@@ -508,20 +545,20 @@ If using VSCode to edit your project the following launch configurations can be
508
545
 
509
546
  ```json
510
547
  {
511
- "name": "Debug Feature",
512
- "type": "node",
513
- "request": "launch",
514
- "program": "${workspaceRoot}/node_modules/@lynxwall/cucumber-tsflow/bin/cucumber-tsflow/vue",
515
- "stopOnEntry": true,
516
- "args": ["--debug-file", "${file}", "-p", "esvue"],
517
- "cwd": "${workspaceRoot}",
518
- "runtimeExecutable": null,
519
- "runtimeArgs": ["--nolazy"],
520
- "env": {
521
- "NODE_ENV": "development"
522
- },
523
- "console": "integratedTerminal",
524
- "sourceMaps": true
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
525
562
  }
526
563
  ```
527
564
 
@@ -574,9 +611,9 @@ The following Scenario uses boolean values in the Given and Then statements:
574
611
 
575
612
  ```gherkin
576
613
  Scenario: Boolean type supported
577
- Given I pass true into a step
578
- When checking the boolean value
579
- Then we can see that true was passed in
614
+ Given I pass true into a step
615
+ When checking the boolean value
616
+ Then we can see that true was passed in
580
617
  ```
581
618
 
582
619
  The associated step definition replaces `true` in this scenario with a `{boolean}` expression as shown below:
@@ -584,17 +621,17 @@ The associated step definition replaces `true` in this scenario with a `{boolean
584
621
  ```typescript
585
622
  @given('I pass {boolean} into a step')
586
623
  iPassbooleanIntoAStep(boolean: boolean): any {
587
- this.boolValue = boolean;
624
+ this.boolValue = boolean;
588
625
  }
589
626
 
590
627
  @when('checking the boolean value')
591
628
  checkingTheBooleanValue(): any {
592
- expect(this.boolValue).not.to.be.undefined;
629
+ expect(this.boolValue).not.to.be.undefined;
593
630
  }
594
631
 
595
632
  @then('we can see that {boolean} was passed in')
596
633
  weCanThatbooleanWasPassedIn(boolean: boolean): any {
597
- expect(this.boolValue).to.equal(boolean);
634
+ expect(this.boolValue).to.equal(boolean);
598
635
  }
599
636
  ```
600
637
 
@@ -622,7 +659,7 @@ public givenAValueBasedSearch(searchValue: string): void {
622
659
  }
623
660
  ```
624
661
 
625
- **Note**: Tags added to steps work the same as "Tagged Hooks" documented here: <https://github.com/cucumber/cucumber-js/blob/v12.2.0/docs/support_files/hooks.md>
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>
626
663
 
627
664
  ## Hooks
628
665
 
@@ -654,12 +691,12 @@ class MySteps {
654
691
 
655
692
  @beforeStep('@addNumbers')
656
693
  public beforeStep() {
657
- ...
694
+ ...
658
695
  }
659
696
 
660
697
  @afterStep('@addNumbers')
661
698
  public afterStep() {
662
- ...
699
+ ...
663
700
  }
664
701
 
665
702
  @after()
@@ -723,15 +760,15 @@ If it doesn't already exist, create a file named cucumber.json at the root of yo
723
760
 
724
761
  #### Using the behave json formatter
725
762
 
726
- 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.2.0/docs/custom_snippet_syntaxes.md>
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>
727
764
 
728
765
  ```typescript
729
766
  {
730
- "default": {
731
- "format": [
732
- "behave:cucumber_report.json"
733
- ]
734
- }
767
+ "default": {
768
+ "format": [
769
+ "behave:cucumber_report.json"
770
+ ]
771
+ }
735
772
  }
736
773
  ```
737
774
 
@@ -741,11 +778,11 @@ The following example shows how to configure the bamboo junit formatter in cucum
741
778
 
742
779
  ```typescript
743
780
  {
744
- "default": {
745
- "format": [
746
- "junitbamboo:cucumber_report.xml"
747
- ]
748
- }
781
+ "default": {
782
+ "format": [
783
+ "junitbamboo:cucumber_report.xml"
784
+ ]
785
+ }
749
786
  }
750
787
  ```
751
788
 
@@ -789,30 +826,30 @@ import { World } from '@cucumber/cucumber';
789
826
  import { EndTestCaseInfo, StartTestCaseInfo } from '@lynxwall/cucumber-tsflow';
790
827
 
791
828
  export class ScenarioContext {
792
- public world: World;
793
- public someValue = '';
794
- private id: string = '';
795
-
796
- constructor(worldObj: World) {
797
- this.world = worldObj;
798
- }
799
- public initialize({ pickle, gherkinDocument }: StartTestCaseInfo): void {
800
- this.id = this.makeid(5);
801
- console.log(`Sync init: ${this.id}`);
802
- console.log(`Start Test Case: ${this.getFeatureAndScenario(gherkinDocument.uri!, pickle.name)}`);
803
- }
804
- public dispose({ pickle, gherkinDocument }: EndTestCaseInfo): void {
805
- console.log(`Sync dispose: ${this.id}`);
806
- console.log(`End Test Case: ${this.getFeatureAndScenario(gherkinDocument.uri!, pickle.name)}`);
807
- }
808
- private getFeatureAndScenario(path: string, scenario: string): string | undefined {
809
- ...
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
+ ...
810
847
  return `${fileName}: ${scenario.split(' ').join('-')}`;
811
- }
812
- private makeid(length: number) {
813
- ...
814
- return result;
815
- }
848
+ }
849
+ private makeid(length: number) {
850
+ ...
851
+ return result;
852
+ }
816
853
  }
817
854
  ```
818
855
 
@@ -823,39 +860,39 @@ import { World } from '@cucumber/cucumber';
823
860
  import { EndTestCaseInfo, StartTestCaseInfo } from '@lynxwall/cucumber-tsflow';
824
861
 
825
862
  export class ScenarioContext {
826
- public world: World;
827
- public someValue = '';
828
- private id: string = '';
829
-
830
- constructor(worldObj: World) {
831
- this.world = worldObj;
832
- }
833
- public async initialize({ pickle, gherkinDocument }: StartTestCaseInfo): Promise<void> {
834
- this.id = this.makeid(5);
835
- await this.logTest(`Async init: ${this.id}`);
836
- await this.logTest(`Start Test Case: ${this.getFeatureAndScenario(gherkinDocument.uri!, pickle.name)}`);
837
- }
838
- public async dispose({ pickle, gherkinDocument }: EndTestCaseInfo): Promise<void> {
839
- await this.logTest(`Async dispose: ${this.id}`);
840
- await this.logTest(`End Test Case: ${this.getFeatureAndScenario(gherkinDocument.uri!, pickle.name)}`);
841
- }
842
- async logTest(text: string): Promise<void> {
843
- await Promise.resolve(console.log(text));
844
- }
845
- private getFeatureAndScenario(path: string, scenario: string): string | undefined {
846
- ...
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
+ ...
847
884
  return `${fileName}: ${scenario.split(' ').join('-')}`;
848
- }
885
+ }
849
886
  private makeid(length: number) {
850
- ...
851
- return result;
852
- }
887
+ ...
888
+ return result;
889
+ }
853
890
  }
854
891
  ```
855
892
 
856
893
  **Initialize Binding in Step class:**
857
894
 
858
- - Update the `@binding()` decorator to indicate the types of context objects that are required by the 'binding' class. You can include up to nine separate _Context_ objects.
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.
859
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.
860
897
 
861
898
  **Single Context class example:**
@@ -867,18 +904,18 @@ import { expect } from 'chai';
867
904
 
868
905
  @binding([ScenarioContext])
869
906
  export default class InjectionTestSteps1 {
870
- constructor(private context: ScenarioContext) {}
871
-
872
- @given('The Workspace is available and valid')
873
- theWorkspaceIsAvailableAndValid() {
874
- expect(this.context).not.to.be.undefined;
875
- expect(this.context.world).not.to.be.undefined;
876
- }
877
-
878
- @when('I change the workspace in one step definition class')
879
- whenIChangeTheWorkspaceInOneStep() {
880
- this.context.someValue = 'value changed';
881
- }
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
+ }
882
919
  }
883
920
  ```
884
921
 
@@ -892,24 +929,24 @@ import { expect } from 'chai';
892
929
 
893
930
  @binding([ScenarioContext, SyncContext])
894
931
  export default class InjectionTestSteps1 {
895
- constructor(
896
- private context: ScenarioContext,
897
- private syncContext: SyncContext
898
- ) {}
899
-
900
- @given('The Workspace is available and valid')
901
- theWorkspaceIsAvailableAndValid() {
902
- expect(this.context).not.to.be.undefined;
903
- expect(this.context.world).not.to.be.undefined;
904
-
905
- expect(this.syncContext).not.to.be.undefined;
906
- expect(this.syncContext.world).not.to.be.undefined;
907
- }
908
-
909
- @when('I change the workspace in one step definition class')
910
- whenIChangeTheWorkspaceInOneStep() {
911
- this.context.someValue = 'value changed';
912
- }
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
+ }
913
950
  }
914
951
  ```
915
952
 
@@ -927,16 +964,16 @@ Starting with version **6.4.0** the Cucumber World object is now passed into a _
927
964
  import { World } from '@cucumber/cucumber';
928
965
 
929
966
  export class ScenarioContext {
930
- public world: World;
931
- public someValue = '';
967
+ public world: World;
968
+ public someValue = '';
932
969
 
933
- constructor(worldObj: World) {
934
- this.world = worldObj;
935
- }
970
+ constructor(worldObj: World) {
971
+ this.world = worldObj;
972
+ }
936
973
 
937
- public dispose(): void {
938
- this.someValue = '';
939
- }
974
+ public dispose(): void {
975
+ this.someValue = '';
976
+ }
940
977
  }
941
978
  ```
942
979
 
@@ -958,8 +995,8 @@ With this approach, you would define a world property on simple _Context_ class
958
995
  import { World } from '@cucumber/cucumber';
959
996
 
960
997
  export class ScenarioContext {
961
- public world!: World;
962
- public someValue = '';
998
+ public world!: World;
999
+ public someValue = '';
963
1000
  }
964
1001
  ```
965
1002
 
@@ -974,14 +1011,14 @@ import { World } from '@cucumber/cucumber';
974
1011
 
975
1012
  @binding([ScenarioContext])
976
1013
  export default class WorldContext {
977
- _worldObj?: World;
1014
+ _worldObj?: World;
978
1015
 
979
- constructor(private context: ScenarioContext) {}
1016
+ constructor(private context: ScenarioContext) {}
980
1017
 
981
- @before()
982
- beforeScenario() {
983
- this.context.world = this._worldObj as World;
984
- }
1018
+ @before()
1019
+ beforeScenario() {
1020
+ this.context.world = this._worldObj as World;
1021
+ }
985
1022
  }
986
1023
  ```
987
1024