Skip to content

Commit 0484712

Browse files
fix(test-runner): recover beforeAll-skipped tests for --last-failed (#42056)
Co-authored-by: piotrkozlowski <piotr.kozlowski@housecallpro.com>
1 parent e201234 commit 0484712

2 files changed

Lines changed: 59 additions & 2 deletions

File tree

packages/playwright/src/runner/lastRun.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
import fs from 'fs';
1818
import path from 'path';
1919

20-
import type { FullResult, Suite } from '../../types/testReporter';
20+
import type { FullResult, Suite, TestCase } from '../../types/testReporter';
2121
import type { config as commonConfig } from '../common';
2222
import type { ReporterV2 } from '../reporters/reporterV2';
2323

@@ -26,6 +26,14 @@ type LastRunInfo = {
2626
failedTests: string[];
2727
};
2828

29+
function didNotRun(test: TestCase): boolean {
30+
if (test.outcome() !== 'skipped')
31+
return false;
32+
if (test.results.some(result => result.status === 'interrupted'))
33+
return false;
34+
return !test.results.length || test.expectedStatus !== 'skipped';
35+
}
36+
2937
export class LastRunReporter implements ReporterV2 {
3038
private _lastRunFile: string | undefined;
3139
private _suite: Suite | undefined;
@@ -71,7 +79,7 @@ export class LastRunReporter implements ReporterV2 {
7179
return;
7280
const lastRunInfo: LastRunInfo = {
7381
status: result.status,
74-
failedTests: this._suite?.allTests().filter(t => !t.ok()).map(t => t.id) || [],
82+
failedTests: this._suite?.allTests().filter(t => !t.ok() || didNotRun(t)).map(t => t.id) || [],
7583
};
7684
await fs.promises.mkdir(path.dirname(this._lastRunFile), { recursive: true });
7785
await fs.promises.writeFile(this._lastRunFile, JSON.stringify(lastRunInfo, undefined, 2));

tests/playwright-test/runner.spec.ts

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -866,6 +866,55 @@ test('should run nothing with --last-failed when previous run had no failures',
866866
expect(result2.didNotRun).toBe(0);
867867
});
868868

869+
test('should run last failed tests that did not run because a beforeAll hook failed', async ({ runInlineTest }) => {
870+
const workspace = {
871+
'a.spec.js': `
872+
import fs from 'fs';
873+
import { test, expect } from '@playwright/test';
874+
test.beforeAll(() => {
875+
if (!fs.existsSync('marker.txt')) {
876+
fs.writeFileSync('marker.txt', '');
877+
throw new Error('from beforeAll');
878+
}
879+
});
880+
test('one', () => {});
881+
test('two', () => {});
882+
`
883+
};
884+
const result1 = await runInlineTest(workspace);
885+
expect(result1.exitCode).toBe(1);
886+
expect(result1.failed).toBe(1);
887+
expect(result1.didNotRun).toBe(1);
888+
889+
const result2 = await runInlineTest(workspace, {}, {}, { additionalArgs: ['--last-failed'] });
890+
expect(result2.exitCode).toBe(0);
891+
expect(result2.passed).toBe(2);
892+
expect(result2.didNotRun).toBe(0);
893+
});
894+
895+
test('should not run intentionally skipped tests with --last-failed', async ({ runInlineTest }) => {
896+
const workspace = {
897+
'a.spec.js': `
898+
import { test, expect } from '@playwright/test';
899+
test('fail', () => {
900+
expect(1).toBe(2);
901+
});
902+
test('skipped', () => {
903+
test.skip();
904+
});
905+
`
906+
};
907+
const result1 = await runInlineTest(workspace);
908+
expect(result1.exitCode).toBe(1);
909+
expect(result1.failed).toBe(1);
910+
expect(result1.skipped).toBe(1);
911+
912+
const result2 = await runInlineTest(workspace, {}, {}, { additionalArgs: ['--last-failed'] });
913+
expect(result2.exitCode).toBe(1);
914+
expect(result2.failed).toBe(1);
915+
expect(result2.skipped).toBe(0);
916+
});
917+
869918
test('should run last failed tests in a shard', async ({ runInlineTest }) => {
870919
const workspace = {
871920
'a.spec.js': `

0 commit comments

Comments
 (0)