This page documents the standard reporter implementations shipped with @playwright/test: the ReporterV2 interface contract, the TerminalReporter base class, and each concrete reporter (ListReporter, LineReporter, DotReporter, JSONReporter, JUnitReporter, GitHubReporter). For the HTML reporter specifically, see 6.1. For the blob reporter and multi-shard report merging, see 6.3.
All reporters — built-in and custom — implement the ReporterV2 interface, declared in packages/playwright/src/reporters/reporterV2.ts The interface defines a lifecycle of event callbacks that the test runner invokes during a test run.
ReporterV2 lifecycle — method call sequence:
| Method | When called |
|---|---|
onConfigure(config) | After config is resolved, before any tests run |
onBegin(suite) | The root Suite is available; test count is known |
onTestBegin(test, result) | A test attempt starts |
onStepBegin(test, result, step) | A test.step() starts |
onStepEnd(test, result, step) | A test.step() finishes |
onTestEnd(test, result) | A test attempt finishes (pass, fail, skip, timeout) |
onStdOut/onStdErr(chunk, test?, result?) | Test stdout/stderr output |
onError(error) | A fatal error outside any test |
onEnd(result) | All tests complete; FullResult.status is set |
onExit() | After everything, including post-processing |
Optional method printsToStdio(): boolean signals to the runner whether this reporter writes to stdout. When false, the runner adds a secondary terminal reporter (dot or line) to ensure some terminal output always appears.
Sources: packages/playwright/src/reporters/base.ts150-369 packages/playwright/src/reporters/json.ts29-61 packages/playwright/src/reporters/junit.ts29-97
Reporter class relationships:
Sources: packages/playwright/src/reporters/base.ts150-369 packages/playwright/src/reporters/list.ts32-250 packages/playwright/src/reporters/line.ts21-140 packages/playwright/src/reporters/dot.ts21-90 packages/playwright/src/reporters/github.ts65-150 packages/playwright/src/reporters/json.ts29-250 packages/playwright/src/reporters/junit.ts29-200
TerminalReporter (defined in packages/playwright/src/reporters/base.ts150-369) implements ReporterV2 and is the base for all terminal-output reporters. It handles:
Screen abstraction — a TerminalScreen object (screen field) carries isTTY, ttyWidth, ttyHeight, color support, and the stdout/stderr streams. Three pre-built screen objects are exported:
terminalScreen — reads actual TTY state; respects PLAYWRIGHT_FORCE_TTY and FORCE_COLOR env vars.nonTerminalScreen — non-TTY, for file-bound reporters; colors follow terminal env vars.internalScreen — always colored, non-TTY; for internal post-processing.Failure formatting — formatFailure(), formatResultFailure(), formatError(), formatTestHeader(), and formatTestTitle() produce the full terminal failure blocks including code snippets, stack traces, attachment paths, and cause chains.
Summary generation — generateSummary() classifies all tests by outcome (expected, unexpected, flaky, skipped, interrupted, didNotRun). generateSummaryMessage() renders the colored summary line. epilogue(full) calls both and optionally prints all failures and slow tests.
Slow test tracking — fileDurations map accumulates per-file durations; getSlowTests() applies reportSlowTests.threshold and reportSlowTests.max from config.
Output path resolution — resolveOutputFile() (exported from base.ts) is used by file-based reporters (JSONReporter, JUnitReporter) to handle the env-var and config-option conventions for output file paths.
resolveOutputFile() resolution priority:
Sources: packages/playwright/src/reporters/base.ts678-711
File: packages/playwright/src/reporters/list.ts
Identifier: 'list' (default locally)
ListReporter extends TerminalReporter. It assigns a sequential index to each test attempt and, in TTY mode, renders a live-updating row per test. When a test starts, it writes a pending row; when it ends, the row is updated in-place (using terminal cursor control codes) with the final status mark and duration.
Status marks:
| Mark | Meaning |
|---|---|
✓ (or ok on Windows) | Passed |
✘ (or x on Windows) | Failed |
- | Skipped |
Step rendering:
Controlled by PLAYWRIGHT_LIST_PRINT_STEPS env var or the printSteps config option (read in the constructor via getAsBooleanFromENV). When enabled, each test.step() gets its own numbered row (e.g., 1.1, 1.2). When disabled (default), the single test row updates its title to reflect the current step inline.
TTY scrolling detection:
ListReporter tracks _lastRow and _lastColumn to detect when the terminal has scrolled past the original row for a test. If so, it appends a new row instead of trying to move up to the original one, preventing display corruption.
Env vars:
| Variable | Effect |
|---|---|
PLAYWRIGHT_LIST_PRINT_STEPS | Enable per-step rows |
PLAYWRIGHT_FORCE_TTY | Force/override TTY mode and dimensions |
FORCE_COLOR | Force/override color output |
Sources: packages/playwright/src/reporters/list.ts32-260
File: packages/playwright/src/reporters/line.ts
Identifier: 'line'
LineReporter extends TerminalReporter. It maintains a single mutable terminal line showing the most recently active test. Each onTestBegin rewrites that line with [N/total] file:line › title. In TTY mode, onStepBegin/onStepEnd update the line to include the current step path.
When a test fails, LineReporter immediately prints the full failure block inline during the run (not deferred to epilogue). This is its key behavioral difference from ListReporter.
Stdout/stderr from tests is printed with a one-line erase (\u001B<FileRef file-url="https://github.com/microsoft/playwright/blob/54e92be7/1A\\u001B[2K) before it to keep the output coherent.\n\nSources#LNaN-LNaN" NaN file-path="1A\u001B[2K`) before it to keep the output coherent.\n\nSources">Hii
File: packages/playwright/src/reporters/dot.ts
Identifier: 'dot' (default on CI)
DotReporter extends TerminalReporter. It prints a single character per completed test attempt with no other progress output.
Character legend:
| Character | Meaning |
|---|---|
· (green) | Passed (expected) |
F (red) | Failed |
T (red) | Timed out |
× (gray) | Failed/timed out, will retry |
± (yellow) | Passed on retry (flaky) |
° (yellow) | Skipped |
It wraps to a new line every 80 characters to avoid very wide output. All failure detail is deferred to epilogue().
Sources: packages/playwright/src/reporters/dot.ts21-90
File: packages/playwright/src/reporters/github.ts
Identifier: 'github'
GitHubReporter extends TerminalReporter and is designed for use inside GitHub Actions. It inherits the terminal summary from TerminalReporter but also emits GitHub Actions workflow commands (::error, ::warning, ::notice) for each failure.
The GitHubLogger helper class formats these annotations. Each test failure produces a ::error file=...,line=...,col=...::message annotation pointing to the source location. Slow tests produce ::warning annotations.
Because GitHubReporter returns false from printsToStdio(), the runner adds a secondary terminal reporter alongside it, so there is still visible terminal output during the run.
Colors are forcibly disabled (noColors) because GitHub annotations do not support ANSI escape sequences.
Sources: packages/playwright/src/reporters/github.ts65-200
File: packages/playwright/src/reporters/json.ts
Identifier: 'json'
JSONReporter implements ReporterV2 directly (no TerminalReporter inheritance). It collects the full suite tree at onEnd and serializes it into a JSONReport object.
JSONReport top-level structure:
| Field | Type | Description |
|---|---|---|
config | Serialized FullConfig | Project configs, rootDir (posix), etc. |
suites | JSONReportSuite[] | File-level suites merged across projects |
errors | JSONReportError[] | Fatal errors outside any test |
stats | Object | startTime, duration, expected, skipped, unexpected, flaky |
Tests from the same file but different projects are merged into a single JSONReportSuite, with tests from each project appearing as separate JSONReportTest entries within a JSONReportSpec.
Output path resolution follows the standard resolveOutputFile('JSON', ...) pattern:
| Env Var | Config Option | Behavior |
|---|---|---|
PLAYWRIGHT_JSON_OUTPUT_FILE | outputFile (full path) | Absolute output path |
PLAYWRIGHT_JSON_OUTPUT_NAME | outputFile (base name) | Relative to output dir |
PLAYWRIGHT_JSON_OUTPUT_DIR | — | Directory for base-name output |
If no output file is configured, the JSON is printed to stdout.
When another reporter is already configured but JSON is needed for automation (e.g., in the test harness itself), you can inject the JSON reporter via the PW_TEST_REPORTER env var pointing to the reporter JS file, as done in tests/playwright-test/playwright-test-fixtures.ts147-151
Sources: packages/playwright/src/reporters/json.ts29-260
File: packages/playwright/src/reporters/junit.ts
Identifier: 'junit'
JUnitReporter implements ReporterV2 directly and produces JUnit-compatible XML. The XML structure mirrors the standard JUnit schema:
<testsuites id="" name="" tests="" failures="" skipped="" errors="" time="">
<testsuite name="file.test.js" hostname="projectName" tests="" failures="" skipped="" time="">
<testcase name="test title" classname="file.test.js" time="">
<failure type="FAILURE" message="...">...</failure> <!-- if failed -->
<skipped/> <!-- if skipped -->
<properties>
<property name="annotation:type" value="..."/> <!-- for annotations with value -->
<property name="annotation:type"><![CDATA[...]]> <!-- for annotations without value -->
</properties>
<system-out><![CDATA[...]]></system-out>
<system-err><![CDATA[...]]></system-err>
</testcase>
</testsuite>
</testsuites>
Each test retry is included as additional <failure> blocks within the same <testcase>. The hostname attribute on <testsuite> holds the Playwright project name.
Key options:
| Env Var | Config Option | Default |
|---|---|---|
PLAYWRIGHT_JUNIT_OUTPUT_FILE | outputFile | stdout |
PLAYWRIGHT_JUNIT_STRIP_ANSI | stripANSIControlSequences | false |
PLAYWRIGHT_JUNIT_INCLUDE_PROJECT_IN_TEST_NAME | includeProjectInTestName | false |
PLAYWRIGHT_JUNIT_SUITE_ID | — | '' |
PLAYWRIGHT_JUNIT_SUITE_NAME | — | '' |
Test annotations are serialized as <properties> entries. Annotations with a description value are encoded as value attributes; annotations without one use CDATA content. This is compatible with Xray JUnit extensions.
Sources: packages/playwright/src/reporters/junit.ts29-280
Reporters are specified in playwright.config.ts via TestConfig.reporter. The value can be a string shorthand or a tuple [name, options]:
Default reporter selection:
Reporters that set printsToStdio() = false (JSON when writing to file, JUnit when writing to file, GitHub) cause the runner to automatically add a secondary terminal reporter (dot on CI, line otherwise) to maintain visible progress output. This is why reporter: [['json', { outputFile: 'a.json' }]] still prints dot characters to the terminal during the run.
Sources: docs/src/test-reporters-js.md1-415 packages/playwright/src/reporters/json.ts43-45 packages/playwright/src/reporters/junit.ts52-54 packages/playwright/src/reporters/github.ts73-75
Code entities by reporter name:
Sources: packages/playwright/src/reporters/list.ts1-10 packages/playwright/src/reporters/line.ts1-10 packages/playwright/src/reporters/dot.ts1-10 packages/playwright/src/reporters/github.ts1-10 packages/playwright/src/reporters/json.ts1-10 packages/playwright/src/reporters/junit.ts1-10
All TerminalReporter subclasses call this.epilogue(full) in their onEnd override. epilogue prints:
_printFailures, which calls formatFailure for each).reportSlowTests is configured.N failed, N passed, N skipped, etc.).formatFailure in packages/playwright/src/reporters/base.ts383-461 produces the complete per-test failure block:
error.snippet), stack traces, and retry separators.playwright show-trace hint when a trace attachment is present.The kOutputSymbol symbol (on TestResult) is used by TerminalReporter.onStdOut/onStdErr to accumulate per-result stdout/stderr chunks. Terminal reporters can then replay this output alongside the failure block.
Refresh this wiki
This wiki was recently refreshed. Please wait 2 days to refresh again.