-
Notifications
You must be signed in to change notification settings - Fork 1.7k
ci(e2e): report Cypress retries in CI so flaky specs are visible #3033
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’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -17,6 +17,7 @@ chainlit.md | |
| cypress/screenshots | ||
| cypress/videos | ||
| cypress/downloads | ||
| cypress/reports | ||
|
|
||
| __pycache__ | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,63 @@ | ||
| import assert from 'node:assert/strict'; | ||
| import { test } from 'node:test'; | ||
|
|
||
| import { collectRetriedTests } from './retryReport.ts'; | ||
|
|
||
| const asTests = (tests: unknown) => | ||
| tests as CypressCommandLine.RunResult['tests']; | ||
|
|
||
| test('ignores a test that passed on its first attempt', () => { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P2: This regression test is never executed: nothing in any CI workflow or npm/pnpm script runs Prompt for AI agents |
||
| const tests = asTests([ | ||
| { | ||
| title: ['suite', 'stable test'], | ||
| state: 'passed', | ||
| attempts: [{ state: 'passed' }] | ||
| } | ||
| ]); | ||
|
|
||
| assert.deepEqual( | ||
| collectRetriedTests('cypress/e2e/example/spec.cy.ts', tests), | ||
| [] | ||
| ); | ||
| }); | ||
|
|
||
| test('reports a test that failed then passed as retried', () => { | ||
| const tests = asTests([ | ||
| { | ||
| title: ['suite', 'flaky test'], | ||
| state: 'passed', | ||
| attempts: [{ state: 'failed' }, { state: 'passed' }] | ||
| } | ||
| ]); | ||
|
|
||
| assert.deepEqual( | ||
| collectRetriedTests('cypress/e2e/example/spec.cy.ts', tests), | ||
| [ | ||
| { | ||
| spec: 'cypress/e2e/example/spec.cy.ts', | ||
| title: 'suite > flaky test', | ||
| attempts: 2 | ||
| } | ||
| ] | ||
| ); | ||
| }); | ||
|
|
||
| test('excludes a test that failed every attempt', () => { | ||
| const tests = asTests([ | ||
| { | ||
| title: ['suite', 'broken test'], | ||
| state: 'failed', | ||
| attempts: [ | ||
| { state: 'failed' }, | ||
| { state: 'failed' }, | ||
| { state: 'failed' }, | ||
| { state: 'failed' } | ||
| ] | ||
| } | ||
| ]); | ||
|
|
||
| assert.deepEqual( | ||
| collectRetriedTests('cypress/e2e/example/spec.cy.ts', tests), | ||
| [] | ||
| ); | ||
| }); | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| export interface RetriedTest { | ||
| spec: string; | ||
| title: string; | ||
| attempts: number; | ||
| } | ||
|
|
||
| /** | ||
| * A test counts as retried when at least one attempt failed but the overall | ||
| * test still passed - i.e. Cypress' `retries` config absorbed the failure. | ||
| * Tests that exhaust every retry and still fail are already visible via the | ||
| * job's exit status, so they are excluded here. | ||
| */ | ||
| export function collectRetriedTests( | ||
| specRelative: string, | ||
| tests: CypressCommandLine.RunResult['tests'] | ||
| ): RetriedTest[] { | ||
| return tests | ||
| .filter( | ||
| (test) => | ||
| test.state === 'passed' && | ||
| test.attempts.some((attempt) => attempt.state === 'failed') | ||
| ) | ||
| .map((test) => ({ | ||
| spec: specRelative, | ||
| title: test.title.join(' > '), | ||
| attempts: test.attempts.length | ||
| })); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P2: When a shard is killed before
after:spec, or retry-artifact download fails, this branch treats the incomplete collection as a clean run and overwrites an existing PR comment with “No specs needed a retry.” Reconcile to zero retries only after confirming all expected shard reports were collected; otherwise leave the previous report unchanged and surface the collection failure.Prompt for AI agents