Cheat sheet
Playwright
Auto-waiting, locators, fixtures, network control, and debugging.
Core ideas
- Auto-waiting
- Actions wait for the element to be attached, visible, stable, enabled and able to receive events. You rarely need manual waits.
- Web-first assertions
- expect(locator) retries until the condition holds or times out.
await expect(page.getByRole('alert')).toHaveText('Saved');- Browser context
- An isolated profile (cookies, storage). Fast to create, so each test gets a clean one.
Locators
- getByRole
- Preferred; mirrors how users and assistive tech see the page.
page.getByRole('button', { name: 'Sign in' })- getByLabel / getByText / getByTestId
- Good alternatives. Use getByTestId when text is unstable.
- Chaining and filtering
- Narrow to a row, then act inside it.
page.getByRole('row').filter({ hasText: 'Alice' }).getByRole('button')
Speed and isolation
- Storage state
- Log in once, save the session, reuse it so tests skip the login screen.
await context.storageState({ path: 'auth.json' });- Fixtures
- Reusable setup and teardown injected into tests; compose them instead of base classes.
- Parallelism
- Files run in parallel across workers; tests in a file run in order unless configured.
Network
- Mock a response
- Intercept and fulfil to test error states you cannot trigger easily.
await page.route('**/api/orders', r => r.fulfill({ status: 500 }));- Wait for a request
- Pair the action with waitForResponse to avoid races.
Debugging
- Trace viewer
- Records steps, DOM snapshots, network and console. Open it on a failed CI run.
npx playwright show-trace trace.zip- Codegen and inspector
- Record a starting script and step through with PWDEBUG=1.
- Retries
- Use for CI noise only; track retried tests as flaky rather than hiding them.