automationplaywrightlearning

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

  1. Install Playwright in a new project: npm init playwright@latest.
  2. Open Playwright Inspector β€” it writes the first test for you: npx playwright codegen <url>. Not perfect code, but as a starter β€” fine.
  3. Run tests with the --ui flag: 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.