Skip to content

Commit

Permalink
Add support for skipped steps
Browse files Browse the repository at this point in the history
This fixes #1053 [1].

[1] #1053
  • Loading branch information
badeball committed Jul 10, 2023
1 parent 2bd954c commit d9043da
Show file tree
Hide file tree
Showing 8 changed files with 225 additions and 11 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

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

## Unreleased

- Add support for skipped steps, fixes [#1053](https://github.com/badeball/cypress-cucumber-preprocessor/issues/1053).

## v18.0.1

- Give each TestStep (from `@cucumber/messages`) a unique ID, fixes [#1034](https://github.com/badeball/cypress-cucumber-preprocessor/issues/1034).
Expand Down
24 changes: 23 additions & 1 deletion docs/cucumber-basics.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ Custom parameter types can be registered using `defineParameterType()`. They sha

# Pending steps

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".
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.

```ts
import { When } from "@badeball/cypress-cucumber-preprocessor";
Expand All @@ -66,6 +66,28 @@ When("a step", () => {
});
```

# Skipped steps

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.

```ts
import { When } from "@badeball/cypress-cucumber-preprocessor";

When("a step", () => {
return "skipped";
});
```

```ts
import { When } from "@badeball/cypress-cucumber-preprocessor";

When("a step", () => {
cy.then(() => {
return "skipped";
});
});
```

# Nested steps

You can invoke other steps from a step using `Step()`, as shown below.
Expand Down
63 changes: 63 additions & 0 deletions features/fixtures/skipped-steps.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
[
{
"description": "",
"elements": [
{
"description": "",
"id": "a-feature;a-scenario",
"keyword": "Scenario",
"line": 2,
"name": "a scenario",
"steps": [
{
"arguments": [],
"keyword": "Given ",
"line": 3,
"name": "a preceding step",
"match": {
"location": "not available:0"
},
"result": {
"status": "passed",
"duration": 0
}
},
{
"arguments": [],
"keyword": "And ",
"line": 4,
"name": "a skipped step",
"match": {
"location": "not available:0"
},
"result": {
"status": "skipped",
"duration": 0
}
},
{
"arguments": [],
"keyword": "And ",
"line": 5,
"name": "a succeeding step",
"match": {
"location": "not available:0"
},
"result": {
"status": "skipped",
"duration": 0
}
}
],
"tags": [],
"type": "scenario"
}
],
"id": "a-feature",
"line": 1,
"keyword": "Feature",
"name": "a feature",
"tags": [],
"uri": "cypress/e2e/a.feature"
}
]
17 changes: 17 additions & 0 deletions features/fixtures/skipped-steps.ndjson
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{"testRunStarted":{"timestamp":{"seconds":0,"nanos":0}}}
{"source":{"data":"Feature: a feature\n Scenario: a scenario\n Given a preceding step\n And a skipped step\n And a succeeding step","uri":"cypress/e2e/a.feature","mediaType":"text/x.cucumber.gherkin+plain"}}
{"gherkinDocument":{"feature":{"tags":[],"location":{"line":1,"column":1},"language":"en","keyword":"Feature","name":"a feature","description":"","children":[{"scenario":{"id":"id","tags":[],"location":{"line":2,"column":3},"keyword":"Scenario","name":"a scenario","description":"","steps":[{"id":"id","location":{"line":3,"column":5},"keyword":"Given ","keywordType":"Context","text":"a preceding step"},{"id":"id","location":{"line":4,"column":5},"keyword":"And ","keywordType":"Conjunction","text":"a skipped step"},{"id":"id","location":{"line":5,"column":5},"keyword":"And ","keywordType":"Conjunction","text":"a succeeding step"}],"examples":[]}}]},"comments":[],"uri":"cypress/e2e/a.feature"}}
{"pickle":{"id":"id","uri":"cypress/e2e/a.feature","astNodeIds":["id"],"tags":[],"name":"a scenario","language":"en","steps":[{"id":"id","text":"a preceding step","type":"Context","astNodeIds":["id"]},{"id":"id","text":"a skipped step","type":"Context","astNodeIds":["id"]},{"id":"id","text":"a succeeding step","type":"Context","astNodeIds":["id"]}]}}
{"stepDefinition":{"id":"id","pattern":{"type":"CUCUMBER_EXPRESSION","source":"a preceding step"},"sourceReference":{"uri":"not available","location":{"line":0}}}}
{"stepDefinition":{"id":"id","pattern":{"type":"CUCUMBER_EXPRESSION","source":"a skipped step"},"sourceReference":{"uri":"not available","location":{"line":0}}}}
{"stepDefinition":{"id":"id","pattern":{"type":"CUCUMBER_EXPRESSION","source":"a succeeding step"},"sourceReference":{"uri":"not available","location":{"line":0}}}}
{"testCase":{"id":"id","pickleId":"id","testSteps":[{"id":"id","pickleStepId":"id","stepDefinitionIds":["id"]},{"id":"id","pickleStepId":"id","stepDefinitionIds":["id"]},{"id":"id","pickleStepId":"id","stepDefinitionIds":["id"]}]}}
{"testCaseStarted":{"id":"id","testCaseId":"id","attempt":0,"timestamp":{"seconds":0,"nanos":0}}}
{"testStepStarted":{"testStepId":"id","testCaseStartedId":"id","timestamp":{"seconds":0,"nanos":0}}}
{"testStepFinished":{"testStepId":"id","testCaseStartedId":"id","testStepResult":{"status":"PASSED","duration":0},"timestamp":{"seconds":0,"nanos":0}}}
{"testStepStarted":{"testStepId":"id","testCaseStartedId":"id","timestamp":{"seconds":0,"nanos":0}}}
{"testStepFinished":{"testStepId":"id","testCaseStartedId":"id","testStepResult":{"status":"SKIPPED","duration":0},"timestamp":{"seconds":0,"nanos":0}}}
{"testStepStarted":{"testStepId":"id","testCaseStartedId":"id","timestamp":{"seconds":0,"nanos":0}}}
{"testStepFinished":{"testStepId":"id","testCaseStartedId":"id","testStepResult":{"status":"SKIPPED","duration":0},"timestamp":{"seconds":0,"nanos":0}}}
{"testCaseFinished":{"testCaseStartedId":"id","timestamp":{"seconds":0,"nanos":0},"willBeRetried":false}}
{"testRunFinished":{"timestamp":{"seconds":0,"nanos":0}}}
22 changes: 22 additions & 0 deletions features/reporters/json.feature
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,28 @@ Feature: JSON formatter
Then it passes
And there should be a JSON output similar to "fixtures/pending-steps.json"

Scenario: skipped step
Given a file named "cypress/e2e/a.feature" with:
"""
Feature: a feature
Scenario: a scenario
Given a preceding step
And a skipped step
And a succeeding step
"""
And a file named "cypress/support/step_definitions/steps.js" with:
"""
const { Given } = require("@badeball/cypress-cucumber-preprocessor");
Given("a preceding step", function () {})
Given("a skipped step", function () {
return "skipped";
});
Given("a succeeding step", function () {})
"""
When I run cypress
Then it passes
And there should be a JSON output similar to "fixtures/skipped-steps.json"

Scenario: retried
Given additional Cypress configuration
"""
Expand Down
22 changes: 22 additions & 0 deletions features/reporters/messages.feature
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,28 @@ Feature: messages report
Then it passes
And there should be a messages similar to "fixtures/pending-steps.ndjson"

Scenario: skipped step
Given a file named "cypress/e2e/a.feature" with:
"""
Feature: a feature
Scenario: a scenario
Given a preceding step
And a skipped step
And a succeeding step
"""
And a file named "cypress/support/step_definitions/steps.js" with:
"""
const { Given } = require("@badeball/cypress-cucumber-preprocessor");
Given("a preceding step", function () {})
Given("a skipped step", function () {
return "skipped";
});
Given("a succeeding step", function () {})
"""
When I run cypress
Then it passes
And there should be a messages similar to "fixtures/skipped-steps.ndjson"

Scenario: retried
Given additional Cypress configuration
"""
Expand Down
52 changes: 52 additions & 0 deletions features/skipped_steps.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
Feature: skipped steps
Background:
Given a file named "cypress/e2e/a.feature" with:
"""
Feature: a feature
Scenario: a scenario
Given a skipped step
"""
And a file named "cypress/support/step_definitions/steps.js" with:
"""
const { Given } = require("@badeball/cypress-cucumber-preprocessor")
Given("a skipped step", function() {
return "skipped"
})
"""

Rule: skipped steps make the test skipped

Scenario: basic skipped step
When I run cypress
Then it passes
And it should appear to have skipped the scenario "a scenario"

Scenario: with step hooks returning strings
Given a file named "cypress/support/step_definitions/hooks.js" with:
"""
const { BeforeStep, AfterStep } = require("@badeball/cypress-cucumber-preprocessor")
BeforeStep(function() {
return "foobar"
})
AfterStep(function() {
return "foobar"
})
"""
When I run cypress
Then it passes
And it should appear to have skipped the scenario "a scenario"

Scenario: with step hooks returning chains
Given a file named "cypress/support/step_definitions/hooks.js" with:
"""
const { BeforeStep, AfterStep } = require("@badeball/cypress-cucumber-preprocessor")
BeforeStep(function() {
return cy.wrap("foobar")
})
AfterStep(function() {
return cy.wrap("foobar")
})
"""
When I run cypress
Then it passes
And it should appear to have skipped the scenario "a scenario"
32 changes: 22 additions & 10 deletions lib/browser-runtime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -589,16 +589,28 @@ function createPickle(context: CompositionContext, pickle: messages.Pickle) {
.then(({ start, result }) => {
const end = createTimestamp();

if (result === "pending") {
taskTestStepFinished(context, {
testStepId,
testCaseStartedId,
testStepResult: {
status: messages.TestStepResultStatus.PENDING,
duration: duration(start, end),
},
timestamp: end,
});
if (result === "pending" || result === "skipped") {
if (result === "pending") {
taskTestStepFinished(context, {
testStepId,
testCaseStartedId,
testStepResult: {
status: messages.TestStepResultStatus.PENDING,
duration: duration(start, end),
},
timestamp: end,
});
} else {
taskTestStepFinished(context, {
testStepId,
testCaseStartedId,
testStepResult: {
status: messages.TestStepResultStatus.SKIPPED,
duration: duration(start, end),
},
timestamp: end,
});
}

remainingSteps.shift();

Expand Down

0 comments on commit d9043da

Please sign in to comment.