Anti-Patterns
When to Use
Reference this list when a test is flaky, slow, or unexpectedly failing — most root causes trace to one of these patterns.
Decision
Ranked by how often they cause flake or wasted CI minutes:
| Rank | Anti-Pattern | Fix |
|---|---|---|
| 1 | page.waitForTimeout(2000) as the default wait |
Replace with web-first assertion or waitForResponse |
| 2 | Tests that depend on each other's state | Each test creates its own state; test.describe.serial is a smell |
| 3 | Brittle CSS selectors (.btn.btn-primary.mt-3 > span:nth-child(2)) |
Use getByRole, getByLabel, or getByTestId |
| 4 | Missing await on async calls |
Turn on eslint-plugin-playwright |
| 5 | Asserting implementation details (.has-loaded CSS class) |
Prefer user-visible: getByText('5 results') |
| 6 | Test files >500 lines / mega-test asserting 20 things | Split per journey; use test.step() |
| 7 | expect(true).toBe(false) for sad-path |
Use throw new Error('Unexpected branch') or test.fail() |
| 8 | Overusing page.evaluate() |
Most calls have a Playwright API that preserves auto-wait and trace |
| 9 | isVisible() / textContent() for assertions |
Always expect(locator) — these return immediately, no auto-retry |
| 10 | Disabling fullyParallel to "stabilize" |
Hides flake; fix locator/auth/state isolation instead |
| 11 | Committing playwright/.auth/*.json |
Leaks session cookies; gitignore |
| 12 | Trace Viewer only for failures | Open them on slow CI runs to find race conditions in green tests |
| 13 | .first() instead of .filter() |
Hides "two elements match" bugs; pair with .toHaveCount(1) |
| 14 | Mixing VR (toHaveScreenshot) and functional E2E in the same test |
Different stability requirements; keep separate |
Common Mistakes
- Wrong: Bumping
expect.timeoutto silence flake — masks real bugs. Right: Investigate the underlying race condition - Wrong:
PWDEBUG=1left on in CI — slows suite dramatically. Right: Only set in local dev - Wrong:
test.onlycommitted — CI doesn't catch it withoutforbidOnly: truein config
See Also
- Assertions — correct auto-retry usage
- Locators — resilient locator priority order
- CI Patterns —
forbidOnly, retries, artifact strategy - Debugging — finding the root cause of flake