Playwright is a browser automation framework for reliable end-to-end tests. This cheat sheet uses TypeScript and the Playwright test runner.
Install
# Create a new project
npm init playwright@latest
# Install browsers after cloning a project
npx playwright install
# Install browsers and OS dependencies in CI
npx playwright install --with-deps
Test structure
import { test, expect } from '@playwright/test';
test.describe('Login', () => {
test.beforeEach(async ({ page }) => {
await page.goto('/login');
});
test('signs in with valid details', async ({ page }) => {
await page.getByLabel('Email').fill('qa@example.com');
await page.getByLabel('Password').fill('secret');
await page.getByRole('button', { name: 'Sign in' }).click();
await expect(page).toHaveURL(/dashboard/);
});
});
Locator order: prefer role, label, placeholder, text and test ID. Avoid long CSS or XPath selectors.
Actions and assertions
| Task | Example |
|---|---|
| Navigate | await page.goto('/orders') |
| Click | await page.getByRole('button', { name: 'Save' }).click() |
| Fill | await page.getByLabel('Name').fill('Ana') |
| Select | await page.getByLabel('Country').selectOption('PT') |
| Upload | await page.getByLabel('File').setInputFiles('report.pdf') |
| Visible | await expect(locator).toBeVisible() |
| Text | await expect(locator).toHaveText('Saved') |
| Count | await expect(page.getByRole('row')).toHaveCount(5) |
| API response | expect(response.ok()).toBeTruthy() |
Waits
Actions auto-wait for elements to be actionable. Web-first assertions retry until their condition passes or times out.
await expect(page.getByText('Complete')).toBeVisible();
await page.waitForURL('**/dashboard');
await page.waitForResponse(r => r.url().includes('/orders') && r.status() === 200);
Avoid:
page.waitForTimeout(3000). Fixed sleeps are slow and fail when the application takes longer than expected.Fixtures
Fixtures prepare reusable test state and clean it up. Built-in fixtures include page, context, browser and request.
import { test as base } from '@playwright/test';
export const test = base.extend({
signedInPage: async ({ page }, use) => {
await page.goto('/login');
// Sign in or restore authenticated state
await use(page);
},
});
Debugging
- Run with
--debugto open the inspector. - Use
--uito explore, filter and rerun tests. - Add
await page.pause()at a useful point. - Open the HTML report after a run.
- Keep traces, screenshots and videos for failed CI tests.
Commands
npx playwright test
npx playwright test login.spec.ts
npx playwright test --grep "valid details"
npx playwright test --project=chromium
npx playwright test --headed
npx playwright test --debug
npx playwright test --ui
npx playwright show-report
npx playwright show-trace trace.zip
npx playwright codegen https://example.com