Playwright: where to start and how to learn
Playwright became the web automation standard in 2023-2025. Compared to Selenium it gives you auto-wait, better debugging, native iframe and shadow DOM support. Compared to Cypress โ multi-browser, multi-tab, no same-origin restrictions. A curated set of resources to help you switch or start fresh.
Official sources (must read)
โ playwright.dev/docs/intro โ official docs. Very well written, reads like a tutorial, not a reference. โ playwright.dev/docs/best-practices โ best practices from the Playwright team. Especially the parts about web-first assertions and locators. โ playwright.dev/docs/release-notes โ whatโs new in each version. Playwright moves fast, features land almost every release.
How to start practically
- Install Playwright in a new project:
npm init playwright@latest. - Open Playwright Inspector โ it writes the first test for you:
npx playwright codegen <url>. Not perfect code, but as a starter โ fine. - Run tests with the
--uiflag:npx playwright test --uiโ graphical trace viewer. The best automated-test debugging Iโve seen.
Topics worth understanding separately
Locators and web-first assertions
The main difference from Selenium โ Locator API + expect(). Itโs not just a renamed By-selector โ it auto-retries. More in my post on auto-wait.
Page Object Pattern in TypeScript
Playwright is TS-first. Page Objects come out more natural than in Selenium:
class LoginPage {
constructor(readonly page: Page) {}
async login(email: string, password: string) {
await this.page.getByLabel('Email').fill(email);
await this.page.getByLabel('Password').fill(password);
await this.page.getByRole('button', { name: 'Sign In' }).click();
}
}
API testing through Playwright
Playwright handles not just UI but API requests โ request.post(...). Convenient when API tests need to live in the same framework.
Fixtures and test data
Declarative fixtures via test.extend โ powerful pattern. For example, if every test needs a logged-in user โ described once, used everywhere.
CI integration
Playwright understands GitHub Actions / GitLab CI natively. Parallelization, sharding, retry on flaky tests, HTML report โ all built in.
Visual regression
await expect(page).toHaveScreenshot() โ built-in pixel-perfect comparison. See my post on visual regression.
Beyond the docs
โ Playwright YouTube (@Playwrightdev) โ short 5-10 minute feature videos. Made by the Playwright team.
โ Test Automation University (catalog) โ free video courses including Playwright tutorials.
โ Awesome Playwright (GitHub list) โ curated list of resources: plugins, utilities, videos.
Beginner antipatterns
โ Using page.click('css=...') โ old API. Migrate to page.locator(...) or page.getByRole/getByText.
โ await page.waitForTimeout(2000) โ this is Thread.sleep. Breaks things in CI. Use only for debugging.
โ expect(await locator.textContent()).toBe(...) โ synchronous check without retry. Correct: await expect(locator).toHaveText('...').
What to do right now
โ If you have Selenium and it works โ donโt migrate for migrationโs sake. Add Playwright for new tests, keep the old.
โ
Run npx playwright codegen on your productโs main UX flow. Youโll get a draft E2E test.
โ
Enable trace: 'on-first-retry' in playwright.config.ts โ gives offline debugging with a timeline of every action.
More: Playwright docs, Test Automation University, Awesome Playwright.