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.

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
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
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 code1/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
Quick check
Why don't Playwright tests usually need manual waits like setTimeout?
Go deeper
- 1Write a Playwright test covering a simple multi-page user flow.
- 2Run the same test across Chromium, Firefox and WebKit.
- 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.