Playwright 1.65: A Filter That Matches Nothing Now Fails Every Shard
1,464 runs on Playwright 1.64.1 and 1.65.1. A sharded run with zero matching tests went from all green to all red. Empty shards still pass. One flag still slips through.
Playwright 1.65 has one line in its notable changes that reads like a small tidy-up: a sharded run now fails with "No tests found" when no tests match across all shards. If your CI builds a --grep or a path filter per pull request and fans it out over a shard matrix, that line decides whether a pull request that touches no tests is green or red.
I ran the same suite on 1.64.1 and 1.65.1 to see exactly which cases changed. The harness and raw results are in the PoC repo.
The setup
- 32 spec files with one test each. The tests use no browser.
fullyParallel: trueandworkers: 1, so Playwright can put each test on any shard.@playwright/test1.64.1 and 1.65.1, on Node 24 and macOS.- 0, 1, 2, 4, 8 and 16 selected tests, picked by tag.
- 2, 4, 8 and 16 shards. Every shard is its own process, as it is in a CI matrix.
- Each cell with and without
--pass-with-no-tests, with Playwright's own split and with playwright-shard-balancer in the config.
That is 1,464 runs. I recorded the exit code of every run and the number of tests it ran. A second script runs four real filters that can match nothing.
The numbers
Zero selected tests, failed shards out of all shards:
| Version | --pass-with-no-tests | Unsharded | 2 shards | 4 shards | 8 shards | 16 shards |
|---|---|---|---|---|---|---|
| 1.64.1 | no | 1/1 | 0/2 | 0/4 | 0/8 | 0/16 |
| 1.64.1 | yes | 0/1 | 0/2 | 0/4 | 0/8 | 0/16 |
| 1.65.1 | no | 1/1 | 2/2 | 4/4 | 8/8 | 16/16 |
| 1.65.1 | yes | 0/1 | 0/2 | 0/4 | 0/8 | 0/16 |
On 1.64.1, sharding hid the error. The unsharded run failed with "No tests found" and the same filter with --shard passed on every shard. On 1.65.1 the sharded run agrees with the unsharded one: every shard fails.
No other exit code changed. A job here is one cell of the matrix with all of its shards. With 1 to 16 selected tests, all 180 jobs had 0 failed shards on both versions, even when 15 of 16 shards had no test to run. An empty shard is still fine. A whole run with no tests is not.
Which filters hit it
The same check with four filters, as shards 1/2 and 2/2, without the flag:
| Filter | 1.64.1 unsharded | 1.64.1 sharded | 1.65.1 unsharded | 1.65.1 sharded |
|---|---|---|---|---|
--grep matches nothing | fails | 0/2 fail | fails | 2/2 fail |
| Path filter matches nothing | fails | 0/2 fail | fails | 2/2 fail |
--last-failed after a green run | fails | 0/2 fail | fails | 0/2 fail |
--only-changed, no test file changed | passes | 0/2 fail | passes | 0/2 fail |
For --last-failed, the last run file from the green run was still on disk, as it is when CI restores it from a cache or an artifact.
Two results here are not in the release note:
--last-failedafter a green run still passes when sharded on 1.65.1. It ran 0 tests and exited 0 on both shards. Unsharded, the same command exits 1 with "No tests found" on both versions. The new check did not apply to this flag. Without the last run file,--last-failedran the whole suite, so this only happens when the file is restored.--only-changedwith no changed test file exited 0 in every cell, sharded or not, on both versions. It passed before the change, so it says nothing about the new rule.
The balancer
playwright-shard-balancer plans shards through Playwright's preprocess hook, so I checked whether a shard it leaves empty trips the new rule. It does not. Version 0.1.3 gave the same exit code as Playwright's split in every cell: all shards fail on a zero-test selection, and none fail when at least one test is selected. The balancer did plan differently: it left a different number of shards empty in 36 of the paired jobs.
What I'd change in CI
- If a filter can legitimately match nothing, such as a docs-only pull request, add
--pass-with-no-teststo the sharded command. It turned every cell green on both versions. - The flag cannot tell a docs-only pull request from a broken filter. Both select nothing and both pass. If an empty selection should never happen in your pipeline, leave the flag off: on 1.65 that mistake fails the build instead of passing on every shard.
- Check your sharded jobs before you upgrade. A job that was green on 1.64 with no tests to run is red on 1.65.
- Do not use the exit code of a sharded
--last-failedjob as proof that tests ran. With a restored last run file from a green run, it ran nothing and exited 0.