Skip to content
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions docs/src/test-api/class-testoptions.md
Original file line number Diff line number Diff line change
Expand Up @@ -571,8 +571,8 @@ export default defineConfig({

## property: TestOptions.trace
* since: v1.10
- type: <[Object]|[TraceMode]<"off"|"on"|"retain-on-failure"|"on-first-retry"|"retain-on-first-failure"|"retain-on-failure-and-retries">>
- `mode` <[TraceMode]<"off"|"on"|"retain-on-failure"|"on-first-retry"|"on-all-retries"|"retain-on-first-failure"|"retain-on-failure-and-retries">> Trace recording mode.
- type: <[Object]|[TraceMode]<"off"|"on"|"retain-on-failure"|"on-first-retry"|"retain-on-first-failure"|"retain-on-failure-and-retries"|"retain-all-failures">>
- `mode` <[TraceMode]<"off"|"on"|"retain-on-failure"|"on-first-retry"|"on-all-retries"|"retain-on-first-failure"|"retain-on-failure-and-retries"|"retain-all-failures">> Trace recording mode.
- `attachments` ?<[boolean]> Whether to include test attachments. Defaults to true. Optional.
- `screenshots` ?<[boolean]> Whether to capture screenshots during tracing. Screenshots are used to build a timeline preview. Defaults to true. Optional.
- `snapshots` ?<[boolean]> Whether to capture DOM snapshot on every action. Defaults to true. Optional.
Expand All @@ -586,6 +586,7 @@ Whether to record trace for each test. Defaults to `'off'`.
* `'retain-on-failure'`: Record trace for each test. When test run passes, remove the recorded trace.
* `'retain-on-first-failure'`: Record trace for the first run of each test, but not for retries. When test run passes, remove the recorded trace.
* `'retain-on-failure-and-retries'`: Record trace for each test run. Retains all traces when an attempt fails.
* `'retain-all-failures'`: Record trace for each test run. Retains the trace only for attempts that failed, regardless of the final test outcome.

For more control, pass an object that specifies `mode` and trace features to enable.

Expand Down
2 changes: 1 addition & 1 deletion docs/src/test-cli-js.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ npx playwright test --ui
| `--test-list <file>` | Path to a file containing a list of tests to run. See [test list](#test-list) for details. |
| `--test-list-invert <file>` | Path to a file containing a list of tests to skip. See [test list](#test-list) for details. |
| `--timeout <timeout>` | Specify test timeout threshold in milliseconds, zero for unlimited (default: 30 seconds). |
| `--trace <mode>` | Force tracing mode, can be `on`, `off`, `on-first-retry`, `on-all-retries`, `retain-on-failure`, `retain-on-first-failure`, `retain-on-failure-and-retries`. |
| `--trace <mode>` | Force tracing mode, can be `on`, `off`, `on-first-retry`, `on-all-retries`, `retain-on-failure`, `retain-on-first-failure`, `retain-on-failure-and-retries`, `retain-all-failures`. |
| `--tsconfig <path>` | Path to a single tsconfig applicable to all imported files (default: look up tsconfig for each imported file separately). |
| `--ui` | Run tests in interactive UI mode. |
| `--ui-host <host>` | Host to serve UI on; specifying this option opens UI in a browser tab. |
Expand Down
2 changes: 1 addition & 1 deletion packages/playwright/src/program.ts
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ function addInitAgentsCommand(program: Command) {
});
}

const kTraceModes: TraceMode[] = ['on', 'off', 'on-first-retry', 'on-all-retries', 'retain-on-failure', 'retain-on-first-failure', 'retain-on-failure-and-retries'];
const kTraceModes: TraceMode[] = ['on', 'off', 'on-first-retry', 'on-all-retries', 'retain-on-failure', 'retain-on-first-failure', 'retain-on-failure-and-retries', 'retain-all-failures'];

// Note: update docs/src/test-cli-js.md when you update this, program is the source of truth.

Expand Down
5 changes: 5 additions & 0 deletions packages/playwright/src/worker/testTracing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,9 @@ export class TestTracing {
if (this._options?.mode === 'retain-on-failure-and-retries')
return true;

if (this._options?.mode === 'retain-all-failures')
return true;

return false;
}

Expand Down Expand Up @@ -168,6 +171,8 @@ export class TestTracing {
const testFailed = this._testInfo.status !== this._testInfo.expectedStatus;
if (this._options.mode === 'retain-on-failure-and-retries')
return !testFailed && this._testInfo.retry === 0;
if (this._options.mode === 'retain-all-failures')
return !testFailed;
return !testFailed && (this._options.mode === 'retain-on-failure' || this._options.mode === 'retain-on-first-failure');
}

Expand Down
4 changes: 3 additions & 1 deletion packages/playwright/types/test.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6937,6 +6937,8 @@ export interface PlaywrightWorkerOptions {
* - `'retain-on-first-failure'`: Record trace for the first run of each test, but not for retries. When test run
* passes, remove the recorded trace.
* - `'retain-on-failure-and-retries'`: Record trace for each test run. Retains all traces when an attempt fails.
* - `'retain-all-failures'`: Record trace for each test run. Retains the trace only for attempts that failed,
* regardless of the final test outcome.
*
* For more control, pass an object that specifies `mode` and trace features to enable.
*
Expand Down Expand Up @@ -6991,7 +6993,7 @@ export interface PlaywrightWorkerOptions {
}

export type ScreenshotMode = 'off' | 'on' | 'only-on-failure' | 'on-first-failure';
export type TraceMode = 'off' | 'on' | 'retain-on-failure' | 'on-first-retry' | 'on-all-retries' | 'retain-on-first-failure' | 'retain-on-failure-and-retries';
export type TraceMode = 'off' | 'on' | 'retain-on-failure' | 'on-first-retry' | 'on-all-retries' | 'retain-on-first-failure' | 'retain-on-failure-and-retries' | 'retain-all-failures';
export type VideoMode = 'off' | 'on' | 'retain-on-failure' | 'on-first-retry';
/**
* Playwright Test provides many options to configure test environment,
Expand Down
44 changes: 43 additions & 1 deletion tests/playwright-test/playwright.trace.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -386,7 +386,7 @@ test('should respect --trace', async ({ runInlineTest }, testInfo) => {
expect(fs.existsSync(testInfo.outputPath('test-results', 'a-test-1', 'trace.zip'))).toBeTruthy();
});

for (const mode of ['off', 'retain-on-failure', 'on-first-retry', 'on-all-retries', 'retain-on-first-failure', 'retain-on-failure-and-retries']) {
for (const mode of ['off', 'retain-on-failure', 'on-first-retry', 'on-all-retries', 'retain-on-first-failure', 'retain-on-failure-and-retries', 'retain-all-failures']) {
test(`trace:${mode} should not create trace zip artifact if page test passed`, async ({ runInlineTest }) => {
const result = await runInlineTest({
'a.spec.ts': `
Expand Down Expand Up @@ -1196,6 +1196,48 @@ test('trace:retain-on-failure-and-retries should keep all traces when test fails
expect(fs.existsSync(retryTracePath)).toBeTruthy();
});

test('trace:retain-all-failures should keep traces only for failed attempts when test is flaky', async ({ runInlineTest }, testInfo) => {
const result = await runInlineTest({
'a.spec.ts': `
import { test, expect } from '@playwright/test';
test('flaky', async ({ page }) => {
await page.goto('about:blank');
expect(test.info().retry).toBe(2);
});
`,
}, { trace: 'retain-all-failures', retries: 2 });

expect(result.exitCode).toBe(0);
expect(result.flaky).toBe(1);

const firstRunTracePath = testInfo.outputPath('test-results', 'a-flaky', 'trace.zip');
expect(fs.existsSync(firstRunTracePath)).toBeTruthy();
const retry1TracePath = testInfo.outputPath('test-results', 'a-flaky-retry1', 'trace.zip');
expect(fs.existsSync(retry1TracePath)).toBeTruthy();
const retry2TracePath = testInfo.outputPath('test-results', 'a-flaky-retry2', 'trace.zip');
expect(fs.existsSync(retry2TracePath)).toBeFalsy();
});

test('trace:retain-all-failures should keep all traces when test fails on every attempt', async ({ runInlineTest }, testInfo) => {
const result = await runInlineTest({
'a.spec.ts': `
import { test, expect } from '@playwright/test';
test('fail', async ({ page }) => {
await page.goto('about:blank');
expect(true).toBe(false);
});
`,
}, { trace: 'retain-all-failures', retries: 1 });

expect(result.exitCode).toBe(1);
expect(result.failed).toBe(1);

const firstRunTracePath = testInfo.outputPath('test-results', 'a-fail', 'trace.zip');
expect(fs.existsSync(firstRunTracePath)).toBeTruthy();
const retryTracePath = testInfo.outputPath('test-results', 'a-fail-retry1', 'trace.zip');
expect(fs.existsSync(retryTracePath)).toBeTruthy();
});

test('should not corrupt actions when no library trace is present', async ({ runInlineTest }) => {
const result = await runInlineTest({
'a.spec.ts': `
Expand Down
2 changes: 1 addition & 1 deletion utils/generate_types/overrides-test.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ export interface PlaywrightWorkerOptions {
}

export type ScreenshotMode = 'off' | 'on' | 'only-on-failure' | 'on-first-failure';
export type TraceMode = 'off' | 'on' | 'retain-on-failure' | 'on-first-retry' | 'on-all-retries' | 'retain-on-first-failure' | 'retain-on-failure-and-retries';
export type TraceMode = 'off' | 'on' | 'retain-on-failure' | 'on-first-retry' | 'on-all-retries' | 'retain-on-first-failure' | 'retain-on-failure-and-retries' | 'retain-all-failures';
export type VideoMode = 'off' | 'on' | 'retain-on-failure' | 'on-first-retry';
export interface PlaywrightTestOptions {
acceptDownloads: boolean;
Expand Down
Loading