Turn on retries
A flaky test fails and then passes on the same code. Playwright can see that only if it runs the failed test again. Retries are off by default; turn them on in playwright.config.ts:
import { defineConfig } from "@playwright/test";
export default defineConfig({
retries: process.env.CI ? 2 : 0,
});
Or for one run from the command line: npx playwright test --retries=2. The details, and how to keep retries from hiding problems: Playwright retries without hiding flaky tests.
What Playwright's report marks as flaky
After a run with retries, each test ends in one of four outcomes:
- passed: passed on the first attempt;
- flaky: failed at least once, then passed on a retry;
- failed: failed on every attempt;
- skipped: not run.
The list reporter prints a count such as 1 flaky at the end, and the HTML report has a Flaky filter. Each retry is its own attempt with its own error, so you can see what went wrong the first time.
The final attempt decides
Within one run, the last attempt decides the outcome. A test that fails twice and passes on the third attempt is flaky, not failed. A test that fails on all its attempts is failed, however many retries it had.
Squally counts the same way: a test that passed on its first try is stable in that run, one that passed after at least one retry is flaky, and one whose final attempt failed is failed, retried or not.
Flaky, failed, failing in a row
Over many runs, three patterns are worth telling apart:
- Flaky: needs a retry now and then, and passes. The share of runs tells you how often.
- Failing now and then: fails on all attempts in some runs. Often the same causes as flakiness, with a bigger effect: the run is red.
- Failing in a row: failed in each of its latest runs. That is usually a real break, not flakiness.
Squally shows each per test: Flaky % and Failed % in the Test explorer, and a Failing in a row card on the Overview for tests that failed in at least their last 3 runs.

Which of them costs the most CI time: What flaky tests cost: CI time lost to retries. How to fix them: Fixing flaky Playwright tests: causes and patterns.
CI vs. local runs
Local runs are noisy: half-written tests, a debugger left open, a dev server that was not running. Counted together with CI runs, they blur the rate. Keep them apart, or look at CI runs alone.
Squally tells them apart through its reporter: it recognizes the CI system from its environment, and a run that is not on a recognized CI is local. The filters show CI runs, local runs or both; both by default.
Sharded runs count once
With --shard=1/4, one CI run is split over four machines. When you count runs per test, those four parts are one run of the suite, not four.
Squally merges the shards of one CI run and counts them once.
Outage runs left out
Sometimes most of the suite fails at once: the staging server is down, a deploy broke the login, the CI runner lost its network. Those failures say nothing about individual tests, and counted as test failures they push every rate up.
Squally leaves such runs out of the per-test rates: a run with at least 20 tests in which more than 80% failed counts as an outage.
Whatever you count with, decide on a rule like this before you look at the numbers.
Finding them in Squally
- Add
squally-reporterto the reporters inplaywright.config.tsand set the ingest key in CI. - Keep retries on in CI, as above.
- On the Overview, the Flaky tests tile counts the tests with at least one flaky run in the period, and the Most flaky card lists the tests with the highest share of flaky runs, once a test has at least 3 runs.
- In the Test explorer, sort by Flaky % and open a test to see its runs and each attempt.
How Squally counts, in full: How Squally measures tests in the docs. How Squally's detection compares with other tools: Compare.
Questions
Does a test that fails all its retries count as flaky?
No. No attempt passed, so it failed in that run. Flaky means it failed at least once and then passed on a retry.
Does --repeat-each help?
It helps to reproduce one suspect test: npx playwright test cart.spec.ts --repeat-each=20 runs it 20 times. To find flaky tests across a whole suite it costs a lot of CI time; retries in CI catch them as they happen.
How many runs do I need before the rate means something?
More than a handful. One flaky run out of three says little; one in three over fifty runs is a pattern. Squally's Most flaky card waits for at least 3 runs per test - a floor, not a guarantee.
Keep reading
Flaky Playwright tests: the overview
Playwright retries without hiding flaky tests
How to set retries per config, project and describe block, and how to keep them from hiding problems.
Read the guide →What flaky tests cost: CI time lost to retries
Where retries and failed runs spend CI time, two honest ways to count it, and a worked example in minutes.
Read the guide →Fixing flaky Playwright tests: causes and patterns
The usual causes, from fixed waits to shared state, and the Playwright pattern that fixes each.
Read the guide →EU-hosted Playwright reporting and GDPR
What test results contain, where they are stored, the DPA, masking, retention and how to send less.
Read the guide →