← blog
· series: Measured

Playwright 1.65 onlyFailures: Smaller Reports That Say Zero Tests Passed

160 runs of a 2,000-test suite on Playwright 1.65.1. onlyFailures cut the JSON report from 3.05 MB to 158 KB at 20 failed tests. It also cut the totals, and the durations other tools read.

Playwright 1.65 adds an onlyFailures option to the HTML, JSON and JUnit reporters, and a new failures terminal reporter. The release note says the option keeps only tests with unexpected outcomes, flaky tests and interrupted tests. I wanted three things before turning it on: how much smaller the reports get, whether the run gets faster, and what the report no longer contains.

I measured it on a 2,000-test suite. The harness and raw results are in the PoC repo.

The setup

A second script runs 8 tests with one outcome each, to see which outcomes count as a failure.

How much smaller

Report size, full and with onlyFailures. HTML is the whole report folder, which holds one attachment per failed test:

Failed testsJSONJSON onlyFailuresJUnitJUnit onlyFailuresHTMLHTML onlyFailures
02.92 MB2.8 KB222 KB102 B891 KB517 KB
203.05 MB158 KB250 KB34 KB964 KB599 KB
1003.54 MB766 KB363 KB155 KB1.14 MB773 KB
4005.38 MB3.05 MB786 KB609 KB1.73 MB1.41 MB

The saving depends on the format and on how red the run is:

Does the run get faster

Not on this suite. Median wall time over 5 runs, in seconds:

Failed testsdot onlyJSONJSON onlyFailuresHTMLHTML onlyFailures
02.472.412.522.482.41
203.703.733.673.743.71
1007.958.498.408.088.16
40024.1623.7624.2124.1424.17

The medians of a reporter and its onlyFailures twin differ by at most 0.46 seconds (JUnit at 100 failed tests, not in the table), and the sign changes from row to row. Single runs varied a lot: the slowest took just over three times the median. A difference smaller than about 5% would not show up in 5 repeats.

Loading is faster, but from a small base. I loaded each report from the last repeat 10 times: the JSON with JSON.parse in Node, the HTML in headless Chromium from a local file. Parsing the JSON report took 4.5 ms full and 0.3 ms with onlyFailures at 20 failed tests. The HTML report showed its first test after 63 ms full and 48 ms with onlyFailures.

What counts as a failure

Eight tests, one outcome each, with one retry:

TestWith onlyFailures
passesdropped
failskept
passes on retry (flaky)kept
is skippeddropped
is fixmedropped
fails as expected with test.fail()dropped
passes but is marked test.fail()kept
times outkept

All three reporters agreed. Flaky tests stay in. Skipped and fixme tests go, so the report can no longer tell you what was not run. The source also keeps interrupted tests; I did not test that.

The totals shrink too

This is the part I did not expect. The report does not only drop the test entries. Its totals count only what it kept:

FieldFullonlyFailures
JSON statsexpected 2, skipped 2, unexpected 3, flaky 1expected 0, skipped 0, unexpected 3, flaky 1
JUnit <testsuites>tests 8, failures 2, errors 1, skipped 2tests 4, failures 2, errors 1, skipped 0
HTML countersAll 6, Passed 2, Failed 3, Flaky 1, Skipped 2All 4, Passed 0, Failed 3, Flaky 1, Skipped 0

On the 2,000-test suite with 20 failed tests, the JUnit report says tests="20" and the JSON report says expected: 0. Anything that reads a pass rate from those fields now reads 0% for a run that was 99% green. A fully green run produces a JUnit file with zero test cases.

What reads the report after the run

Any tool that reads passed tests or durations from the report loses them. I tested one, which I maintain. playwright-shard-balancer builds its timings file from the durations in a JSON report. From the full report with 20 failed tests it read timings for 1,980 tests. From the onlyFailures report it read timings for 0 and exited 0. It printed 0 samples from 1 input(s), gave no warning, and wrote an empty timings file.

Two things did hold up:

The failures reporter

The new failures terminal reporter prints no progress output. It prints each failure as it happens, then a summary. On a green run it printed 21 bytes where dot printed 4 KB. With 20 failed tests it printed 26 KB where dot printed 30 KB, because the error output is nearly all of the log by then. It makes green logs quiet. It does not make red logs short.

What I'd do with it

The limits: all numbers are from one macOS machine, one Node version and one suite with no browser. Traces, screenshots and videos change what a report weighs, and I did not measure them.