Skip to content

Commit

Permalink
support: include willBeRetried in after hook argument (#2045)
Browse files Browse the repository at this point in the history
  • Loading branch information
davidjgoss committed Jun 6, 2022
1 parent 535589c commit 126772d
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 2 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Expand Up @@ -8,6 +8,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
Please see [CONTRIBUTING.md](https://github.com/cucumber/cucumber/blob/master/CONTRIBUTING.md) on how to contribute to Cucumber.

## [Unreleased]
### Added
- Add `willBeRetried` to the parameter passed to `After` hook functions ([#2045](https://github.com/cucumber/cucumber-js/pull/2045))

## [8.2.2] - 2022-05-27
### Changed
Expand Down
4 changes: 4 additions & 0 deletions UPGRADING.md
Expand Up @@ -29,6 +29,10 @@ setDefinitionFunctionWrapper(function (fn) {
})
```

### Accessing `willBeRetried` from hooks

In the argument passed to your `After` hook function, the `result` no longer has a `willBeRetried` property; this is now available at the top level of the object.

### Using `Cli` programmatically

The `Cli` class is sometimes used to run Cucumber programmatically. We've had to make a few breaking changes:
Expand Down
2 changes: 1 addition & 1 deletion docs/support_files/api_reference.md
Expand Up @@ -38,7 +38,7 @@ Defines a hook which is run after each scenario.
* `tags`: String tag expression used to apply this hook to only specific scenarios. See [cucumber-tag-expressions](https://docs.cucumber.io/tag-expressions/) for more information.
* `timeout`: A hook-specific timeout, to override the default timeout.
* `fn`: A function, defined as follows:
* The first argument will be an object of the form `{pickle, gherkinDocument, result, testCaseStartedId}`
* The first argument will be an object of the form `{pickle, gherkinDocument, result, willBeRetried, testCaseStartedId}`
* The pickle object comes from the [gherkin](https://github.com/cucumber/cucumber/tree/gherkin/v15.0.2/gherkin) library. See `testdata/good/*.pickles.ndjson` for examples of its structure.
* When using the asynchronous callback interface, have one final argument for the callback function.

Expand Down
7 changes: 6 additions & 1 deletion src/runtime/test_case_runner.ts
Expand Up @@ -175,6 +175,7 @@ export default class TestCaseRunner {

async run(): Promise<messages.TestStepResultStatus> {
for (let attempt = 0; attempt < this.maxAttempts; attempt++) {
const moreAttemptsRemaining = attempt + 1 < this.maxAttempts
this.currentTestCaseStartedId = this.newId()
const testCaseStarted: messages.Envelope = {
testCaseStarted: {
Expand All @@ -197,6 +198,9 @@ export default class TestCaseRunner {
}
if (didWeRunStepsYet) {
hookParameter.result = this.getWorstStepResult()
hookParameter.willBeRetried =
this.getWorstStepResult().status ===
messages.TestStepResultStatus.FAILED && moreAttemptsRemaining
}
return await this.runHook(
findHookDefinition(testStep.hookId, this.supportCodeLibrary),
Expand All @@ -213,9 +217,10 @@ export default class TestCaseRunner {
}
})
}

const willBeRetried =
this.getWorstStepResult().status ===
messages.TestStepResultStatus.FAILED && attempt + 1 < this.maxAttempts
messages.TestStepResultStatus.FAILED && moreAttemptsRemaining
const testCaseFinished: messages.Envelope = {
testCaseFinished: {
testCaseStartedId: this.currentTestCaseStartedId,
Expand Down
38 changes: 38 additions & 0 deletions src/runtime/test_case_runner_spec.ts
Expand Up @@ -359,6 +359,44 @@ describe('TestCaseRunner', () => {
expect(envelopes).to.eql(expected)
expect(result).to.eql(messages.TestStepResultStatus.PASSED)
})

it('should provide the correctly willBeRetried value to the hook', async () => {
// Arrange
const hookStub = sinon.stub()
const supportCodeLibrary = buildSupportCodeLibrary(
({ Given, After }) => {
let willPass = false
Given('a step', function () {
if (willPass) {
return
}
willPass = true
throw 'error' // eslint-disable-line @typescript-eslint/no-throw-literal
})
After(hookStub)
}
)
const {
gherkinDocument,
pickles: [pickle],
} = await parse({
data: ['Feature: a', 'Scenario: b', 'Given a step'].join('\n'),
uri: 'a.feature',
})

// Act
await testRunner({
gherkinDocument,
pickle,
retries: 1,
supportCodeLibrary,
})

// Assert
expect(hookStub).to.have.been.calledTwice()
expect(hookStub.args[0][0].willBeRetried).to.eq(true)
expect(hookStub.args[1][0].willBeRetried).to.eq(false)
})
})

describe('with a step when skipping', () => {
Expand Down
1 change: 1 addition & 0 deletions src/support_code_library_builder/types.ts
Expand Up @@ -15,6 +15,7 @@ export interface ITestCaseHookParameter {
gherkinDocument: messages.GherkinDocument
pickle: messages.Pickle
result?: messages.TestStepResult
willBeRetried?: boolean
testCaseStartedId: string
}

Expand Down

0 comments on commit 126772d

Please sign in to comment.