Most Playwright pain comes from a handful of repeatable mistakes. Recognizing them early — in your code or a teammate's PR — saves weeks of flaky-suite firefighting.
Missing await
Playwright APIs return Promises. Without await, the test races ahead while navigation or clicks still run, producing errors like "element not found" or false passes when assertions run before actions finish.
Enable TypeScript strict mode and @typescript-eslint/no-floating-promises to catch unawaited calls at compile time.
The VS Code Playwright extension highlights missing awaits in many cases.
Other Frequent Mistakes
waitForTimeout(5000) → use expect() or waitForURL
cy-style chaining → Playwright is async/await
shared global state → isolated contexts per test
live API in CI → page.route() stubs
waitForTimeout masks timing bugs — replace with condition waits.
Cypress habits don't port directly — learn Playwright's async model.
Tests must not depend on execution order from other tests.
Hard-coded credentials belong in env vars or secrets, not specs.
Mistake → Fix
Quick diagnosis guide.
Symptom
Likely Fix
Random element not found
Add missing await
Passes locally, fails CI
Check env vars, traces, timeouts
Flakes on parallel run
Remove shared state; stub APIs
Slow suite
storageState auth; mock network; fewer E2E
Selector breaks often
Switch to getByRole/getByTestId
CI browser won't start
install --with-deps on Linux
Replacing waitForTimeout
Every waitForTimeout should become await expect(locator).toBeVisible(), page.waitForURL(), or page.waitForResponse(). If none apply, the test may be asserting the wrong outcome.
// Before
await page.waitForTimeout(2000);
// After
await expect(page.getByRole('status')).toHaveText('Loaded');
Fixing Order-Dependent Tests
If test B fails when run alone but passes after test A, B depends on A's side effects. Give B its own setup via beforeEach, page.route(), or storageState — never rely on file execution order.
Common Mistakes
Documenting mistakes without fixing them in the existing suite.
Increasing timeouts globally instead of fixing root causes.
Blaming Playwright for flakes caused by shared state or missing awaits.
Skipping Trace Viewer when investigating intermittent failures.
Key Takeaways
Missing await is the most common beginner bug.
Replace waitForTimeout with condition-based waits.
Isolate tests — no order dependence or shared mutable state.
Use traces and role-based locators to fix flakes permanently.
Pro Tip
Run npx playwright test --repeat-each=10 on suspicious tests locally to reproduce flakes before CI exposes them.
Continue with Playwright Cheat Sheet to build on what you learned here.