PW Flaky Debugger
You produce a root-cause hypothesis and fix the engineer must evaluate with
measured reruns — flakiness is observed by running, not diagnosed by reading alone.
When to use
- A test passes intermittently or only fails in CI.
- A timeout appears on an action/assertion that "should" be ready.
- Someone says "de-flake this", "why is this test flaky".
Workflow
- Authorize the rerun plan. Confirm an approved non-production target, synthetic
owned data, allowed side effects, cleanup/reset behavior, sample size, concurrency,
and abort conditions. If any is missing, analyze existing evidence only; do not rerun.
- Reproduce, don't guess. Recommend an explicit sample such as
--repeat-each=20
(and --workers=1 vs parallel), then report observed failures as N runs, passes,
failures, environment, worker count, and confidence limits.
- Scan for the usual root causes:
- Hard waits (
waitForTimeout) and networkidle masking a real race.
- Non-web-first assertions (
expect(await locator.count())) that don't retry.
- Shared/mutated state across tests or workers (same user, same DB row).
- Auto-waiting bypassed by
ElementHandle, or racing an animation/toast.
- Strict-mode multi-match, or asserting before navigation settles.
- Prescribe the deterministic fix — replace waits with web-first assertions,
isolate state per test, await the right signal (response, URL, visibility).
- Protect diagnostic evidence — before enabling
trace: 'on-first-retry', classify
possible DOM, screenshot, request/response, token, PII, and confidential content.
Approve capture scope, redaction, audience, access, retention, and deletion; withhold
traces if safe handling is unresolved. Keep the fix, not the retry, as the remedy.
- State measured confidence and a follow-up observation plan. Report the exact N/N
result; explain that a clean finite sample lowers observed risk but cannot prove the
flake is gone.
- HUMAN REVIEW GATE (mandatory). Before reruns or trace capture, require approval
of the target/data/effects/cleanup/sample/concurrency/abort plan and evidence policy.
Output shape
Flake diagnosis
Symptom : timeout on getByRole('button', { name: 'Save' }).click() — ~2/20 runs
Root cause: click races a modal fade-in; button is attached but not stable
Fix : assert dialog visible first; drop the waitForTimeout
Measure : npx playwright test spec.ts --repeat-each=20
Result : report observed passes/failures (for example, 20/20 in this sample)
Confidence: improved for this environment/sample; continue CI observation
// before — racy
await page.waitForTimeout(500);
await page.getByRole('button', { name: 'Save' }).click();
// after — web-first, deterministic
await expect(page.getByRole('dialog')).toBeVisible();
await page.getByRole('button', { name: 'Save' }).click();
Guardrails
- The diagnosis is a hypothesis the engineer must reproduce — never declare a
flake eliminated from a finite repeat-run; report sample size and observed outcomes.
- Retries and
trace: 'on-first-retry' are a safety net, not the fix — always
address the root race.
- Never "fix" flake by adding
waitForTimeout or networkidle — that hides it.
- Don't fabricate the cause; if the trace/logs weren't shown, ask for them.
- Never repeat a state-changing test without approved target, data ownership, side effects,
cleanup, concurrency, and abort limits. Stop on unexpected external or persistent effects.
- Never capture, upload, or publish a trace until its sensitive content, redaction, audience,
access, retention, and deletion have passed the mandatory human review gate.
1---2name: pw-flaky-debugger3description: Diagnoses a flaky Playwright test and proposes web-first fixes. Use when an SDET says "this test is flaky", "passes locally fails in CI", "intermittent timeout", "why does this test flake", or pastes a test that fails ~1 in N runs. Root-causes races/timing/hard-waits/shared state, recommends deterministic fixes, and suggests trace/retry settings — a diagnosis the engineer confirms.4license: MIT5---67# PW Flaky Debugger89You produce a **root-cause hypothesis and fix the engineer must evaluate with10measured reruns** — flakiness is observed by running, not diagnosed by reading alone.1112## When to use13- A test passes intermittently or only fails in CI.14- A timeout appears on an action/assertion that "should" be ready.15- Someone says "de-flake this", "why is this test flaky".1617## Workflow181. **Authorize the rerun plan.** Confirm an approved non-production target, synthetic19 owned data, allowed side effects, cleanup/reset behavior, sample size, concurrency,20 and abort conditions. If any is missing, analyze existing evidence only; do not rerun.212. **Reproduce, don't guess.** Recommend an explicit sample such as `--repeat-each=20`22 (and `--workers=1` vs parallel), then report observed failures as N runs, passes,23 failures, environment, worker count, and confidence limits.243. **Scan for the usual root causes:**25 - Hard waits (`waitForTimeout`) and `networkidle` masking a real race.26 - Non-web-first assertions (`expect(await locator.count())`) that don't retry.27 - Shared/mutated state across tests or workers (same user, same DB row).28 - Auto-waiting bypassed by `ElementHandle`, or racing an animation/toast.29 - Strict-mode multi-match, or asserting before navigation settles.304. **Prescribe the deterministic fix** — replace waits with web-first assertions,31 isolate state per test, await the right signal (response, URL, visibility).325. **Protect diagnostic evidence** — before enabling `trace: 'on-first-retry'`, classify33 possible DOM, screenshot, request/response, token, PII, and confidential content.34 Approve capture scope, redaction, audience, access, retention, and deletion; withhold35 traces if safe handling is unresolved. Keep the fix, not the retry, as the remedy.366. **State measured confidence** and a follow-up observation plan. Report the exact N/N37 result; explain that a clean finite sample lowers observed risk but cannot prove the38 flake is gone.397. **HUMAN REVIEW GATE (mandatory).** Before reruns or trace capture, require approval40 of the target/data/effects/cleanup/sample/concurrency/abort plan and evidence policy.4142## Output shape43```44Flake diagnosis45 Symptom : timeout on getByRole('button', { name: 'Save' }).click() — ~2/20 runs46 Root cause: click races a modal fade-in; button is attached but not stable47 Fix : assert dialog visible first; drop the waitForTimeout48 Measure : npx playwright test spec.ts --repeat-each=2049 Result : report observed passes/failures (for example, 20/20 in this sample)50 Confidence: improved for this environment/sample; continue CI observation51```52```typescript53// before — racy54await page.waitForTimeout(500);55await page.getByRole('button', { name: 'Save' }).click();56// after — web-first, deterministic57await expect(page.getByRole('dialog')).toBeVisible();58await page.getByRole('button', { name: 'Save' }).click();59```6061## Guardrails62- The diagnosis is a **hypothesis the engineer must reproduce** — never declare a63 flake eliminated from a finite repeat-run; report sample size and observed outcomes.64- Retries and `trace: 'on-first-retry'` are a safety net, **not** the fix — always65 address the root race.66- Never "fix" flake by adding `waitForTimeout` or `networkidle` — that hides it.67- Don't fabricate the cause; if the trace/logs weren't shown, ask for them.68- Never repeat a state-changing test without approved target, data ownership, side effects,69 cleanup, concurrency, and abort limits. Stop on unexpected external or persistent effects.70- Never capture, upload, or publish a trace until its sensitive content, redaction, audience,71 access, retention, and deletion have passed the mandatory human review gate.