Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix logFailedTestCases for RerunFormatter #2292

Merged
merged 7 commits into from
Jun 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
furiel marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ Please see [CONTRIBUTING.md](./CONTRIBUTING.md) on how to contribute to Cucumber
- New option for JUnit test suite name to be passed in `formatOptions` ([#2265](https://github.com/cucumber/cucumber-js/issues/2265))
- Include source reference in emitted messages for parameter types ([#2287](https://github.com/cucumber/cucumber-js/pull/2287))

### Fixed
- Correctly interpret retried scenarios in rerun formatter ([#2292](https://github.com/cucumber/cucumber-js/pull/2292))

## [9.1.2] - 2023-05-07
### Changed
- Only show global install warning in debug mode ([#2285](https://github.com/cucumber/cucumber-js/pull/2285))
Expand Down
58 changes: 43 additions & 15 deletions features/retry.feature
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ Feature: Retry flaky tests
Scenario: Failing
Given a failing step
"""
Given a file named "features/step_definitions/cucumber_steps.js" with:
And a file named "features/step_definitions/cucumber_steps.js" with:
"""
const {Given} = require('@cucumber/cucumber')

Expand All @@ -47,7 +47,7 @@ Feature: Retry flaky tests
Scenario: Failing
Given a failing step
"""
Given a file named "features/step_definitions/cucumber_steps.js" with:
And a file named "features/step_definitions/cucumber_steps.js" with:
"""
const {Given} = require('@cucumber/cucumber')

Expand All @@ -67,7 +67,7 @@ Feature: Retry flaky tests
Scenario: Flaky
Given a flaky step
"""
Given a file named "features/step_definitions/cucumber_steps.js" with:
And a file named "features/step_definitions/cucumber_steps.js" with:
"""
const {Given} = require('@cucumber/cucumber')

Expand Down Expand Up @@ -107,7 +107,7 @@ Feature: Retry flaky tests
Scenario: Flaky
Given a flaky step
"""
Given a file named "features/step_definitions/cucumber_steps.js" with:
And a file named "features/step_definitions/cucumber_steps.js" with:
"""
const {Given} = require('@cucumber/cucumber')

Expand Down Expand Up @@ -149,7 +149,7 @@ Feature: Retry flaky tests
Scenario: Good
Given a good step
"""
Given a file named "features/step_definitions/cucumber_steps.js" with:
And a file named "features/step_definitions/cucumber_steps.js" with:
"""
const {Given} = require('@cucumber/cucumber')

Expand Down Expand Up @@ -197,7 +197,7 @@ Feature: Retry flaky tests
Scenario: Good
Given a good step
"""
Given a file named "features/step_definitions/cucumber_steps.js" with:
And a file named "features/step_definitions/cucumber_steps.js" with:
"""
const {Given} = require('@cucumber/cucumber')

Expand Down Expand Up @@ -246,7 +246,7 @@ Feature: Retry flaky tests
Scenario: Bad
Given a bad step
"""
Given a file named "features/step_definitions/cucumber_steps.js" with:
And a file named "features/step_definitions/cucumber_steps.js" with:
"""
const {Given} = require('@cucumber/cucumber')

Expand Down Expand Up @@ -305,7 +305,7 @@ Feature: Retry flaky tests
Scenario: Failing
Given a failing step
"""
Given a file named "features/step_definitions/cucumber_steps.js" with:
And a file named "features/step_definitions/cucumber_steps.js" with:
"""
const {Given} = require('@cucumber/cucumber')

Expand All @@ -330,7 +330,7 @@ Feature: Retry flaky tests
Scenario: Flaky
Given a flaky step
"""
Given a file named "features/step_definitions/cucumber_steps.js" with:
And a file named "features/step_definitions/cucumber_steps.js" with:
"""
const {Given} = require('@cucumber/cucumber')

Expand All @@ -357,7 +357,7 @@ Feature: Retry flaky tests
Scenario: Flaky
Given a flaky step
"""
Given a file named "features/step_definitions/cucumber_steps.js" with:
And a file named "features/step_definitions/cucumber_steps.js" with:
"""
const {Given} = require('@cucumber/cucumber')

Expand Down Expand Up @@ -386,7 +386,7 @@ Feature: Retry flaky tests
Scenario: Also Flaky
Given an other flaky step
"""
Given a file named "features/step_definitions/cucumber_steps.js" with:
And a file named "features/step_definitions/cucumber_steps.js" with:
"""
const {Given} = require('@cucumber/cucumber')

Expand Down Expand Up @@ -430,7 +430,7 @@ Feature: Retry flaky tests
Scenario: Third Flaky
Given one more flaky step
"""
Given a file named "features/step_definitions/cucumber_steps.js" with:
And a file named "features/step_definitions/cucumber_steps.js" with:
"""
const {Given} = require('@cucumber/cucumber')

Expand Down Expand Up @@ -479,7 +479,7 @@ Feature: Retry flaky tests
Scenario: Flaky
Given a flaky step
"""
Given a file named "features/step_definitions/cucumber_steps.js" with:
And a file named "features/step_definitions/cucumber_steps.js" with:
"""
const {Before, After, Given, setWorldConstructor} = require('@cucumber/cucumber')

Expand Down Expand Up @@ -526,7 +526,7 @@ Feature: Retry flaky tests
Scenario: Passing
Given a passing step
"""
Given a file named "features/step_definitions/cucumber_steps.js" with:
And a file named "features/step_definitions/cucumber_steps.js" with:
"""
const {Given} = require('@cucumber/cucumber')

Expand Down Expand Up @@ -558,7 +558,7 @@ Feature: Retry flaky tests
Scenario: Passing
Given a passing step
"""
Given a file named "features/step_definitions/cucumber_steps.js" with:
And a file named "features/step_definitions/cucumber_steps.js" with:
"""
const {Given} = require('@cucumber/cucumber')

Expand All @@ -570,3 +570,31 @@ Feature: Retry flaky tests
And scenario "Failing" attempt 0 step "Given a failing step" has status "failed"
And scenario "Failing" attempt 1 step "Given a failing step" has status "failed"
And scenario "Passing" step "Given a passing step" has status "skipped"

Scenario: RerunFormatter does not report attempts that are retried
furiel marked this conversation as resolved.
Show resolved Hide resolved
Given a file named "features/a.feature" with:
"""
Feature:
Scenario: Flaky
Given a flaky step
"""
And a file named "features/step_definitions/cucumber_steps.js" with:
"""
const {Given} = require('@cucumber/cucumber')

let attemptCountdown = 2

Given(/^a flaky step$/, function() {
if (attemptCountdown == 0) {
return
}
attemptCountdown = attemptCountdown - 1
throw 'fail'
})
"""
When I run cucumber-js with `--retry 1 --format rerun`
Then it outputs the text:
"""
features/a.feature:2
"""
And it fails
49 changes: 32 additions & 17 deletions src/formatter/rerun_formatter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,12 @@ interface UriToLinesMap {
[uri: string]: number[]
}

function isFailedAttempt(worstTestStepResult: messages.TestStepResult) {
return worstTestStepResult.status !== messages.TestStepResultStatus.PASSED
}

export default class RerunFormatter extends Formatter {
private readonly separator: string
protected readonly separator: string
public static readonly documentation: string =
'Prints failing files with line numbers.'

Expand All @@ -29,31 +33,42 @@ export default class RerunFormatter extends Formatter {
this.separator = valueOrDefault(rerunOptions.separator, DEFAULT_SEPARATOR)
}

logFailedTestCases(): void {
getFailureMap(): UriToLinesMap {
const mapping: UriToLinesMap = {}
this.eventDataCollector
.getTestCaseAttempts()
.forEach(({ gherkinDocument, pickle, worstTestStepResult }) => {
if (
worstTestStepResult.status !== messages.TestStepResultStatus.PASSED
) {
const relativeUri = pickle.uri
const line =
getGherkinScenarioLocationMap(gherkinDocument)[
pickle.astNodeIds[pickle.astNodeIds.length - 1]
].line
if (doesNotHaveValue(mapping[relativeUri])) {
mapping[relativeUri] = []
.forEach(
({ gherkinDocument, pickle, worstTestStepResult, willBeRetried }) => {
if (isFailedAttempt(worstTestStepResult) && !willBeRetried) {
const relativeUri = pickle.uri
const line =
getGherkinScenarioLocationMap(gherkinDocument)[
pickle.astNodeIds[pickle.astNodeIds.length - 1]
].line
if (doesNotHaveValue(mapping[relativeUri])) {
mapping[relativeUri] = []
}
mapping[relativeUri].push(line)
}
mapping[relativeUri].push(line)
}
})
const text = Object.keys(mapping)
)

return mapping
}

formatFailedTestCases(): string {
const mapping = this.getFailureMap()

return Object.keys(mapping)
.map((uri) => {
const lines = mapping[uri]
return `${uri}:${lines.join(':')}`
})
.join(this.separator)
this.log(text)
}

logFailedTestCases(): void {
const failedTestCases = this.formatFailedTestCases()
this.log(failedTestCases)
}
}