fix(test runner): apply --last-failed after sharding (#34166)

This commit is contained in:
Dmitry Gozman 2024-12-30 18:45:49 +00:00 committed by GitHub
parent cab2bc4e2a
commit cd32d1b08c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 38 additions and 1 deletions

View File

@ -56,6 +56,7 @@ export class FullConfigInternal {
cliFailOnFlakyTests?: boolean;
cliLastFailed?: boolean;
testIdMatcher?: Matcher;
lastFailedTestIdMatcher?: Matcher;
defineConfigWasUsed = false;
globalSetups: string[] = [];

View File

@ -43,7 +43,7 @@ export class LastRunReporter implements ReporterV2 {
return;
try {
const lastRunInfo = JSON.parse(await fs.promises.readFile(this._lastRunFile, 'utf8')) as LastRunInfo;
this._config.testIdMatcher = id => lastRunInfo.failedTests.includes(id);
this._config.lastFailedTestIdMatcher = id => lastRunInfo.failedTests.includes(id);
} catch {
}
}

View File

@ -194,6 +194,10 @@ export async function createRootSuite(testRun: TestRun, errors: TestError[], sho
filterTestsRemoveEmptySuites(rootSuite, test => testsInThisShard.has(test));
}
// Explicitly apply --last-failed filter after sharding.
if (config.lastFailedTestIdMatcher)
filterByTestIds(rootSuite, config.lastFailedTestIdMatcher);
// Now prepend dependency projects without filtration.
{
// Filtering 'only' and sharding might have reduced the number of top-level projects.

View File

@ -841,3 +841,35 @@ test('should run last failed tests', async ({ runInlineTest }) => {
expect(result2.passed).toBe(0);
expect(result2.failed).toBe(1);
});
test('should run last failed tests in a shard', async ({ runInlineTest }) => {
const workspace = {
'a.spec.js': `
import { test, expect } from '@playwright/test';
test('pass-a', async () => {});
test('fail-a', async () => {
expect(1).toBe(2);
});
`,
'b.spec.js': `
import { test, expect } from '@playwright/test';
test('pass-b', async () => {});
test('fail-b', async () => {
expect(1).toBe(2);
});
`,
};
const result1 = await runInlineTest(workspace, { shard: '2/2' });
expect(result1.exitCode).toBe(1);
expect(result1.passed).toBe(1);
expect(result1.failed).toBe(1);
expect(result1.output).toContain('b.spec.js:3:11 pass-b');
expect(result1.output).toContain('b.spec.js:4:11 fail-b');
const result2 = await runInlineTest(workspace, { shard: '2/2' }, {}, { additionalArgs: ['--last-failed'] });
expect(result2.exitCode).toBe(1);
expect(result2.passed).toBe(0);
expect(result2.failed).toBe(1);
expect(result2.output).not.toContain('b.spec.js:3:11 pass-b');
expect(result2.output).toContain('b.spec.js:4:11 fail-b');
});