Skip to content

Commit 4d28901

Browse files
authored
feat(list-reporter): add printFailuresInline option (#40875)
1 parent b4d8076 commit 4d28901

5 files changed

Lines changed: 56 additions & 4 deletions

File tree

docs/src/test-reporters-js.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ export default defineConfig({
7070
});
7171
```
7272

73-
Here is an example output in the middle of a test run. Failures will be listed at the end.
73+
Here is an example output in the middle of a test run. Failures will be listed at the end by default.
7474
```bash
7575
npx playwright test --reporter=list
7676
Running 124 tests using 6 workers
@@ -97,11 +97,22 @@ export default defineConfig({
9797
});
9898
```
9999

100+
You can print failures inline as soon as they are available instead of waiting until the end of the run:
101+
102+
```js title="playwright.config.ts"
103+
import { defineConfig } from '@playwright/test';
104+
105+
export default defineConfig({
106+
reporter: [['list', { printFailuresInline: true }]],
107+
});
108+
```
109+
100110
List report supports the following configuration options and environment variables:
101111

102112
| Environment Variable Name | Reporter Config Option| Description | Default
103113
|---|---|---|---|
104114
| `PLAYWRIGHT_LIST_PRINT_STEPS` | `printSteps` | Whether to print each step on its own line. | `false`
115+
| `PLAYWRIGHT_LIST_PRINT_FAILURES_INLINE` | `printFailuresInline` | Whether to print failure details immediately after a failed test instead of at the end. | `false`
105116
| `PLAYWRIGHT_FORCE_TTY` | | Whether to produce output suitable for a live terminal. Supports `true`, `1`, `false`, `0`, `[WIDTH]`, and `[WIDTH]x[HEIGHT]`. `[WIDTH]` and `[WIDTH]x[HEIGHT]` specifies the TTY dimensions. | `true` when terminal is in TTY mode, `false` otherwise.
106117
| `FORCE_COLOR` | | Whether to produce colored output. | `true` when terminal is in TTY mode, `false` otherwise.
107118
| `NO_COLOR` | | Whether to disable colored output ([no-color.org](https://no-color.org/)). Any non-empty value disables colors. | unset

packages/playwright/src/reporters/list.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,14 @@ class ListReporter extends TerminalReporter {
3838
private _stepIndex = new Map<TestStep, string>();
3939
private _needNewLine = false;
4040
private _printSteps: boolean;
41+
private _printFailuresInline: boolean;
42+
private _failureIndex = 0;
4143
private _paused = new Set<TestResult>();
4244

4345
constructor(options?: ListReporterOptions & CommonReporterOptions & TerminalReporterOptions) {
4446
super(options);
4547
this._printSteps = getAsBooleanFromENV('PLAYWRIGHT_LIST_PRINT_STEPS', options?.printSteps);
48+
this._printFailuresInline = getAsBooleanFromENV('PLAYWRIGHT_LIST_PRINT_FAILURES_INLINE', options?.printFailuresInline);
4649
}
4750

4851
override onBegin(suite: Suite) {
@@ -191,6 +194,15 @@ class ListReporter extends TerminalReporter {
191194
const wasPaused = this._paused.delete(result);
192195
if (!wasPaused)
193196
this._updateTestLine(test, result);
197+
if (!wasPaused && this._printFailuresInline && !this.willRetry(test) && (test.outcome() === 'flaky' || test.outcome() === 'unexpected' || result.status === 'interrupted'))
198+
this._printFailure(test);
199+
}
200+
201+
private _printFailure(test: TestCase) {
202+
this._maybeWriteNewLine();
203+
const message = '\n' + this.formatFailure(test, ++this._failureIndex) + '\n';
204+
this._updateLineCountAndNewLineFlagForOutput(message);
205+
this.screen.stdout.write(message);
194206
}
195207

196208
private _updateTestLine(test: TestCase, result: TestResult) {
@@ -290,7 +302,7 @@ class ListReporter extends TerminalReporter {
290302
override async onEnd(result: FullResult) {
291303
await super.onEnd(result);
292304
this.screen.stdout.write('\n');
293-
this.epilogue(true);
305+
this.epilogue(!this._printFailuresInline);
294306
}
295307
}
296308

packages/playwright/types/test.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import type { APIRequestContext, Browser, BrowserContext, BrowserContextOptions,
1919
export * from 'playwright-core';
2020

2121
export type BlobReporterOptions = { outputDir?: string, fileName?: string };
22-
export type ListReporterOptions = { printSteps?: boolean };
22+
export type ListReporterOptions = { printSteps?: boolean, printFailuresInline?: boolean };
2323
export type JUnitReporterOptions = { outputFile?: string, stripANSIControlSequences?: boolean, includeProjectInTestName?: boolean, includeRetries?: boolean };
2424
export type JsonReporterOptions = { outputFile?: string };
2525
export type HtmlReporterOptions = {

tests/playwright-test/reporter-list.spec.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,35 @@ for (const useIntermediateMergeReport of [false, true] as const) {
259259
expect(result.exitCode).toBe(1);
260260
});
261261

262+
test('print failures inline with option', async ({ runInlineTest }) => {
263+
const result = await runInlineTest({
264+
'playwright.config.ts': `
265+
module.exports = {
266+
reporter: [['list', { printFailuresInline: true }]],
267+
workers: 1,
268+
};
269+
`,
270+
'a.test.ts': `
271+
import { test, expect } from '@playwright/test';
272+
test('fails early', async ({}) => {
273+
expect(1).toBe(2);
274+
});
275+
test('runs later', async ({}) => {
276+
});
277+
`,
278+
});
279+
const text = result.output;
280+
const failureHeader = '1) a.test.ts:3:15 › fails early';
281+
const laterTestStatus = `${POSITIVE_STATUS_MARK} 2 a.test.ts:6:15 › runs later`;
282+
const failureIndex = text.indexOf(failureHeader);
283+
const laterTestIndex = text.indexOf(laterTestStatus);
284+
expect(failureIndex).toBeGreaterThan(-1);
285+
expect(laterTestIndex).toBeGreaterThan(failureIndex);
286+
expect(text.indexOf('Error: expect(received).toBe(expected)', failureIndex)).toBeGreaterThan(failureIndex);
287+
expect(text.indexOf(failureHeader, failureIndex + 1)).toBe(-1);
288+
expect(result.exitCode).toBe(1);
289+
});
290+
262291
test('print stdio', async ({ runInlineTest }) => {
263292
const result = await runInlineTest({
264293
'a.test.ts': `

utils/generate_types/overrides-test.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import type { APIRequestContext, Browser, BrowserContext, BrowserContextOptions,
1818
export * from 'playwright-core';
1919

2020
export type BlobReporterOptions = { outputDir?: string, fileName?: string };
21-
export type ListReporterOptions = { printSteps?: boolean };
21+
export type ListReporterOptions = { printSteps?: boolean, printFailuresInline?: boolean };
2222
export type JUnitReporterOptions = { outputFile?: string, stripANSIControlSequences?: boolean, includeProjectInTestName?: boolean, includeRetries?: boolean };
2323
export type JsonReporterOptions = { outputFile?: string };
2424
export type HtmlReporterOptions = {

0 commit comments

Comments
 (0)