How to detect flaky tests in Playwright

Playwright finds flaky tests for you once it is allowed to retry. This guide covers the setting, what the report shows, and how to count flakiness over many runs without skewing the numbers.

Updated 15 November 2026

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.

Squally's Test explorer with example data: runs, failed %, flaky %, time lost and the last 10 runs per test
Example data The Test explorer of the demo project: shows a delivery estimate needed a retry in 27.5% of its 51 runs and never failed; the next three tests failed in some of their 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

  1. Add squally-reporter to the reporters in playwright.config.ts and set the ingest key in CI.
  2. Keep retries on in CI, as above.
  3. 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.
  4. 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

See your own flaky tests

Add one reporter line to playwright.config.ts and every CI run shows up with its flaky tests and the time they cost.

Get started Read the quickstart