fix(testing): keep promoted retry results marked as interrupted in summary

Track hasPromotedResults on FileResult so printFinalSummary correctly
identifies specs with promoted pending retries as interrupted (! marker)
rather than definitively failed (✗ marker). Transient first-attempt
failures from interrupted runs no longer inflate the failed spec count.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Joe Li
2026-04-07 11:14:27 -07:00
parent 013933dff9
commit 33db206fd0
2 changed files with 42 additions and 2 deletions

View File

@@ -46,6 +46,7 @@ interface FileResult {
bufferedOutput: string[];
duration: number;
started: boolean;
hasPromotedResults: boolean;
}
interface Colors {
@@ -114,6 +115,7 @@ export default class CypressStyleReporter implements Reporter {
bufferedOutput: [],
duration: 0,
started: false,
hasPromotedResults: false,
});
this.fileOrder.push(fileKey);
}
@@ -226,6 +228,7 @@ export default class CypressStyleReporter implements Reporter {
for (const [testId, pending] of file.pendingResults) {
if (!file.results.has(testId)) {
file.results.set(testId, pending);
file.hasPromotedResults = true;
}
}
}
@@ -435,7 +438,8 @@ export default class CypressStyleReporter implements Reporter {
let passing = 0;
let failing = 0;
let skippedCount = 0;
const wasInterrupted = file.results.size < file.totalExpected;
const wasInterrupted =
file.hasPromotedResults || file.results.size < file.totalExpected;
for (const r of file.results.values()) {
if (r.outcome === 'expected' || r.outcome === 'flaky') passing += 1;
@@ -445,7 +449,7 @@ export default class CypressStyleReporter implements Reporter {
const tests = file.results.size;
totalSpecs += 1;
if (failing > 0) failedSpecs += 1;
if (failing > 0 && !wasInterrupted) failedSpecs += 1;
totalSkipped += skippedCount;
const marker = wasInterrupted

View File

@@ -859,6 +859,42 @@ test('footer counts failed specs, not individual failed tests', () => {
expect(output).not.toContain('2 of 4 failed');
});
test('promoted retry results keep spec marked as interrupted in summary', () => {
const reporter = new CypressStyleReporter();
const t1 = mockTest({
id: '1',
title: 'fails once',
file: 'tests/promoted.spec.ts',
retries: 2,
outcome: 'unexpected',
});
reporter.onBegin(mockConfig, mockSuite([t1]));
// First attempt fails (non-terminal: retry 0 !== retries 2)
reporter.onTestEnd(
t1,
mockResult({
status: 'failed',
retry: 0,
duration: 1000,
errors: [{ message: 'first fail' }],
}),
);
// Run interrupted before retry 1 — onEnd promotes pending result
reporter.onEnd({ status: 'interrupted' } as any);
const output = getStdout();
// Per-file box: promoted result shown with interrupted label
expect(output).toContain('✗ fails once');
expect(output).toContain('1 of 1 (interrupted)');
// Footer: "Run was interrupted", NOT "1 of 1 failed"
// (the failure is transient — test never exhausted its retries)
expect(output).toContain('interrupted');
expect(output).not.toContain('1 of 1 failed');
});
test('interrupted test with retries is treated as terminal, not dropped', () => {
const reporter = new CypressStyleReporter();
const t1 = mockTest({