Skip to content

Commit 3e9a31c

Browse files
committed
Merge remote-tracking branch 'origin/master'
2 parents d9a2b69 + 4fee78f commit 3e9a31c

29 files changed

+1180
-311
lines changed

CHANGELOG.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,30 @@
22

33
All notable changes to this project will be documented in this file.
44

5+
## v19.0.1
6+
7+
- Fix type members to account for scenario hook names, fixes [#1113](https://github.com/badeball/cypress-cucumber-preprocessor/issues/1113).
8+
9+
## v19.0.0
10+
11+
Breaking changes:
12+
13+
- Run `After(..)` hooks in reversed order of definition. This is in line with how cucumber-js behaves.
14+
15+
- Updated all dependencies, including `@cucumber/cucumber` to v10.
16+
17+
- String literal attachments are now base64-encoded in JSON reports, ref. [cucumber/cucumber-js#2261](https://github.com/cucumber/cucumber-js/pull/2261).
18+
19+
Other changes:
20+
21+
- Scenario hooks (`Before(..)` and `After(..)`) are now invoked with an object containing a bunch of relevant data. This is in line with how cucumber-js behaves.
22+
23+
- Hooks may now be optionally named. This is in line with how cucumber-js behaves.
24+
25+
- Omit outputting internal task to the command log when using `attach(..)`.
26+
27+
- Add an [API](docs/json-report.md#attachments-node-environment) for adding attachments from the Node environment, fixes [#1089](https://github.com/badeball/cypress-cucumber-preprocessor/issues/1089).
28+
529
## v18.0.6
630

731
- Make the compile output play nicer with ESM, relates to [#1093](https://github.com/badeball/cypress-cucumber-preprocessor/issues/1093).

docs/cucumber-basics.md

Lines changed: 46 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,30 @@
11
[← Back to documentation](readme.md)
22

3-
# Expressions
3+
# Table of Contents <!-- omit from toc -->
4+
5+
- [Step definitions](#step-definitions)
6+
- [Expressions](#expressions)
7+
- [Arguments](#arguments)
8+
- [Custom parameter types](#custom-parameter-types)
9+
- [Pending steps](#pending-steps)
10+
- [Skipped steps](#skipped-steps)
11+
- [Nested steps](#nested-steps)
12+
- [Hooks](#hooks)
13+
- [Scenario hooks](#scenario-hooks)
14+
- [Step hooks](#step-hooks)
15+
- [Named hooks](#named-hooks)
16+
17+
# Step definitions
18+
19+
## Expressions
420

521
A step definition’s *expression* can either be a regular expression or a [cucumber expression](https://github.com/cucumber/cucumber-expressions#readme). The examples in this section use cucumber expressions. If you prefer to use regular expressions, each *capture group* from the match will be passed as arguments to the step definition’s function.
622

723
```ts
824
Given("I have {int} cukes in my belly", (cukes: number) => {});
925
```
1026

11-
# Arguments
27+
## Arguments
1228

1329
Steps can be accompanied by [doc strings](https://cucumber.io/docs/gherkin/reference/#doc-strings) or [data tables](https://cucumber.io/docs/gherkin/reference/#data-tables), both which will be passed to the step definition as the last argument, as shown below.
1430

@@ -34,7 +50,7 @@ Given(/^a table step$/, (table: DataTable) => {
3450

3551
See [here](https://github.com/cucumber/cucumber-js/blob/main/docs/support_files/data_table_interface.md) for `DataTable`'s interface.
3652

37-
# Custom parameter types
53+
## Custom parameter types
3854

3955
Custom parameter types can be registered using `defineParameterType()`. They share the same scope as tests and you can invoke `defineParameterType()` anywhere you define steps, though the order of definition is unimportant. The table below explains the various arguments you can pass when defining a parameter type.
4056

@@ -44,7 +60,7 @@ Custom parameter types can be registered using `defineParameterType()`. They sha
4460
| `regexp` | A regexp that will match the parameter. May include capture groups.
4561
| `transformer` | A function or method that transforms the match from the regexp. Must have arity 1 if the regexp doesn't have any capture groups. Otherwise the arity must match the number of capture groups in `regexp`. |
4662

47-
# Pending steps
63+
## Pending steps
4864

4965
You can return `"pending"` from a step defintion or a chain to mark a step as pending. This will halt the execution and Cypress will report the test as "skipped". This is generally used for marking steps as "unimplemented" and allows you to commit unfinished work without breaking the test suite.
5066

@@ -66,7 +82,7 @@ When("a step", () => {
6682
});
6783
```
6884

69-
# Skipped steps
85+
## Skipped steps
7086

7187
You can return `"skipped"` from a step defintion or a chain to mark a step as pending. This will halt the execution and Cypress will report the test as "skipped". This however is generally used for conditionally short circuiting a test.
7288

@@ -88,7 +104,7 @@ When("a step", () => {
88104
});
89105
```
90106

91-
# Nested steps
107+
## Nested steps
92108

93109
You can invoke other steps from a step using `Step()`, as shown below.
94110

@@ -123,7 +139,11 @@ When("I fill in the entire form", function () {
123139
});
124140
```
125141

126-
# Scenario hooks
142+
# Hooks
143+
144+
There are two types of hooks, scenario hooks and step hooks, each explained below.
145+
146+
## Scenario hooks
127147

128148
`Before()` and `After()` is similar to Cypress' `beforeEach()` and `afterEach()`, but they can be selected to conditionally run based on the tags of each scenario, as shown below. Furthermore, failure in these hooks does **not** result in remaining tests being skipped. This is contrary to Cypress' `beforeEach` and `afterEach`.
129149

@@ -148,9 +168,13 @@ Before({ tags: "@foo and @bar" }, function () {
148168
Before({ tags: "@foo or @bar" }, function () {
149169
// This hook will be executed before scenarios tagged with @foo or @bar.
150170
});
171+
172+
Before(function ({ pickle, gherkinDocument, testCaseStartedId }) {
173+
// Scenario hooks are invoked with an object containing a bunch of relevant data.
174+
});
151175
```
152176

153-
# Step hooks
177+
## Step hooks
154178

155179
`BeforeStep()` and `AfterStep()` are hooks invoked before and after each step, respectively. These too can be selected to conditionally run based on the tags of each scenario, as shown below.
156180

@@ -176,9 +200,22 @@ BeforeStep({ tags: "@foo or @bar" }, function () {
176200
// This hook will be executed before steps in scenarios tagged with @foo or @bar.
177201
});
178202

179-
BeforeStep(function ({ pickle, pickleStep, gherkinDocument, result, testCaseStartedId, testStepId }) {
203+
BeforeStep(function ({ pickle, pickleStep, gherkinDocument, testCaseStartedId, testStepId }) {
180204
// Step hooks are invoked with an object containing a bunch of relevant data.
181205
});
182206
```
183207

184208
[^1]: This discrepancy between the preprocessor and cucumber-js is currently considered to be unsolvable, as explained [here](https://github.com/badeball/cypress-cucumber-preprocessor/issues/824#issuecomment-1561492281).
209+
210+
## Named hooks
211+
212+
Both scenario hooks and step hooks can optionally be named. Names are displayed in the command log, as well as in [messages reports](messages-report.md).
213+
214+
```ts
215+
import { Before, BeforeStep, After, AfterStep } from "@badeball/cypress-cucumber-preprocessor";
216+
217+
Before({ name: "foo" }, function () {});
218+
BeforeStep({ name: "bar" }, function () {});
219+
After({ name: "baz" }, function () {});
220+
AfterStep({ name: "qux" }, function () {});
221+
```

docs/json-report.md

Lines changed: 56 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@ The report is outputted to `cucumber-report.json` in the project directory, but
1818

1919
Screenshots are automatically added to JSON reports, including that of failed tests (unless you have disabled `screenshotOnRunFailure`).
2020

21-
## Attachments
21+
## Attachments (browser environment)
2222

23-
Text, images and other data can be added to the output of the messages and JSON reports with attachments.
23+
Text, images and other data can be added to the output of the messages and JSON reports with attachments, using the browser API explained below.
2424

2525
```ts
2626
import { Given, attach } from "@badeball/cypress-cucumber-preprocessor";
@@ -59,3 +59,57 @@ Given("a step", function() {
5959
attach("Zm9vYmFy", "base64:text/plain");
6060
});
6161
```
62+
63+
## Attachments (node environment)
64+
65+
Similar to the browser API explained above, attachments can also be added using a Node API. This is less typical and only required in specific scenarios. This API is available through the `onAfterStep` option in `addCucumberPreprocessorPlugin`, like shown below. The Node API mimicks the options found in the browser API.
66+
67+
```ts
68+
await addCucumberPreprocessorPlugin(on, config, {
69+
onAfterStep({ wasLastStep, attach }) {
70+
attach("foobar");
71+
}
72+
});
73+
```
74+
75+
By default, text is saved with a MIME type of text/plain. You can also specify a different MIME type.
76+
77+
```ts
78+
await addCucumberPreprocessorPlugin(on, config, {
79+
onAfterStep({ wasLastStep, attach }) {
80+
attach('{ "name": "foobar" }', "application/json");
81+
}
82+
});
83+
```
84+
85+
Images and other binary data can be attached using a Buffer. The data will be base64 encoded in the output.
86+
87+
```ts
88+
await addCucumberPreprocessorPlugin(on, config, {
89+
onAfterStep({ wasLastStep, attach }) {
90+
attach(Buffer.from("foobar"), "text/plain");
91+
}
92+
});
93+
```
94+
95+
If you've already got a base64-encoded string, you can prefix your mime type with `base64:` to indicate this.
96+
97+
```ts
98+
await addCucumberPreprocessorPlugin(on, config, {
99+
onAfterStep({ wasLastStep, attach }) {
100+
attach("Zm9vYmFy", "base64:text/plain");
101+
}
102+
});
103+
```
104+
105+
A `wasLastStep` option is available if you need to attach something at the end of the test.
106+
107+
```ts
108+
await addCucumberPreprocessorPlugin(on, config, {
109+
onAfterStep({ wasLastStep, attach }) {
110+
if (wasLastStep) {
111+
attach("foobar");
112+
}
113+
}
114+
});
115+
```

features/attachments.feature

Lines changed: 0 additions & 69 deletions
This file was deleted.
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
Feature: attachments
2+
3+
Background:
4+
Given additional preprocessor configuration
5+
"""
6+
{
7+
"json": {
8+
"enabled": true
9+
}
10+
}
11+
"""
12+
13+
Rule: it should support a variety of options
14+
15+
Scenario: string identity
16+
Given a file named "cypress/e2e/a.feature" with:
17+
"""
18+
Feature: a feature
19+
Scenario: a scenario
20+
Given a step
21+
"""
22+
And a file named "cypress/support/step_definitions/steps.js" with:
23+
"""
24+
const { Given, attach } = require("@badeball/cypress-cucumber-preprocessor");
25+
Given("a step", function() {
26+
attach("foobar")
27+
})
28+
"""
29+
When I run cypress
30+
Then it passes
31+
And there should be a JSON output similar to "fixtures/attachments/string.json"
32+
33+
Scenario: array buffer
34+
Given a file named "cypress/e2e/a.feature" with:
35+
"""
36+
Feature: a feature
37+
Scenario: a scenario
38+
Given a step
39+
"""
40+
And a file named "cypress/support/step_definitions/steps.js" with:
41+
"""
42+
const { Given, attach } = require("@badeball/cypress-cucumber-preprocessor");
43+
Given("a step", function() {
44+
attach(new TextEncoder().encode("foobar").buffer, "text/plain")
45+
})
46+
"""
47+
When I run cypress
48+
Then it passes
49+
And there should be a JSON output similar to "fixtures/attachments/string.json"
50+
51+
Scenario: string encoded
52+
Given a file named "cypress/e2e/a.feature" with:
53+
"""
54+
Feature: a feature
55+
Scenario: a scenario
56+
Given a step
57+
"""
58+
And a file named "cypress/support/step_definitions/steps.js" with:
59+
"""
60+
const { fromByteArray } = require("base64-js");
61+
const { Given, attach } = require("@badeball/cypress-cucumber-preprocessor");
62+
Given("a step", function() {
63+
attach(fromByteArray(new TextEncoder().encode("foobar")), "base64:text/plain")
64+
})
65+
"""
66+
When I run cypress
67+
Then it passes
68+
And there should be a JSON output similar to "fixtures/attachments/string.json"

0 commit comments

Comments
 (0)