@lynxwall/cucumber-tsflow 7.6.0 → 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 +266 -229
- 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 +23 -31
- package/lib/api/load-configuration.js.map +1 -1
- package/lib/api/load-support.d.ts +11 -2
- package/lib/api/load-support.js +31 -6
- 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/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 -7
- /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,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
|
-
|
|
146
|
-
|
|
147
|
-
|
|
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
|
-
|
|
170
|
-
|
|
171
|
-
|
|
205
|
+
@given('I enter {int} and {int}')
|
|
206
|
+
iEnterintAndint(int: number, int2: number): any {
|
|
207
|
+
this.computedResult = int + int2;
|
|
172
208
|
}
|
|
173
209
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
210
|
+
@when('checking the results')
|
|
211
|
+
checkingTheResults(): any {
|
|
212
|
+
expect(this.computedResult).to.be.greaterThan(0);
|
|
213
|
+
}
|
|
178
214
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
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.
|
|
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
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
```
|
|
230
|
-
|
|
231
|
-
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:
|
|
232
268
|
|
|
233
269
|
```typescript
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
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
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
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
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
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
|
-
|
|
301
|
-
|
|
302
|
-
|
|
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
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
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
|
-
|
|
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.
|
|
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`
|
|
422
|
-
| `debugFile` | `string`
|
|
423
|
-
| `enableVueStyle` | `boolean`
|
|
424
|
-
| `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 |
|
|
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.
|
|
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
|
-
|
|
463
|
-
|
|
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
|
-
|
|
475
|
-
|
|
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
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
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
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
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
|
-
|
|
578
|
-
|
|
579
|
-
|
|
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
|
-
|
|
624
|
+
this.boolValue = boolean;
|
|
588
625
|
}
|
|
589
626
|
|
|
590
627
|
@when('checking the boolean value')
|
|
591
628
|
checkingTheBooleanValue(): any {
|
|
592
|
-
|
|
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
|
-
|
|
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.
|
|
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.
|
|
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
|
-
|
|
731
|
-
|
|
732
|
-
|
|
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
|
-
|
|
745
|
-
|
|
746
|
-
|
|
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
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
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
|
-
|
|
813
|
-
|
|
814
|
-
|
|
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
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
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
|
-
|
|
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.
|
|
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
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
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
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
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
|
-
|
|
931
|
-
|
|
967
|
+
public world: World;
|
|
968
|
+
public someValue = '';
|
|
932
969
|
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
970
|
+
constructor(worldObj: World) {
|
|
971
|
+
this.world = worldObj;
|
|
972
|
+
}
|
|
936
973
|
|
|
937
|
-
|
|
938
|
-
|
|
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
|
-
|
|
962
|
-
|
|
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
|
-
|
|
1014
|
+
_worldObj?: World;
|
|
978
1015
|
|
|
979
|
-
|
|
1016
|
+
constructor(private context: ScenarioContext) {}
|
|
980
1017
|
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
1018
|
+
@before()
|
|
1019
|
+
beforeScenario() {
|
|
1020
|
+
this.context.world = this._worldObj as World;
|
|
1021
|
+
}
|
|
985
1022
|
}
|
|
986
1023
|
```
|
|
987
1024
|
|