Skip to content

Common Playwright Mistakes

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.

// Mistake: no await
page.goto('/dashboard');
await expect(page.getByText('Welcome')).toBeVisible(); // flaky

// Fix
await page.goto('/dashboard');
await expect(page.getByText('Welcome')).toBeVisible();

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.