@gnuechtel/nx-cucumber 1.4.1 → 2.0.0-13776525992

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 (40) hide show
  1. package/README.md +264 -331
  2. package/executors.json +1 -7
  3. package/package.json +8 -7
  4. package/src/adapters/contract.d.ts +51 -0
  5. package/src/adapters/contract.js +13 -0
  6. package/src/adapters/contract.js.map +1 -0
  7. package/src/adapters/registry.d.ts +16 -0
  8. package/src/adapters/registry.js +46 -0
  9. package/src/adapters/registry.js.map +1 -0
  10. package/src/adapters/validation.d.ts +5 -0
  11. package/src/adapters/validation.js +79 -0
  12. package/src/adapters/validation.js.map +1 -0
  13. package/src/core/cucumber-report-html.d.ts +11 -5
  14. package/src/core/cucumber-report-html.js +15 -53
  15. package/src/core/cucumber-report-html.js.map +1 -1
  16. package/src/generators/project/files/all/cucumber.js.template +21 -0
  17. package/src/generators/project/project.js +12 -72
  18. package/src/generators/project/project.js.map +1 -1
  19. package/src/generators/project/schema.d.ts +1 -5
  20. package/src/generators/project/schema.json +6 -46
  21. package/src/index.d.ts +7 -0
  22. package/src/index.js +8 -0
  23. package/src/index.js.map +1 -1
  24. package/src/playwright/playwright-hooks.js +4 -0
  25. package/src/playwright/playwright-hooks.js.map +1 -1
  26. package/src/plugin/create-nodes.d.ts +20 -0
  27. package/src/plugin/create-nodes.js +174 -0
  28. package/src/plugin/create-nodes.js.map +1 -0
  29. package/src/core/debug-message-handler.d.ts +0 -12
  30. package/src/core/debug-message-handler.js +0 -120
  31. package/src/core/debug-message-handler.js.map +0 -1
  32. package/src/core/ts-node-nx-cucumber-alias.d.ts +0 -10
  33. package/src/core/ts-node-nx-cucumber-alias.js +0 -38
  34. package/src/core/ts-node-nx-cucumber-alias.js.map +0 -1
  35. package/src/executors/cucumber-api/cucumber-api.d.ts +0 -15
  36. package/src/executors/cucumber-api/cucumber-api.js +0 -331
  37. package/src/executors/cucumber-api/cucumber-api.js.map +0 -1
  38. package/src/executors/cucumber-api/schema.d.ts +0 -10
  39. package/src/executors/cucumber-api/schema.json +0 -211
  40. package/src/generators/project/files/coverage/.nycrc.json.template +0 -9
package/README.md CHANGED
@@ -5,8 +5,8 @@ Plugin to use Cucumber within Nx workspaces
5
5
  <!-- TOC -->
6
6
 
7
7
  - [Introduction](#introduction)
8
+ - [What changed in 2.x](#what-changed-in-2x)
8
9
  - [Prerequisites](#prerequisites)
9
- - [Cucumber JavaScript API](#cucumber-javascript-api)
10
10
  - [Quick start](#quick-start)
11
11
  - [Install Nx](#install-nx)
12
12
  - [Install dependencies](#install-dependencies)
@@ -14,17 +14,19 @@ Plugin to use Cucumber within Nx workspaces
14
14
  - [Basic project generator usage](#basic-project-generator-usage)
15
15
  - [Additional project generator options](#additional-project-generator-options)
16
16
  - [Execute Cucumber projects](#execute-cucumber-projects)
17
- - [Basic executor usage](#basic-executor-usage)
18
- - [Additional executor options](#additional-executor-options)
19
- - [Custom Cucumber configuration](#custom-cucumber-configuration)
20
- - [Custom Playwright configuration](#custom-playwright-configuration)
21
- - [Multiple dev server targets](#multiple-dev-server-targets)
22
- - [Skip dev server](#skip-dev-server)
17
+ - [Inferred tasks](#inferred-tasks)
18
+ - [Plugin registration](#plugin-registration)
19
+ - [Cucumber configuration](#cucumber-configuration)
20
+ - [World parameters](#world-parameters)
23
21
  - [Enable videos](#enable-videos)
24
22
  - [Change screenshot options](#change-screenshot-options)
25
23
  - [Custom Cucumber world](#custom-cucumber-world)
26
24
  - [Playwright world](#playwright-world)
27
25
  - [Core world](#core-world)
26
+ - [Reports](#reports)
27
+ - [Built-in HTML report](#built-in-html-report)
28
+ - [Beautiful HTML report](#beautiful-html-report)
29
+ - [JSON and XML reports](#json-and-xml-reports)
28
30
  - [Code coverage](#code-coverage)
29
31
  - [Example projects](#example-projects)
30
32
  - [Main examples](#main-examples)
@@ -44,25 +46,27 @@ Plugin to use Cucumber within Nx workspaces
44
46
  - [Logging](#logging)
45
47
  - [Contribution](#contribution)
46
48
  - [Troubleshooting](#troubleshooting)
47
- - [Known limitations in 1.x](#known-limitations-in-1x)
48
- - [Dev server does not shutdown properly](#dev-server-does-not-shutdown-properly)
49
- - [Wrong line numbers when using Playwright inspector](#wrong-line-numbers-when-using-playwright-inspector)
50
- - [A tag is not found](#a-tag-is-not-found)
51
- - [Some Cucumber product feature does not work with nx-cucumber](#some-cucumber-product-feature-does-not-work-with-nx-cucumber)
49
+ - [Migration from 1.x](#migration-from-1x)
52
50
 
53
51
  <!-- /TOC -->
54
52
 
55
53
  ## Introduction
56
54
 
57
- This is nx-cucumber, a plugin for Nx which integrates Cucumber to create the best possible connection between these two essential tools for quality software. The main purpose is to provide generators and executors for multiple Cucumber implementations within Nx workspaces. We have just started with [Cucumber for JavaScript](https://github.com/cucumber/cucumber-js) plus optional [Playwright](https://playwright.dev/docs/library) support and there is already more on the [roadmap](https://gitlab.com/gnuechtel/open-source/-/issues/13).
55
+ This is nx-cucumber, a plugin for Nx which integrates Cucumber to create the best possible connection between these two essential tools for quality software. The plugin provides generators and inferred tasks for [Cucumber for JavaScript](https://github.com/cucumber/cucumber-js) within Nx workspaces, with optional [Playwright](https://playwright.dev/docs/library) support.
58
56
 
59
- ## Prerequisites
57
+ ## What changed in 2.x
58
+
59
+ Version 2.x is a deliberate breaking release that simplifies the plugin architecture:
60
60
 
61
- The only prerequisite for this software is [Node.js](https://nodejs.org/). In our [continuous delivery pipeline](#continuous-delivery-pipeline), we test against the latest Node.js LTS version. Other versions are expected to work, but there is no guarantee. Since this is an [Nx](https://nx.dev/) plugin for [Cucumber](https://github.com/cucumber/cucumber-js), these tools are required too. To provide the best experience for browser automation, the [Playwright library](https://playwright.dev/docs/library) is supported out-of-the-box, but is completely optional and must be enabled explicitly. The npm package supports Nx versions `>=20 <23`. CI coverage focuses on `latest` and `next` Nx versions with the latest Cucumber and Playwright dependencies.
61
+ - **Inferred tasks replace explicit executors.** The `@gnuechtel/nx-cucumber:cucumber-api` executor has been removed. Projects are discovered via `cucumber.js` config files and targets are inferred automatically using [Nx Project Crystal](https://nx.dev/concepts/inferred-tasks).
62
+ - **Framework-native execution.** Tests run via `npx cucumber-js` directly instead of an in-process Cucumber API. This unlocks full Cucumber CLI capabilities without plugin-specific wrappers.
63
+ - **Less configuration.** Generated projects include a `cucumber.js` config file and a minimal `project.json`. All Cucumber and Playwright options are configured through standard Cucumber and Playwright mechanisms.
64
+ - **Nx >=22 only.** The 2.x line requires Nx 22 or later.
65
+ - **Adapter-oriented architecture.** The plugin uses an adapter contract to support multiple executable-spec frameworks. See [docs/adapters/contract.md](https://gitlab.com/gnuechtel/open-source/-/blob/main/docs/adapters/contract.md) for details.
62
66
 
63
- ## Cucumber JavaScript API
67
+ ## Prerequisites
64
68
 
65
- This plugin uses the [Cucumber JavaScript API](https://github.com/cucumber/cucumber-js/blob/main/docs/javascript_api.md). That means, Cucumber is used in-process and _not_ on the command-line. By using this great piece of software, we achieve optimal performance, stability and testing for executing Cucumber scenarios with Nx.
69
+ The only prerequisite for this software is [Node.js](https://nodejs.org/). In our [continuous delivery pipeline](#continuous-delivery-pipeline), we test against the latest Node.js LTS version. Other versions are expected to work, but there is no guarantee. Since this is an [Nx](https://nx.dev/) plugin for [Cucumber](https://github.com/cucumber/cucumber-js), these tools are required too. To provide the best experience for browser automation, the [Playwright library](https://playwright.dev/docs/library) is supported out-of-the-box, but is completely optional and must be enabled explicitly. The npm package supports Nx versions `>=22`. CI coverage focuses on `latest` and `next` Nx versions with the latest Cucumber and Playwright dependencies.
66
70
 
67
71
  ## Quick start
68
72
 
@@ -83,14 +87,14 @@ npm i -D @cucumber/cucumber @playwright/test
83
87
  # install this plugin
84
88
  npm i -D @gnuechtel/nx-cucumber
85
89
 
90
+ # register the plugin in nx.json (enables inferred tasks)
91
+ # add "@gnuechtel/nx-cucumber" to the "plugins" array in nx.json
92
+
86
93
  # create a cucumber project for gnu-app
87
94
  npx nx g @gnuechtel/nx-cucumber:project --project=gnu-app --test-runner=playwright
88
95
 
89
- # run cucumber scenarios (implicitly starts gnu-app)
96
+ # run cucumber scenarios (uses inferred e2e target)
90
97
  npx nx e2e gnu-app-e2e
91
-
92
- # display generated cucumber HTML report
93
- open ./dist/cucumber-js/apps/gnu-app-e2e/reports/html/cucumber-test-report.html
94
98
  ```
95
99
 
96
100
  ## Install Nx
@@ -100,7 +104,7 @@ There are two feasible options to [install Nx](https://nx.dev/getting-started/in
100
104
  - either via `npx create-nx-workspace@latest` to setup a fresh Nx repo or
101
105
  - via `npx nx@latest init` to convert an existing Node.js project into an Nx workspace.
102
106
 
103
- It is never recommended to install all those Nx [dependencies](https://www.npmjs.com/org/nx) manually.
107
+ It is never recommended to install all those Nx [dependencies](https://www.npmjs.com/org/nx) manually.
104
108
  It would just cause too much unnecessary work.
105
109
 
106
110
  ## Install dependencies
@@ -115,12 +119,11 @@ If we want to use the Playwright test runner, we should also install one of the
115
119
  - [playwright](https://www.npmjs.com/package/playwright) (Playwright library) _or_
116
120
  - [@playwright/test](https://www.npmjs.com/package/@playwright/test) (Playwright Test framework)
117
121
 
118
- Since Cucumber is our executor, we are using the [Playwright library](https://playwright.dev/docs/library), not the complete _Playwright Test_ framework. However, Playwright Test also provides very useful [expect](https://playwright.dev/docs/test-assertions) extensions which are usable standalone with the library. So we recommend using `@playwright/test`, which also includes the `playwright` dependency.
122
+ We recommend using `@playwright/test`, which also includes the `playwright` dependency and provides very useful [expect](https://playwright.dev/docs/test-assertions) extensions.
119
123
 
120
124
  Optional dependencies:
121
125
 
122
- - [cucumber-html-reporter](https://www.npmjs.com/package/cucumber-html-reporter) is only required when report option `html-beautiful` is enabled.
123
- - [nyc](https://www.npmjs.com/package/nyc) is only required when code coverage instrumentation is enabled.
126
+ - [cucumber-html-reporter](https://www.npmjs.com/package/cucumber-html-reporter) is required for the [beautiful HTML report](#beautiful-html-report).
124
127
 
125
128
  ## Generate Cucumber projects
126
129
 
@@ -139,126 +142,136 @@ npx nx g @gnuechtel/nx-cucumber:project --project=my-project --test-runner=playw
139
142
 
140
143
  # playwright test runner with custom e2e project name (generates an app 'my-project-foo-e2e')
141
144
  npx nx g @gnuechtel/nx-cucumber:project --project=my-project --name my-project-foo-e2e --test-runner=playwright
142
-
143
- # playwright test runner with custom base URL
144
- npx nx g @gnuechtel/nx-cucumber:project --project=my-project --test-runner=playwright --base-url=http://localhost:8765
145
145
  ```
146
146
 
147
+ The generator creates:
148
+
149
+ - A `cucumber.js` config file with paths, formatters, and TypeScript support
150
+ - A minimal `project.json` with lint target and implicit dependencies
151
+ - Feature files, step definitions, and TypeScript configuration
152
+
153
+ The `e2e` target is **not** defined in `project.json`. It is inferred by the plugin from the `cucumber.js` config file.
154
+
147
155
  ### Additional project generator options
148
156
 
149
157
  All possible project generator options may be passed as command-line parameters and are stored in the related [schema file](https://gitlab.com/gnuechtel/open-source/-/blob/main/libs/nx-cucumber/src/generators/project/schema.json). They can also be displayed on the command-line with the following command: `npx nx g @gnuechtel/nx-cucumber:project --help`.
150
158
 
151
159
  ## Execute Cucumber projects
152
160
 
153
- ### Basic executor usage
161
+ ### Inferred tasks
154
162
 
155
- After the Cucumber project was generated, we are able to execute it with nx:
163
+ In 2.x, the `e2e` target is automatically inferred when the plugin detects a `cucumber.js` config file in a project directory. No executor configuration is needed:
156
164
 
157
165
  ```bash
158
166
  npx nx e2e my-project-e2e
159
167
  ```
160
168
 
161
- The project generator created a `project.json` with a default configuration which works out-of-the-box for hello-world projects as described in the quick start.
162
-
163
- ### Additional executor options
164
-
165
- To change the default configuration, we manually edit the `project.json` of the Cucumber project. All available options are stored in the [executor schema file](https://gitlab.com/gnuechtel/open-source/-/blob/main/libs/nx-cucumber/src/executors/cucumber-api/schema.json). Additionally, a `cucumber.js` file can be stored beside the `project.json` to tweak Cucumber configuration by custom code (see next section).
166
-
167
- ### Custom Cucumber configuration
168
-
169
- Some Cucumber properties are accessible via `project.json`.
170
- But not all properties are supported by nx-cucumber and sometimes, we even want to customize the supported ones.
171
-
172
- For example, we want to set tags based on environment variables.
173
- To achieve such a custom Cucumber configuration:
174
-
175
- 1. We remove the related property from `project.json`: ~~"tags": "not @ignore"~~.
176
-
177
- 2. We create a `cucumber.js` file next to `project.json`. For example:
178
-
179
- ```javascript
180
- const tagsFilter =
181
- process.env['CI_STAGE'] !== 'qa' // Some custom logic based on an example stage variable
182
- ? 'and not @qa-stage-only' // Exclude all 'qa-stage-only' scenarios
183
- : 'and (@qa-stage or @qa-stage-only)'; // Only include 'qa-stage' or 'qa-stage-only' scenarios
184
-
185
- module.exports = {
186
- default: { tags: `not @ignore ${tagsFilter}` }, // Combine default filter with stage filter
187
- };
188
- ```
189
-
190
- In this example, we used a Cucumber configuration file in CommonJS format, but [other formats](https://github.com/cucumber/cucumber-js/blob/main/docs/configuration.md#files) are supported too. Also we would be able to set all advanced Cucumber [options](https://github.com/cucumber/cucumber-js/blob/main/docs/configuration.md#options) in the `cucumber.js` file which are not yet supported in `project.json`.
191
-
192
- ### Custom Playwright configuration
193
-
194
- Custom Playwright options which are passed to a [new browser context](https://playwright.dev/docs/api/class-browser#browser-new-context) may be customized with nx-cucumber. By default, the project generator already creates custom Playwright options in `project.json`:
195
-
196
- ```json
197
- "additionalPlaywrightConfiguration": { "acceptDownloads": true }
198
- ```
199
-
200
- By adding more properties to `additionalPlaywrightConfiguration` we are able to customize the Playwright behavior.
169
+ ### Plugin registration
201
170
 
202
- By default, Playwright scenarios run in Chromium. To execute them in another Playwright browser, set `browser` in `project.json`:
171
+ To enable inferred tasks, register the plugin in `nx.json`:
203
172
 
204
173
  ```json
205
- "browser": "firefox"
174
+ {
175
+ "plugins": ["@gnuechtel/nx-cucumber"]
176
+ }
206
177
  ```
207
178
 
208
- Possible values are `chromium`, `firefox`, and `webkit`.
209
-
210
- ### Multiple dev server targets
211
-
212
- By default, the project generator creates a dev server target and a base URL in `project.json`:
179
+ Target names can be customized:
213
180
 
214
181
  ```json
215
182
  {
216
- "devServerTarget": "my-project:serve",
217
- "baseUrl": "http://localhost:4200"
183
+ "plugins": [
184
+ {
185
+ "plugin": "@gnuechtel/nx-cucumber",
186
+ "options": {
187
+ "e2eTargetName": "integration"
188
+ }
189
+ }
190
+ ]
218
191
  }
219
192
  ```
220
193
 
221
- This will start a dev server with the defined nx target and waits until the `baseUrl` is ready with HTTP status code 200.
222
- After the execution of the Cucumber scenarios, the dev server process will be terminated.
223
-
224
- For some projects it is also util to start more than one dev server, so nx-cucumber supports this:
194
+ ### Cucumber configuration
225
195
 
226
- ```json
227
- "devServerTargets": ["some-dependent-service:serve", "my-project:serve"]
228
- ```
196
+ All Cucumber options are configured in the `cucumber.js` file. The generator creates a default configuration. For example, to customize tags based on environment variables:
229
197
 
230
- Here, two dev server targets will be started before Cucumber execution and terminated afterwards in reverse order.
231
- To wait for additional URLs there is also another useful configuration:
198
+ ```javascript
199
+ const tagsFilter =
200
+ process.env['CI_STAGE'] !== 'qa'
201
+ ? 'and not @qa-stage-only'
202
+ : 'and (@qa-stage or @qa-stage-only)';
232
203
 
233
- ```json
234
- "additionalDevServerUrls": ["http://localhost:9999/status"]
204
+ module.exports = {
205
+ default: {
206
+ tags: `not @ignore ${tagsFilter}`,
207
+ },
208
+ };
235
209
  ```
236
210
 
237
- Here we additionally wait for the Cucumber execution until the URL `http://localhost:9999/status` is ready (also with HTTP status code 200).
211
+ All advanced Cucumber [options](https://github.com/cucumber/cucumber-js/blob/main/docs/configuration.md#options) can be set in the `cucumber.js` file.
238
212
 
239
- ### Skip dev server
213
+ ### World parameters
240
214
 
241
- Sometimes it is not desired to use the dev server facilities of this plugin. For example, the server was started by another script and we just want to execute the Cucumber scenarios. For those use cases, we can skip the dev server in `project.json`:
215
+ Playwright-related options that were previously set in `project.json` executor options are now configured via `worldParameters` in `cucumber.js`:
242
216
 
243
- ```json
244
- "skipServe": true
217
+ ```javascript
218
+ module.exports = {
219
+ default: {
220
+ // ... paths, require, etc.
221
+ worldParameters: {
222
+ headed: false,
223
+ browser: 'chromium',
224
+ disableVideoFiles: true,
225
+ disableVideoAttachments: true,
226
+ disableScreenshotFiles: false,
227
+ disableScreenshotAttachments: false,
228
+ disableJavaScript: false,
229
+ disableCoverage: false,
230
+ },
231
+ },
232
+ };
245
233
  ```
246
234
 
247
235
  ### Enable videos
248
236
 
249
- By default, the project generator disables video files and attachments. To enable video files, we remove the `disableVideoFiles` option from `project.json` or set it to `false`. Removing that option, would store video files with scenario names in the Cucumber output directory (`dist/cucumber-js/application-path/videos` by default). If we also want to include the video files in Cucumber reports as attachments, there is a `disableVideoAttachments` option in `project.json`. Again, we can remove it or set to `false`.
237
+ By default, video files and attachments are disabled. To enable them, set the world parameters in `cucumber.js`:
238
+
239
+ ```javascript
240
+ module.exports = {
241
+ default: {
242
+ // ... paths, require, etc.
243
+ worldParameters: {
244
+ disableVideoFiles: false,
245
+ disableVideoAttachments: false,
246
+ },
247
+ },
248
+ };
249
+ ```
250
250
 
251
251
  ### Change screenshot options
252
252
 
253
- Also by default, screenshots are attached to every scenario which runs with Playwright. We will see them in the Cucumber reports for successful and erroneous scenarios. On the other hand, screenshot _files_ will be created only in case of error. They will also be stored in the Cucumber output directory (`dist/cucumber-js/application-path/screenshots` by default). To change the default behavior and create screenshot files for successful scenario too, we set `enableSuccessfulScreenshotFiles` to `true`. But we can also change the screenshot options in the other direction by setting `disableScreenshotFiles` and `disableScreenshotAttachments` to `true` to disable screenshots completely.
253
+ By default, screenshots are attached to every Playwright scenario. Screenshot _files_ are created only on error. To change this:
254
+
255
+ ```javascript
256
+ module.exports = {
257
+ default: {
258
+ // ... paths, require, etc.
259
+ worldParameters: {
260
+ enableSuccessfulScreenshotFiles: true, // also create files for passing scenarios
261
+ // disableScreenshotFiles: true, // disable screenshot files entirely
262
+ // disableScreenshotAttachments: true, // disable screenshot attachments in reports
263
+ },
264
+ },
265
+ };
266
+ ```
254
267
 
255
268
  ### Custom Cucumber world
256
269
 
257
- For the Playwright and the core test runner, an additional custom [world](https://github.com/cucumber/cucumber-js/blob/main/docs/support_files/world.md) may be created to extend the default behavior. To achieve this, we add the `--custom-world` parameter to the project generator. Currently, the custom world for the core test runner is always generated, even if the parameter is omitted. We are [aware](https://gitlab.com/gnuechtel/open-source/-/issues/30) of this and will change it in the future. An example path for a generated custom world would be `apps/my-project-e2e/src/shared/my-project-world.ts`. The name is the same for both test runners, but there are differences in the implementation.
270
+ For the Playwright and the core test runner, an additional custom [world](https://github.com/cucumber/cucumber-js/blob/main/docs/support_files/world.md) may be created to extend the default behavior. To achieve this, we add the `--custom-world` parameter to the project generator.
258
271
 
259
272
  #### Playwright world
260
273
 
261
- A custom Playwright world must be derived from the `PlaywrightWorld` class of nx-cucumber since a lot of default behavior for the Playwright test runner is implemented there. In theory, it is possible to write an own Playwright world from scratch, but it is absolutely not recommended. To enable a custom Playwright world, it is also required, to set `customWorld` to `true` in `project.json` and to register that world via `setWorldConstructor`. The project generator will create this required code for us.
274
+ A custom Playwright world must be derived from the `PlaywrightWorld` class of nx-cucumber since a lot of default behavior for the Playwright test runner is implemented there. To enable a custom Playwright world, it is also required to register that world via `setWorldConstructor`. The project generator will create this required code for us.
262
275
 
263
276
  An example Playwright world, which extends the built-in clean-up method looks like this:
264
277
 
@@ -302,9 +315,48 @@ export class CustomWorld extends World {
302
315
  }
303
316
  ```
304
317
 
318
+ ## Reports
319
+
320
+ ### Built-in HTML report
321
+
322
+ The generator configures the Cucumber built-in `html` formatter by default. The report is generated at `dist/e2e/<project-root>/reports/html/cucumber-test-report-builtin.html`.
323
+
324
+ ### Beautiful HTML report
325
+
326
+ For a richer HTML report with metadata and screenshots, install `cucumber-html-reporter` and use the exported `createBeautifulHtmlReport` utility:
327
+
328
+ ```bash
329
+ npm i -D cucumber-html-reporter
330
+ ```
331
+
332
+ The utility generates a beautiful HTML report from the Cucumber JSON output:
333
+
334
+ ```typescript
335
+ import { createBeautifulHtmlReport } from '@gnuechtel/nx-cucumber';
336
+
337
+ createBeautifulHtmlReport({
338
+ jsonDir: 'dist/e2e/apps/my-project-e2e/reports/cucumber-json',
339
+ outputDir: 'dist/e2e/apps/my-project-e2e/reports/html',
340
+ reportTitle: 'My Project E2E Tests',
341
+ });
342
+ ```
343
+
344
+ ### JSON and XML reports
345
+
346
+ The generator configures `json` and `junit` formatters by default:
347
+
348
+ - JSON: `dist/e2e/<project-root>/reports/cucumber-json/cucumber-test-report.json`
349
+ - XML (JUnit): `dist/e2e/<project-root>/reports/test-results/cucumber-test-report.xml`
350
+
305
351
  ## Code coverage
306
352
 
307
- Code coverage is an important part for all kinds of testing, so nx-cucumber supports it for the Playwright and core test runner. All [example projects](#example-projects) are configured for code coverage. Playwright code coverage will be enabled by proper application configuration as done in the [example react project](https://gitlab.com/gnuechtel/open-source/-/commit/9b74724b). Core code coverage will be enabled with the `--instrument-test-runner` project generator parameter as done in the [example Node.js project](https://gitlab.com/gnuechtel/open-source/-/commit/cdbd6a00).
353
+ Code coverage is supported for the Playwright test runner through the `PlaywrightWorld` hooks, which collect Istanbul coverage automatically. To enable code coverage for a Playwright project:
354
+
355
+ 1. Install the Vite Istanbul plugin: `npm i -D vite-plugin-istanbul`
356
+ 2. Configure the plugin in the application's `vite.config.ts`
357
+ 3. The `PlaywrightWorld` hooks will automatically collect and report coverage
358
+
359
+ All [example projects](#example-projects) demonstrate code coverage configuration.
308
360
 
309
361
  ## Example projects
310
362
 
@@ -312,43 +364,19 @@ Code coverage is an important part for all kinds of testing, so nx-cucumber supp
312
364
 
313
365
  This repository contains [example projects](https://gitlab.com/gnuechtel/open-source/-/tree/main/apps/example) that can be used directly to see nx-cucumber in action.
314
366
 
315
- In the following table, we will see the following information:
316
-
317
- - the examples that are split into two projects in each case: one main application project and one cucumber project,
318
- - the Nx commands to create these projects, where the cucumber projects are generated with nx-cucumber,
319
- - the configured code coverage for each project,
320
- - the execution of the cucumber specifications with nx-cucumber (via `nx e2e`),
321
- - the Cucumber and coverage reports used.
322
-
323
- | | example react application and cucumber project | example Node.js app and cucumber project |
324
- | ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
325
- | **Execute cucumber project** | `npx nx e2e example-react-app-e2e` | `npx nx e2e example-node-app-e2e` |
326
- | **Source cucumber project** | [apps/example/react-app-e2e](https://gitlab.com/gnuechtel/open-source/-/tree/main/apps/example/react-app-e2e) | [apps/example/node-app-e2e](https://gitlab.com/gnuechtel/open-source/-/tree/main/apps/example/node-app-e2e) |
327
- | **Cucumber project file** | [react-app-e2e/project.json](https://gitlab.com/gnuechtel/open-source/-/blob/main/apps/example/react-app-e2e/project.json) | [node-app-e2e/project.json](https://gitlab.com/gnuechtel/open-source/-/tree/main/apps/example/node-app-e2e/project.json) |
328
- | **Source main project** | [apps/example/react-app](https://gitlab.com/gnuechtel/open-source/-/tree/main/apps/example/react-app) | [apps/example/node-app](https://gitlab.com/gnuechtel/open-source/-/tree/main/apps/example/node-app) |
329
- | **Create main project** | `npx nx g @nx/react:application example/react-app --bundler=vite --style=css --e2e-test-runner=none --routing` | `npx nx g @gnuechtel/nx-cucumber:project --project=example-node-app --directory=example/node-app-e2e --instrument-test-runner` |
330
- | **Create cucumber project** | `npx nx g @gnuechtel/nx-cucumber:project --project=example-react-app --directory=example/react-app-e2e --test-runner=playwright` | `npx nx g @gnuechtel/nx-cucumber:project --project=example-node-app --directory=example/node-app-e2e --instrument-test-runner` |
331
- | **Code coverage** | [configured](https://gitlab.com/gnuechtel/open-source/-/commit/9b74724b) with the vite istanbul plugin | `--instrument-test-runner` parameter and [optimizations](https://gitlab.com/gnuechtel/open-source/-/commit/cdbd6a00) |
332
- | **Cucumber report** | [cucumber-test-report.html](https://gitlab.com/gnuechtel/open-source/-/jobs/artifacts/main/file/dist/cucumber-js/apps/example/react-app-e2e/reports/html/cucumber-test-report.html?job=e2e-examples:linux) | [cucumber-test-report.html](https://gitlab.com/gnuechtel/open-source/-/jobs/artifacts/main/file/dist/cucumber-js/apps/example/node-app-e2e/reports/html/cucumber-test-report.html?job=e2e-examples:linux) |
333
- | **Coverage report** | [lcov-report/index.html](https://gitlab.com/gnuechtel/open-source/-/jobs/artifacts/main/file/dist/coverage/apps/example/react-app-e2e/lcov-report/index.html?job=e2e-examples:linux) | [lcov-report/index.html](https://gitlab.com/gnuechtel/open-source/-/jobs/artifacts/main/file/dist/coverage/apps/example/node-app-e2e/lcov-report/index.html?job=e2e-examples:linux) |
367
+ | | example react application and cucumber project | example Node.js app and cucumber project |
368
+ | ---------------------------- | ------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- |
369
+ | **Execute cucumber project** | `npx nx e2e example-react-app-e2e` | `npx nx e2e example-node-app-e2e` |
370
+ | **Source cucumber project** | [apps/example/react-app-e2e](https://gitlab.com/gnuechtel/open-source/-/tree/main/apps/example/react-app-e2e) | [apps/example/node-app-e2e](https://gitlab.com/gnuechtel/open-source/-/tree/main/apps/example/node-app-e2e) |
334
371
 
335
372
  ### More examples
336
373
 
337
- If we have executed our nx-cucumber [end-to-end tests](#end-to-end-tests-of-this-project), we got a lot of more [example projects](https://gitlab.com/gnuechtel/open-source/-/jobs/artifacts/main/browse/tmp/test-project/apps/?job=e2e-nx-cucumber:linux:%20[latest,%20latest,%20latest]), their [Cucumber](https://gitlab.com/gnuechtel/open-source/-/jobs/artifacts/main/browse/tmp/test-project/dist/cucumber-js/apps/?job=e2e-nx-cucumber:linux:%20[latest,%20latest,%20latest]) output and [coverage](https://gitlab.com/gnuechtel/open-source/-/jobs/artifacts/main/browse/tmp/test-project/dist/coverage/apps/?job=e2e-nx-cucumber:linux:%20[latest,%20latest,%20latest]) reports for free. For example:
338
-
339
- - [multimedia-playwright](https://gitlab.com/gnuechtel/open-source/-/jobs/artifacts/main/browse/tmp/test-project/apps/gnu-app-multimedia-playwright-e2e/?job=e2e-nx-cucumber:linux:%20[latest,%20latest,%20latest])
340
- - [custom-world-playwright](https://gitlab.com/gnuechtel/open-source/-/jobs/artifacts/main/browse/tmp/test-project/apps/gnu-app-custom-world-playwright-e2e/?job=e2e-nx-cucumber:linux:%20[latest,%20latest,%20latest])
341
- - [covered-playwright](https://gitlab.com/gnuechtel/open-source/-/jobs/artifacts/main/browse/tmp/test-project/apps/gnu-app-covered-playwright-e2e/?job=e2e-nx-cucumber:linux:%20[latest,%20latest,%20latest])
342
- - [covered-core](https://gitlab.com/gnuechtel/open-source/-/jobs/artifacts/main/browse/tmp/test-project/apps/gnu-app-covered-core-e2e/?job=e2e-nx-cucumber:linux:%20[latest,%20latest,%20latest])
374
+ If we have executed our nx-cucumber [end-to-end tests](#end-to-end-tests-of-this-project), we got a lot of more example projects and their Cucumber output for free.
343
375
 
344
376
  ## End-to-end tests of this project
345
377
 
346
378
  We support Cucumber with this plugin, and it would be a shame if we used anything other than Cucumber for our own end to end tests. So, we [just do it](https://gitlab.com/gnuechtel/open-source/-/blob/main/apps/nx-cucumber-e2e/features/nx-cucumber.feature)!
347
379
 
348
- And we are not only using Cucumber alone, we are also using nx-cucumber for our end-to-end tests! This is possible, since nx-cucumber is also usable inside this repository. So we can use nx-cucumber for our tests and example projects.
349
-
350
- A great side effect of using nx-cucumber internally is also, that we will be our own and first consumer. So we will always got the first integration test for free after code changes.
351
-
352
380
  To run our own end-to-end tests we simply execute them by:
353
381
 
354
382
  ```bash
@@ -361,96 +389,76 @@ Our [continuous delivery pipeline](https://gitlab.com/gnuechtel/open-source/-/pi
361
389
 
362
390
  The end-to-end tests in the continuous delivery pipeline run on combinations of:
363
391
 
364
- - [latest](https://gitlab.com/gnuechtel/open-source/-/jobs/artifacts/main/file/tmp/test-project/dist/cucumber-js/apps/gnu-app-multimedia-playwright-e2e/reports/html/cucumber-test-report.html?job=e2e-nx-cucumber:linux:%20[latest,%20latest,%20latest]) and [next](https://gitlab.com/gnuechtel/open-source/-/jobs/artifacts/main/file/tmp/test-project/dist/cucumber-js/apps/gnu-app-multimedia-playwright-e2e/reports/html/cucumber-test-report.html?job=e2e-nx-cucumber:linux:%20[next,%20latest,%20latest]) Nx version
392
+ - latest and next Nx version
365
393
  - the latest Cucumber version
366
- - the latest and [next](https://gitlab.com/gnuechtel/open-source/-/jobs/artifacts/main/file/tmp/test-project/dist/cucumber-js/apps/gnu-app-multimedia-playwright-e2e/reports/html/cucumber-test-report.html?job=e2e-nx-cucumber:linux:%20[latest,%20latest,%20next]) Playwright version
394
+ - the latest and next Playwright version
367
395
 
368
- So we currently run 4 Linux matrix combinations. Windows and macOS end-to-end tests run only with the latest versions.
369
-
370
- ![continuous delivery pipeline with selected e2e jobs](https://gitlab.com/gnuechtel/open-source/-/raw/a5efc3dab283ca70da0d2f335df65c7081fbdfac/libs/nx-cucumber/assets/pipeline-jobs.png)
396
+ Linux runs the full test suite. macOS and Windows run `@core` tagged scenarios for faster feedback.
371
397
 
372
398
  ## Debugging and watching scenarios
373
399
 
374
- During the development of Cucumber scenarios, it can be useful to use debugging and watching.
375
- Debugging means, that we can go to the Cucumber scenarios step by step.
400
+ During the development of Cucumber scenarios, it can be useful to use debugging and watching.
401
+ Debugging means, that we can go to the Cucumber scenarios step by step.
376
402
  Watching means, that scenarios will be executed automatically after file changes.
377
403
 
378
404
  ### Debugging
379
405
 
380
- Debugging is available for the Playwright test runner only.
381
- It enables the Playwright inspector with paused execution in a headed browser.
382
- We achieve debugging by the following command:
406
+ Debugging is available for the Playwright test runner only.
407
+ It enables the Playwright inspector with paused execution in a headed browser.
408
+ Set the `PWDEBUG` environment variable:
383
409
 
384
410
  ```bash
385
- npx nx e2e my-project-e2e --debug
411
+ PWDEBUG=1 npx nx e2e my-project-e2e
386
412
  ```
387
413
 
388
- In the following screenshot, we can see the debug mode in action:
389
-
390
- ![debug Playwright](https://gitlab.com/gnuechtel/open-source/-/raw/f3d4938292fb6fef4c8d6ddcc13bd9c31b05db29/libs/nx-cucumber/assets/debug-playwright.png)
391
-
392
414
  ### Watching
393
415
 
394
- To watch Cucumber tests, we can use nx [workspace watching](https://nx.dev/recipes/running-tasks/workspace-watching). By convenience, the project generator creates an `e2e-watch` target (see [example react app](https://gitlab.com/gnuechtel/open-source/-/blob/a4a012089ce5db916f9b2bdb00dad4266b65df3d/apps/example/react-app-e2e/project.json#L28)) which we can use with the following command:
395
-
396
- ```bash
397
- npx nx e2e-watch example-react-app-e2e
398
- ```
399
-
400
- We can combine watching with other parameters:
416
+ To watch Cucumber tests, we can use nx [workspace watching](https://nx.dev/recipes/running-tasks/workspace-watching):
401
417
 
402
418
  ```bash
403
- npx nx e2e-watch example-react-app-e2e --debug
404
- npx nx e2e-watch example-react-app-e2e --debug --tags=@focus
419
+ npx nx watch --projects=my-project-e2e -- npx nx e2e my-project-e2e
405
420
  ```
406
421
 
407
422
  ## Filter Cucumber scenarios
408
423
 
409
- While development of Cucumber scenarios, we often want to execute only selected scenarios. We can achieve this by using the filter capabilities of Cucumber.
424
+ While development of Cucumber scenarios, we often want to execute only selected scenarios. We can achieve this by using the filter capabilities of Cucumber in the `cucumber.js` config or via CLI arguments.
410
425
 
411
426
  ### Filter by tags
412
427
 
413
- - Add some tag to some scenario or feature, like `@focus`:
414
-
415
- ```gherkin
416
- @focus
417
- Scenario: a user wants to get project information
428
+ Add a tag to a scenario and filter:
418
429
 
419
- Given any user has found our project home page
420
- When the user requests project information
421
- Then some advices will be shown
422
- ```
423
-
424
- - Run scenarios with tag parameter:
430
+ ```gherkin
431
+ @focus
432
+ Scenario: a user wants to get project information
425
433
 
426
- ```bash
427
- # Run one-time ...
428
- npx nx e2e my-project-e2e --tag=@focus
434
+ Given any user has found our project home page
435
+ When the user requests project information
436
+ Then some advices will be shown
437
+ ```
429
438
 
430
- # ... or in combination with watch to continuously run scenarios while development
431
- npx nx e2e-watch my-project-e2e --tag=@focus
432
- ```
439
+ ```bash
440
+ npx nx e2e my-project-e2e -- --tags "@focus"
441
+ ```
433
442
 
434
443
  ### Filter by name
435
444
 
436
- We can filter scenarios by name with regular expressions. Simple expressions are good to include scenarios (like in the first example). More [sophisticated](https://regex101.com/r/Lko9Iv/1) expressions are used when we want to exclude some scenarios (like in the second example).
445
+ We can filter scenarios by name with regular expressions:
437
446
 
438
447
  ```bash
439
448
  # execute all scenarios where the name contains 'payment'
440
- npx nx e2e my-project-e2e --name "payment"
449
+ npx nx e2e my-project-e2e -- --name "payment"
441
450
 
442
451
  # execute all scenarios where the name does not contain 'mobile' nor something like 'top secret'
443
- npx nx e2e my-project-e2e --name '^((?!mobile|top.?secret).)*$'
452
+ npx nx e2e my-project-e2e -- --name '^((?!mobile|top.?secret).)*$'
444
453
  ```
445
454
 
446
455
  ## Special tags
447
456
 
448
- As seen in the last chapter, Cucumber tags can be used for scenario filtering. Another purpose is to control some technical behavior.
449
- Nx-cucumber provides some technical built-in tags which are described here.
457
+ Cucumber tags can be used for scenario filtering and to control technical behavior. Nx-cucumber provides some technical built-in tags which are described here.
450
458
 
451
459
  ### Tags `@javascript` and `@noscript`
452
460
 
453
- In `project.json` we can set `disableJavaScript` to `true`. With that setting, we would disable javascript for all Cucumber scenarios with the Playwright test runner. However, we can enable javascript again for selected scenarios in such a case, by using the `@javascript` tag for single scenarios or complete features:
461
+ In `cucumber.js` we can set `worldParameters.disableJavaScript` to `true`. With that setting, we would disable javascript for all Cucumber scenarios with the Playwright test runner. However, we can enable javascript again for selected scenarios by using the `@javascript` tag:
454
462
 
455
463
  ```gherkin
456
464
  @javascript
@@ -473,9 +481,7 @@ Then a welcome message will be shown
473
481
 
474
482
  ### Tag @headed
475
483
 
476
- By default, all Cucumber scenarios with Playwright run in a headless browser. Some actions like copy-and-paste do not work headless. In such cases, we can add the `@headed` tag to scenarios to use a headed browser. When a headless browser is currently running, it will be closed and a headed one will be started and vice versa. Existing headless/headed browser instances will be reused, when the previous scenario also used the same browser mode.
477
-
478
- A headed example scenario could be written like this:
484
+ By default, all Cucumber scenarios with Playwright run in a headless browser. Some actions like copy-and-paste do not work headless. In such cases, we can add the `@headed` tag to scenarios to use a headed browser.
479
485
 
480
486
  ```gherkin
481
487
  @headed
@@ -486,190 +492,117 @@ When the users copies the search
486
492
  Then the search data is stored in the clipboard
487
493
  ```
488
494
 
489
- The following example implementation of the Cucumber steps reads data from the clipboard.
490
- It only works with the `@headed` tag and could be written like this:
491
-
492
- ```typescript
493
- import { Given, Then, When } from '@cucumber/cucumber';
494
- import { expect } from '@playwright/test';
495
- import { PlaywrightWorld } from '@gnuechtel/nx-cucumber';
496
-
497
- Given(
498
- 'the user has searched for content',
499
- async function (this: PlaywrightWorld) {
500
- await this.page.type('#search', mySearch);
501
- await this.page.click('#searchButton');
502
- }
503
- );
504
-
505
- When('users copies the search', async function (this: PlaywrightWorld) {
506
- await this.page.click('#copySearchButton');
507
- });
508
-
509
- Then(
510
- 'the search data is stored in the clipboard',
511
- async function (this: PlaywrightWorld) {
512
- const clipboardText = await readTextFromClipboard(this.page);
513
- expect(clipboardText).toBe(mySearch);
514
- }
515
- );
516
-
517
- const mySearch = 'my search';
518
-
519
- async function readTextFromClipboard(page: Page) {
520
- await page.context().grantPermissions(['clipboard-read']);
521
- return (await page.evaluate(() =>
522
- window.navigator.clipboard.readText().then((text) => {
523
- return new Promise((resolve) => {
524
- resolve(text);
525
- });
526
- })
527
- )) as string;
528
- }
529
- ```
530
-
531
495
  ## Profiles
532
496
 
533
- Nx-cucumber supports [Cucumber profiles](https://github.com/cucumber/cucumber-js/blob/main/docs/profiles.md) with [custom Cucumber configuration](#custom-cucumber-configuration).
534
- An example `cucumber.js` file which provides some profiles for special names could look like this:
497
+ Nx-cucumber supports [Cucumber profiles](https://github.com/cucumber/cucumber-js/blob/main/docs/profiles.md) in the `cucumber.js` config:
535
498
 
536
499
  ```javascript
537
500
  module.exports = {
501
+ default: {
502
+ // ... default configuration
503
+ },
538
504
  homepage: { name: ['a user visits the home page'] },
539
505
  'project-info': { name: ['a user wants to get project information'] },
540
506
  };
541
507
  ```
542
508
 
543
- To define profiles, which will be executed by default, we can define them in `project.json` like this:
544
-
545
- ```json
546
- "profiles": ["homepage"]
547
- ```
548
-
549
- We can also run profiles from the command-line, which would override any defined default profiles:
509
+ Run profiles from the command-line:
550
510
 
551
511
  ```bash
552
- # Use our custom homepage and project-info profiles
553
- npx nx e2e my-project-e2e --profile homepage --profile project-info
554
-
555
- # Use built-in Cucumber default profile
556
- npx nx e2e my-project-e2e --profile default
512
+ npx nx e2e my-project-e2e -- --profile homepage
557
513
  ```
558
514
 
559
515
  ## Logging
560
516
 
561
- Logging messages are produced by the [debug](https://www.npmjs.com/package/debug) library. The project generator creates a [.env file](https://gitlab.com/gnuechtel/open-source/-/blob/main/libs/nx-cucumber/src/generators/project/files/all/.env.template?ref_type=heads) which contains the default logging configuration. By changing the `.env` file in the generated Cucumber project, the verbosity of the log output may be decreased (e.g. remove `pw:api` or just use `e2e:cucumber`) or increased (e.g. use `pw:*`). A typical output for a single scenario with Playwright looks like this:
562
-
563
- ```log
564
- 2023-10-31T23:26:23.135Z e2e:cucumber STARTED - scenario - a user visits the home page
565
- 2023-10-31T23:26:23.136Z e2e:hooks Before - Cleaning up
566
- 2023-10-31T23:26:23.136Z e2e:world Cleaning up world instance
567
- 2023-10-31T23:26:23.136Z e2e:world World instance cleaned up
568
- 2023-10-31T23:26:23.136Z e2e:hooks Before - Cleaned up
569
- 2023-10-31T23:26:23.137Z e2e:cucumber PASSED - hook - prepare
570
- 2023-10-31T23:26:23.137Z e2e:hooks Before not @headed - Creating new headless Chromium instance
571
- 2023-10-31T23:26:23.139Z pw:api => browserType.launch started
572
- 2023-10-31T23:26:23.295Z pw:api <= browserType.launch succeeded
573
- 2023-10-31T23:26:23.295Z e2e:hooks Before not @headed - Chromium instance created
574
- 2023-10-31T23:26:23.296Z e2e:cucumber PASSED - hook - ensure headless browser [not @headed]
575
- 2023-10-31T23:26:23.296Z e2e:hooks BeforeStep
576
- 2023-10-31T23:26:23.298Z pw:api => started
577
- 2023-10-31T23:26:23.304Z pw:api <= succeeded
578
- 2023-10-31T23:26:23.307Z pw:api => browserContext.exposeFunction started
579
- 2023-10-31T23:26:23.310Z pw:api <= browserContext.exposeFunction succeeded
580
- 2023-10-31T23:26:23.310Z pw:api => started
581
- 2023-10-31T23:26:23.311Z pw:api <= succeeded
582
- 2023-10-31T23:26:23.311Z pw:api => browserContext.newPage started
583
- 2023-10-31T23:26:23.338Z pw:api <= browserContext.newPage succeeded
584
- 2023-10-31T23:26:23.340Z pw:api => page.goto started
585
- 2023-10-31T23:26:23.341Z pw:api navigating to "http://localhost:4200/", waiting until "load"
586
- 2023-10-31T23:26:23.356Z pw:api "commit" event fired
587
- 2023-10-31T23:26:23.356Z pw:api navigated to "http://localhost:4200/"
588
- 2023-10-31T23:26:23.426Z pw:api "domcontentloaded" event fired
589
- 2023-10-31T23:26:23.426Z pw:api "load" event fired
590
- 2023-10-31T23:26:23.427Z pw:api <= page.goto succeeded
591
- 2023-10-31T23:26:23.427Z e2e:hooks AfterStep - Creating screenshots
592
- 2023-10-31T23:26:23.428Z e2e:world Storing screenshots
593
- 2023-10-31T23:26:23.430Z pw:api => page.screenshot started
594
- 2023-10-31T23:26:23.431Z pw:api taking page screenshot
595
- 2023-10-31T23:26:23.655Z pw:api <= page.screenshot succeeded
596
- 2023-10-31T23:26:23.655Z e2e:world Attaching image to current step
597
- 2023-10-31T23:26:23.656Z e2e:world Image attached
598
- 2023-10-31T23:26:23.656Z e2e:world Successful screenshot files are disabled
599
- 2023-10-31T23:26:23.656Z e2e:world Screenshots stored
600
- 2023-10-31T23:26:23.656Z e2e:hooks AfterStep - Screenshots created
601
- 2023-10-31T23:26:23.657Z e2e:cucumber PASSED - step - any user finds our project home page
602
- 2023-10-31T23:26:23.657Z e2e:hooks BeforeStep
603
- 2023-10-31T23:26:23.662Z pw:api => locator._expect started
604
- 2023-10-31T23:26:23.663Z pw:api locator._expect with timeout 5000ms
605
- 2023-10-31T23:26:23.665Z pw:api waiting for locator('h1').getByText('Hello there, Welcome gnu-app 👋')
606
- 2023-10-31T23:26:23.683Z pw:api locator resolved to <h1>…</h1>
607
- 2023-10-31T23:26:23.683Z pw:api <= locator._expect succeeded
608
- 2023-10-31T23:26:23.684Z e2e:hooks AfterStep - Creating screenshots
609
- 2023-10-31T23:26:23.684Z e2e:world Storing screenshots
610
- 2023-10-31T23:26:23.685Z pw:api => page.screenshot started
611
- 2023-10-31T23:26:23.686Z pw:api taking page screenshot
612
- 2023-10-31T23:26:23.837Z pw:api <= page.screenshot succeeded
613
- 2023-10-31T23:26:23.837Z e2e:world Attaching image to current step
614
- 2023-10-31T23:26:23.838Z e2e:world Image attached
615
- 2023-10-31T23:26:23.838Z e2e:world Successful screenshot files are disabled
616
- 2023-10-31T23:26:23.838Z e2e:world Screenshots stored
617
- 2023-10-31T23:26:23.838Z e2e:hooks AfterStep - Screenshots created
618
- 2023-10-31T23:26:23.839Z e2e:cucumber PASSED - step - a welcome message will be shown
619
- 2023-10-31T23:26:23.839Z e2e:hooks After - Collecting coverage
620
- 2023-10-31T23:26:23.841Z pw:api => page.evaluate started
621
- 2023-10-31T23:26:23.847Z pw:api => started
622
- 2023-10-31T23:26:23.848Z pw:api <= succeeded
623
- 2023-10-31T23:26:23.849Z pw:api <= page.evaluate succeeded
624
- 2023-10-31T23:26:23.849Z e2e:hooks After - Coverage collected
625
- 2023-10-31T23:26:23.849Z e2e:hooks After - Cleaning up
626
- 2023-10-31T23:26:23.849Z e2e:world Cleaning up world instance
627
- 2023-10-31T23:26:23.849Z e2e:world Closing browser context
628
- 2023-10-31T23:26:23.850Z pw:api => started
629
- 2023-10-31T23:26:23.859Z pw:api <= succeeded
630
- 2023-10-31T23:26:23.859Z e2e:world Browser context closed
631
- 2023-10-31T23:26:23.859Z e2e:world World instance cleaned up
632
- 2023-10-31T23:26:23.859Z e2e:hooks After - Cleaned up
633
- 2023-10-31T23:26:23.859Z e2e:cucumber PASSED - hook - clean up
634
- 2023-10-31T23:26:23.860Z e2e:cucumber FINISHED - scenario - a user visits the home page
635
- ```
517
+ Logging messages are produced by the [debug](https://www.npmjs.com/package/debug) library. The project generator creates a [.env file](https://gitlab.com/gnuechtel/open-source/-/blob/main/libs/nx-cucumber/src/generators/project/files/all/.env.template?ref_type=heads) which contains the default logging configuration. By changing the `.env` file in the generated Cucumber project, the verbosity of the log output may be decreased or increased.
636
518
 
637
519
  ## Contribution
638
520
 
639
- Currently, this project is written and maintained by a [single person](https://gitlab.com/christian.gnuechtel). Development is active with focus on 1.x compatibility and planned 2.x improvements. Contributing is welcome, especially bug fixes and compatibility updates. Please [open an issue](https://gitlab.com/gnuechtel/open-source/-/issues/new) if you want to join.
521
+ Currently, this project is written and maintained by a [single person](https://gitlab.com/christian.gnuechtel). Development is active with focus on 2.x improvements. Contributing is welcome, especially bug fixes and compatibility updates. Please [open an issue](https://gitlab.com/gnuechtel/open-source/-/issues/new) if you want to join.
640
522
 
641
523
  ## Troubleshooting
642
524
 
643
- ### Known limitations in 1.x
525
+ ### A tag is not found
644
526
 
645
- In the 1.x maintenance line, the following limitations are intentional:
527
+ A common mistake, is to forget the `@` before any tag. This would be wrong: ~~npx nx e2e example-react-app-e2e -- --tags "mytag"~~.
528
+ The correct usage is: `npx nx e2e example-react-app-e2e -- --tags "@mytag"`.
646
529
 
647
- - Playwright UI mode is not supported in the current 1.x executor architecture (tracked for 2.x via #43).
648
- - Deterministic parallel Cucumber execution is not supported in 1.x (tracked for 2.x via #44).
649
- - Inline-workspace Playwright inspector line precision is a known limitation and remains `won't fix` in 1.x (#36).
650
- - Generated external-workspace debug source navigation history is tracked in #49 (currently closed). Open a follow-up issue if regression reappears.
530
+ ### Some Cucumber product feature does not work with nx-cucumber
651
531
 
652
- ### Dev server does not shutdown properly
532
+ Since 2.x uses framework-native execution via `npx cucumber-js`, all Cucumber CLI features are available directly. Configure them in the `cucumber.js` file.
653
533
 
654
- Nx-cucumber does its best to properly shutdown dev server(s) after Cucumber execution. For some project setups it is difficult or even impossible to kill all processes. For such cases an easy workaround exists:
534
+ If a feature is missing, please open an issue with a minimal reproducible setup.
655
535
 
656
- Before executing the Cucumber project, we just start the dev server in another terminal. For example: `npx nx serve my-application`. After that, we execute the Cucumber scenarios as usual: `npx nx e2e my-application-e2e`. The nx-cucumber will detect the running application via the base URL. After the execution the server is still running, since nx-cucumber only shutdowns the self-started dev servers.
536
+ ## Migration from 1.x
657
537
 
658
- ### Wrong line numbers when using Playwright inspector
538
+ ### Prerequisites
659
539
 
660
- When trying out the example projects inside this repository, the Playwright inspector can highlight incorrect line numbers when execution is paused. For inline-workspace scenarios this is tracked in [#36](https://gitlab.com/gnuechtel/open-source/-/issues/36) and remains `won't fix` in 1.x.
540
+ - Upgrade to Nx `>=22`
541
+ - Install `@gnuechtel/nx-cucumber@2`
661
542
 
662
- Generated external-workspace debug source navigation history is documented in [#49](https://gitlab.com/gnuechtel/open-source/-/issues/49), which is currently closed. If a regression reappears, open a follow-up issue. Depending on workspace setup and sync state, source mapping may still vary.
543
+ ### Step 1: Register the plugin
663
544
 
664
- ### A tag is not found
545
+ Add the plugin to `nx.json`:
665
546
 
666
- A common mistake, is to forget the `@` before any tag. This would be wrong: ~~npx nx e2e example-react-app-e2e --tag=mytag~~.
667
- The correct usage is: `npx nx e2e example-react-app-e2e --tag=@mytag`.
547
+ ```json
548
+ {
549
+ "plugins": ["@gnuechtel/nx-cucumber"]
550
+ }
551
+ ```
668
552
 
669
- ### Some Cucumber product feature does not work with nx-cucumber
553
+ ### Step 2: Create cucumber.js config
670
554
 
671
- Nx-cucumber aims to support all important Cucumber product features. Since we are using the [Cucumber JavaScript API](#cucumber-javascript-api), the `cucumber-js` command-line tool is not available, but fortunately most of the advanced features may be used with [custom Cucumber configuration](#custom-cucumber-configuration).
555
+ For each e2e project, create a `cucumber.js` file. For Playwright projects:
672
556
 
673
- Since this is an open source project, you can change this software for your own needs. However, it would be the best choice to [contribute](#contribution) to this project by opening an [issue](https://gitlab.com/gnuechtel/open-source/-/issues/new).
557
+ ```javascript
558
+ const outputDir = 'dist/e2e/apps/my-project-e2e';
559
+
560
+ module.exports = {
561
+ default: {
562
+ paths: ['apps/my-project-e2e/features/**/*.feature'],
563
+ requireModule: ['ts-node/register'],
564
+ require: [
565
+ 'apps/my-project-e2e/src/**/*.ts',
566
+ 'node_modules/@gnuechtel/nx-cucumber/src/playwright/playwright-world-default.js',
567
+ 'node_modules/@gnuechtel/nx-cucumber/src/playwright/playwright-hooks.js',
568
+ ],
569
+ tags: 'not @ignore',
570
+ format: [
571
+ 'summary',
572
+ 'progress-bar',
573
+ `json:${outputDir}/reports/cucumber-json/cucumber-test-report.json`,
574
+ `html:${outputDir}/reports/html/cucumber-test-report-builtin.html`,
575
+ `junit:${outputDir}/reports/test-results/cucumber-test-report.xml`,
576
+ ],
577
+ publishQuiet: true,
578
+ },
579
+ };
580
+ ```
581
+
582
+ For core (non-Playwright) projects, omit the Playwright require entries.
583
+
584
+ ### Step 3: Simplify project.json
585
+
586
+ Remove the executor-based `e2e` and `e2e-cucumber` targets from `project.json`. The plugin infers the `e2e` target automatically from the `cucumber.js` file. Keep only non-inferred targets like `lint`.
587
+
588
+ ### Step 4: Move executor options to cucumber.js
589
+
590
+ | 1.x executor option | 2.x equivalent |
591
+ | ------------------------------ | ----------------------------------------------------- |
592
+ | `testRunner` | Which `require` entries are in `cucumber.js` |
593
+ | `featuresDirectory` | `paths` in `cucumber.js` |
594
+ | `tags` | `tags` in `cucumber.js` |
595
+ | `cucumberTimeout` | `timeout` in `cucumber.js` |
596
+ | `baseUrl`, `headed`, `browser` | `worldParameters` in `cucumber.js` |
597
+ | `disableVideoFiles`, etc. | `worldParameters` in `cucumber.js` |
598
+ | `devServerTarget` | Use Nx task dependencies (`dependsOn`) |
599
+ | `reportOptions` | `format` entries in `cucumber.js` |
600
+ | `instrumentTestRunner` | External coverage tooling (nyc, vite-plugin-istanbul) |
601
+
602
+ ### Step 5: Verify
603
+
604
+ ```bash
605
+ npx nx e2e my-project-e2e
606
+ ```
674
607
 
675
- If a Cucumber feature is missing, please open an issue with a minimal reproducible setup. Maintenance work is prioritized by compatibility and impact.
608
+ The inferred target runs `npx cucumber-js` with the configuration from `cucumber.js`.