10 Playwright Best Practices That Actually Matter in 2026
Battle-tested Playwright best practices: locators, fixtures, parallelism, test data, auth, retries, and the rules that keep large suites fast and reliable.
· 10 min read
Playwright is forgiving — you can write bad tests and they will mostly pass. The teams whose suites stay green at 1,000+ tests follow a small number of disciplined rules. Here are the ten that matter most in 2026.
1. Use role-based locators, not CSS
Prefer `page.getByRole('button', { name: 'Save' })` over `page.locator('.btn-primary')`. Role locators are stable across CSS refactors and double as accessibility checks. CSS locators rot the moment a designer renames a class.
2. Embrace web-first assertions
Use `await expect(locator).toBeVisible()`, not `expect(await locator.isVisible()).toBe(true)`. The former auto-waits up to your timeout; the latter is a snapshot in time and is the #1 source of flakiness.
3. Never use sleep()
`page.waitForTimeout(1000)` is a code smell. Wait for the actual signal — a network response, an element appearing, a URL change. Playwright's waiting primitives cover every realistic case.
4. Use fixtures for setup, not beforeEach
Custom fixtures are per-test, declarative, and self-cleaning. `beforeEach` is global and stateful. Migrate over time and your tests get smaller and clearer.
5. Centralize test data
Hardcoded credentials and inline JSON fixtures rot. Store the values your suite depends on — logins, IDs, payloads — in a hosted catalog like TestAssets and pull them at runtime via REST API. One source of truth across automation and manual QA.
6. Log in once, not in every test
Use `globalSetup` and `storageState` to authenticate once and reuse the session. Tests that exercise the actual login flow are fine — but every other test should start already logged in.
7. Run in parallel from day one
Set `workers: 4` (or higher) in your config and build for isolation from the start. Each test should set up the state it needs, not depend on other tests. Retrofitting parallel-safety later is painful.
8. Quarantine flaky tests within 24 hours
When a test goes flaky, mark it `test.fixme` or move it to a quarantine project, file a ticket, and unblock the main suite. Letting a flaky test stay green-ish destroys trust in the entire suite.
9. Use trace viewer in CI
Configure `trace: 'on-first-retry'` in your CI config. When a test fails, the trace file gives you a frame-by-frame replay of what the browser did, what the network looked like, and what the DOM was at every step. Debugging time drops 10x.
10. Keep the suite small and ruthless
An E2E suite of 50 tests that everyone trusts is worth more than 500 tests that nobody runs. Aggressively delete tests that no longer earn their place.