Stop 15 · TestingTopics · 5/8

Playwright

Part of the Frontend Developer Roadmap

In short

Playwright, from Microsoft, drives Chromium, Firefox and WebKit (Safari's engine) with one API. It waits for elements by itself, runs tests in parallel, and can even record your clicks as code.

A modern end-to-end testing framework (by Microsoft) supporting multiple browsers, with strong auto-waiting and parallelization — a common alternative to Cypress.

The jaadu at a travel desk ticks a toy train, bus and aeroplane with a pencil.

Think of it like this

A travel agent who checks every route

A good travel agent checks your trip on the train, the bus and the flight, so whichever you take, it works. Playwright checks your app on all three major browser engines in one run.

Watch it happen

What one await really does

goto
Click link
Add to cart
Auto-wait
Pass

1/5page.goto("/courses") opens the page using baseURL and waits for it to load.

The big ideas

What you need to know

Three engines

Test on Chromium, Firefox and WebKit. Safari bugs show up without owning a Mac.

Auto-waiting

Actions like click() wait until the element is visible and enabled. Assertions with expect retry until they pass.

User-facing locators

page.getByRole, getByLabel and getByText find elements the way users do, just like Testing Library.

Codegen and traces

codegen records your clicks as test code. The trace viewer replays a failed test step by step.

See it in code

Walk through the code

ts
1import { test, expect } from "@playwright/test";2 3test("student adds a course to the cart", async ({ page }) => {4  await page.goto("/courses"); // uses baseURL from playwright.config5  await page.getByRole("link", { name: "Frontend Bootcamp" }).click();6  await page.getByRole("button", { name: "Add to cart" }).click();7 8  await expect(page.getByTestId("cart-count")).toHaveText("1");9  await expect(page).toHaveURL(/frontend-bootcamp/);10});11 12// npx playwright test              run all tests13// npx playwright test --ui         step through tests visually14// npx playwright codegen localhost:3000   record clicks as code

1/4Each test gets a fresh page in a clean browser context.

Every await waits for the right moment by itself. No sleep calls anywhere, which is why Playwright tests tend to be less flaky.

Save yourself the pain

Common mistakes

Oops

Forgetting await before a Playwright action.

Do this instead

Every page action and expect returns a promise. Missing await makes steps race each other.

Oops

Using CSS selectors like .btn:nth-child(3).

Do this instead

Use getByRole or getByTestId. Layout and classes change, roles and labels rarely do.

Your mission

Record, then clean up

~30 min

Quick check

Why don't Playwright tests usually need manual waits like setTimeout?

Go deeper

  1. 1Write a Playwright test covering a simple multi-page user flow.
  2. 2Run the same test across Chromium, Firefox and WebKit.
  3. 3Try Playwright's codegen tool, which records your clicks into test code.

More topics at this stop

Stuck on this topic? Ask an Insider

Get 1:1 guidance from people who've walked this exact path — on the InsideEdge app.

Download
InsideEdge