API
Playwright API Reference227 Interactive Commands

Playwright Cheatsheet

An interactive multi-column reference covering locators, actions, assertions, network mocking, test configuration, and advanced fixtures. Search, filter, toggle languages, and copy snippets instantly.

/
227 commands
Tags:
Suggestions:

Installation

Install Playwright and browsers
SETUP
playwright.ts
TYPESCRIPT
1234
npm init playwright@latest
# or install manually:
npm i -D @playwright/test
npx playwright install --with-deps
Install Playwright library (no test runner)
SETUP
playwright.ts
TYPESCRIPT
12
npm i playwright
npx playwright install --with-deps

Writing & Running

Write a basic automation script
SETUP
playwright.ts
TYPESCRIPT
1234567
import { chromium } from 'playwright';
 
const browser = await chromium.launch();
const page = await browser.newPage();
await page.goto('https://example.com');
console.log(await page.title());
await browser.close();
Write a basic test
SETUP
playwright.ts
TYPESCRIPT
123456
import { test, expect } from '@playwright/test';
 
test('has title', async ({ page }) => {
await page.goto('https://example.com');
await expect(page).toHaveTitle(/Example/);
});
Run tests
SETUP
playwright.ts
TYPESCRIPT
123
npx playwright test
npx playwright test --headed
npx playwright test --ui
Generate code from user actions
SETUP
playwright.ts
TYPESCRIPT
1
npx playwright codegen https://example.com
View test results in browser
SETUP
playwright.ts
TYPESCRIPT
1
npx playwright show-report

Launch Browsers

Launch Chromium
LAUNCH
playwright.ts
TYPESCRIPT
12
import { chromium } from 'playwright';
const browser = await chromium.launch();
Launch Firefox
LAUNCH
playwright.ts
TYPESCRIPT
12
import { firefox } from 'playwright';
const browser = await firefox.launch();
Launch WebKit
LAUNCH
playwright.ts
TYPESCRIPT
12
import { webkit } from 'playwright';
const browser = await webkit.launch();
Open browser window on launch
LAUNCH
playwright.ts
TYPESCRIPT
123
const browser = await chromium.launch({
headless: false,
});
Open devtools on launch
LAUNCH
playwright.ts
TYPESCRIPT
123
const browser = await chromium.launch({
devtools: true,
});
Slow down browser operations
LAUNCH
playwright.ts
TYPESCRIPT
123
const browser = await chromium.launch({
slowMo: class="hl-number">500, // 500ms delay between actions
});
Set custom launch timeout
LAUNCH
playwright.ts
TYPESCRIPT
123
const browser = await chromium.launch({
timeout: 60_000, // 60 seconds
});
Set custom downloads path
LAUNCH
playwright.ts
TYPESCRIPT
123
const browser = await chromium.launch({
downloadsPath: './downloads',
});

Proxy

Proxy browser traffic
LAUNCH
playwright.ts
TYPESCRIPT
12345
const browser = await chromium.launch({
proxy: {
server: 'http://proxy.com:8080',
},
});
Proxy with authentication
LAUNCH
playwright.ts
TYPESCRIPT
1234567
const browser = await chromium.launch({
proxy: {
server: 'http://proxy.com:8080',
username: 'user',
password: 'pass',
},
});
Bypass proxy for specific domains
LAUNCH
playwright.ts
TYPESCRIPT
123456
const browser = await chromium.launch({
proxy: {
server: 'http://proxy.com:8080',
bypass: '.example.com, .local',
},
});

Persistent Context

Launch with persistent user data
LAUNCH
playwright.ts
TYPESCRIPT
123
const context = await chromium.launchPersistentContext(
'./userData'
);
Configure persistent context options
LAUNCH
playwright.ts
TYPESCRIPT
12345678
const context = await chromium.launchPersistentContext(
'./userData',
{
acceptDownloads: true,
ignoreHTTPSErrors: true,
viewport: { width: class="hl-number">1920, height: class="hl-number">1080 },
}
);

Browser CLI Args

Launch with custom CLI arguments
LAUNCH
playwright.ts
TYPESCRIPT
123
const browser = await chromium.launch({
args: ['--no-sandbox', '--disable-gpu'],
});
Launch a specific browser executable
LAUNCH
playwright.ts
TYPESCRIPT
123
const browser = await chromium.launch({
executablePath: '/usr/bin/google-chrome',
});
Launch Chrome/Edge channel
LAUNCH
playwright.ts
TYPESCRIPT
123
const browser = await chromium.launch({
channel: 'chrome', // or 'msedge', 'chrome-beta'
});

Create Contexts & Pages

Create a new browser context
CONTEXT
playwright.ts
TYPESCRIPT
1
const context = await browser.newContext();
Create a new page
CONTEXT
playwright.ts
TYPESCRIPT
1
const page = await context.newPage();
Set viewport size
CONTEXT
playwright.ts
TYPESCRIPT
123
const context = await browser.newContext({
viewport: { width: class="hl-number">1920, height: class="hl-number">1080 },
});
Set custom user agent
CONTEXT
playwright.ts
TYPESCRIPT
123
const context = await browser.newContext({
userAgent: 'Mozilla/5.0 (Custom Agent)',
});
Emulate a device
CONTEXT
playwright.ts
TYPESCRIPT
12345
import { devices } from 'playwright';
const iPhone = devices['iPhone 14'];
const context = await browser.newContext({
...iPhone,
});
Set locale and timezone
CONTEXT
playwright.ts
TYPESCRIPT
1234
const context = await browser.newContext({
locale: 'en-US',
timezoneId: 'America/New_York',
});
Emulate geolocation
CONTEXT
playwright.ts
TYPESCRIPT
1234
const context = await browser.newContext({
geolocation: { latitude: class="hl-number">40.class="hl-number">7128, longitude: -class="hl-number">74.class="hl-number">006 },
permissions: ['geolocation'],
});

Cookies & Storage

Set cookies on context
CONTEXT
playwright.ts
TYPESCRIPT
123456
await context.addCookies([{
name: 'session',
value: 'abc123',
domain: '.example.com',
path: '/',
}]);
Get cookies from context
CONTEXT
playwright.ts
TYPESCRIPT
12
const cookies = await context.cookies();
console.log(cookies);
Clear all cookies
CONTEXT
playwright.ts
TYPESCRIPT
1
await context.clearCookies();
Save storage state to file
CONTEXT
playwright.ts
TYPESCRIPT
123
await context.storageState({
path: './auth-state.json',
});
Load storage state from file
CONTEXT
playwright.ts
TYPESCRIPT
123
const context = await browser.newContext({
storageState: './auth-state.json',
});

Permissions & HTTP

Grant browser permissions
CONTEXT
playwright.ts
TYPESCRIPT
1234
await context.grantPermissions(
['geolocation', 'notifications'],
{ origin: 'https://example.com' }
);
Set HTTP credentials
CONTEXT
playwright.ts
TYPESCRIPT
123456
const context = await browser.newContext({
httpCredentials: {
username: 'admin',
password: 'secret',
},
});
Send extra HTTP headers
CONTEXT
playwright.ts
TYPESCRIPT
1234
await context.setExtraHTTPHeaders({
'X-Custom-Header': 'value',
'Authorization': 'Bearer token123',
});
Emulate offline mode
CONTEXT
playwright.ts
TYPESCRIPT
123
const context = await browser.newContext({
offline: true,
});
Close context and browser
CONTEXT
playwright.ts
TYPESCRIPT
12
await context.close();
await browser.close();

Page Navigation

Navigate to URL
NAVIGATE
playwright.ts
TYPESCRIPT
1
await page.goto('https://example.com');
Navigate and wait for network idle
NAVIGATE
playwright.ts
TYPESCRIPT
123
await page.goto('https://example.com', {
waitUntil: 'networkidle',
});
Navigate and wait for DOM content loaded
NAVIGATE
playwright.ts
TYPESCRIPT
123
await page.goto('https://example.com', {
waitUntil: 'domcontentloaded',
});
Navigate with custom timeout
NAVIGATE
playwright.ts
TYPESCRIPT
123
await page.goto('https://example.com', {
timeout: 30_000,
});
Go back in history
NAVIGATE
playwright.ts
TYPESCRIPT
1
await page.goBack();
Go forward in history
NAVIGATE
playwright.ts
TYPESCRIPT
1
await page.goForward();
Reload the page
NAVIGATE
playwright.ts
TYPESCRIPT
1
await page.reload();

Wait States

Wait for URL to match
NAVIGATE
playwright.ts
TYPESCRIPT
1
await page.waitForURL('**/dashboard');
Wait for URL with regex
NAVIGATE
playwright.ts
TYPESCRIPT
1
await page.waitForURL(/.*\/login/);
Wait for load state
NAVIGATE
playwright.ts
TYPESCRIPT
1
await page.waitForLoadState('networkidle');
Wait for element to appear
NAVIGATE
playwright.ts
TYPESCRIPT
1
await page.waitForSelector('#dashboard');
Wait for fixed time (anti-pattern)
NAVIGATE
playwright.ts
TYPESCRIPT
1
await page.waitForTimeout(class="hl-number">2000); // avoid in production
Wait for a custom condition
NAVIGATE
playwright.ts
TYPESCRIPT
123
await page.waitForFunction(
() => document.querySelector('#app')?.textContent?.includes('Ready')
);
Get current page URL
NAVIGATE
playwright.ts
TYPESCRIPT
12
const url = page.url();
console.log(url);
Get page title
NAVIGATE
playwright.ts
TYPESCRIPT
12
const title = await page.title();
console.log(title);

Recommended Locators

These locators are resilient and tied to user-facing attributes.

Get by ARIA role
LOCATOR
playwright.ts
TYPESCRIPT
123
const btn = page.getByRole('button', { name: 'Submit' });
const nav = page.getByRole('navigation');
const heading = page.getByRole('heading', { level: class="hl-number">1 });
Get by text content
LOCATOR
playwright.ts
TYPESCRIPT
12
const el = page.getByText('Welcome back');
const exact = page.getByText('Welcome', { exact: true });
Get by label text
LOCATOR
playwright.ts
TYPESCRIPT
12
const email = page.getByLabel('Email Address');
await email.fill('user@example.com');
Get by placeholder text
LOCATOR
playwright.ts
TYPESCRIPT
12
const search = page.getByPlaceholder('Search...');
await search.fill('Playwright');
Get by title attribute
LOCATOR
playwright.ts
TYPESCRIPT
1
const el = page.getByTitle('Close dialog');
Get by alt text
LOCATOR
playwright.ts
TYPESCRIPT
12
const logo = page.getByAltText('Company Logo');
await expect(logo).toBeVisible();
Get by data-testid
LOCATOR
playwright.ts
TYPESCRIPT
12
const card = page.getByTestId('user-profile');
await expect(card).toBeVisible();

CSS & XPath Selectors

Locate by CSS selector
LOCATOR
playwright.ts
TYPESCRIPT
123
const el = page.locator('.card-header');
const byId = page.locator('#main-nav');
const byAttr = page.locator('[data-type=___STRING_0___]');
Locate by XPath
LOCATOR
playwright.ts
TYPESCRIPT
1
const el = page.locator('xpath=//button[@type="submit"]');
Locate with text filter
LOCATOR
playwright.ts
TYPESCRIPT
123
const card = page.locator('.card', {
hasText: 'Premium Plan',
});
Locate with child filter
LOCATOR
playwright.ts
TYPESCRIPT
123
const row = page.locator('tr', {
has: page.locator('td', { hasText: 'Active' }),
});

Filtering & Chaining

Filter locator results
LOCATOR
playwright.ts
TYPESCRIPT
123
const row = page.locator('tr')
.filter({ hasText: 'Jane Doe' });
await row.getByRole('button', { name: 'Edit' }).click();
Filter by child locator
LOCATOR
playwright.ts
TYPESCRIPT
123
const row = page.locator('tr').filter({
has: page.getByRole('button', { name: 'Delete' }),
});
Filter with NOT condition
LOCATOR
playwright.ts
TYPESCRIPT
123
const rows = page.locator('tr').filter({
hasNot: page.locator('.disabled'),
});
Get first / last / nth element
LOCATOR
playwright.ts
TYPESCRIPT
1234
const items = page.locator('.item');
await items.first().click();
await items.last().click();
await items.nth(class="hl-number">2).click();
Count matching elements
LOCATOR
playwright.ts
TYPESCRIPT
12
const count = await page.locator('.item').count();
console.log(`Found ${count} items`);
Combine locators with AND / OR
LOCATOR
playwright.ts
TYPESCRIPT
12345
// AND — must match both
const el = page.getByRole('button').and(page.getByText('Save'));
 
// OR — match either
const el2 = page.getByRole('button').or(page.getByRole('link'));

Mouse Actions

Click an element
ACTION
playwright.ts
TYPESCRIPT
1
await page.getByRole('button', { name: 'Submit' }).click();
Double-click an element
ACTION
playwright.ts
TYPESCRIPT
1
await page.locator('.text-editor').dblclick();
Right-click (context menu)
ACTION
playwright.ts
TYPESCRIPT
1
await page.locator('.canvas').click({ button: 'right' });
Click at specific position
ACTION
playwright.ts
TYPESCRIPT
123
await page.locator('#map').click({
position: { x: class="hl-number">100, y: class="hl-number">200 },
});
Click with modifier keys
ACTION
playwright.ts
TYPESCRIPT
123
await page.locator('a').click({
modifiers: ['Control'], // or 'Shift', 'Alt', 'Meta'
});
Hover over an element
ACTION
playwright.ts
TYPESCRIPT
1
await page.locator('#menu-trigger').hover();

Text Input

Fill an input field
ACTION
playwright.ts
TYPESCRIPT
1
await page.getByLabel('Username').fill('testuser');
Clear an input field
ACTION
playwright.ts
TYPESCRIPT
1
await page.getByLabel('Username').clear();
Type character-by-character
ACTION
playwright.ts
TYPESCRIPT
123
await page.locator('#search').pressSequentially('React', {
delay: class="hl-number">100, // ms between keystrokes
});
Press a specific key
ACTION
playwright.ts
TYPESCRIPT
12
await page.locator('#search').press('Enter');
await page.locator('body').press('Control+a');
Get current input value
ACTION
playwright.ts
TYPESCRIPT
12
const value = await page.getByLabel('Email').inputValue();
console.log(value);

Form Controls

Check / uncheck a checkbox
ACTION
playwright.ts
TYPESCRIPT
12
await page.getByLabel('Agree to terms').check();
await page.getByLabel('Subscribe').uncheck();
Select a radio button
ACTION
playwright.ts
TYPESCRIPT
1
await page.getByLabel('Monthly').check();
Select dropdown option
ACTION
playwright.ts
TYPESCRIPT
123456
// By value
await page.locator('select#color').selectOption('blue');
// By label
await page.locator('select#country').selectOption({ label: 'India' });
// Multiple
await page.locator('select').selectOption(['red', 'green']);
Upload files
ACTION
playwright.ts
TYPESCRIPT
12345678
await page.locator('input[type=___STRING_0___]').setInputFiles(
'data/report.pdf'
);
// Multiple files
await page.locator('input[type=___STRING_0___]').setInputFiles([
'file1.png',
'file2.png',
]);
Clear file upload
ACTION
playwright.ts
TYPESCRIPT
1
await page.locator('input[type=___STRING_0___]').setInputFiles([]);

Drag, Scroll & Focus

Drag and drop
ACTION
playwright.ts
TYPESCRIPT
123
await page.locator('#item').dragTo(
page.locator('#dropzone')
);
Scroll element into view
ACTION
playwright.ts
TYPESCRIPT
1
await page.locator('#footer').scrollIntoViewIfNeeded();
Scroll with mouse wheel
ACTION
playwright.ts
TYPESCRIPT
1
await page.mouse.wheel(class="hl-number">0, class="hl-number">500); // scroll down 500px
Focus an element
ACTION
playwright.ts
TYPESCRIPT
1
await page.locator('#input').focus();
Blur (unfocus) an element
ACTION
playwright.ts
TYPESCRIPT
1
await page.locator('#input').blur();

Element Info

Get element text content
ACTION
playwright.ts
TYPESCRIPT
12
const text = await page.locator('.card-title').textContent();
const inner = await page.locator('.card').innerText();
Get element attribute
ACTION
playwright.ts
TYPESCRIPT
1
const href = await page.locator('a.link').getAttribute('href');
Get element inner HTML
ACTION
playwright.ts
TYPESCRIPT
1
const html = await page.locator('.content').innerHTML();
Check if element is visible
ACTION
playwright.ts
TYPESCRIPT
12
const visible = await page.locator('#modal').isVisible();
const hidden = await page.locator('#loader').isHidden();
Evaluate JavaScript in page
ACTION
playwright.ts
TYPESCRIPT
1234567
const result = await page.evaluate(() => {
return document.title;
});
 
const elResult = await page.locator('#app').evaluate(
(el) => el.dataset.version
);

Keyboard

Press a key
METHOD
playwright.ts
TYPESCRIPT
123
await page.keyboard.press('Enter');
await page.keyboard.press('Control+C');
await page.keyboard.press('Meta+A'); // Cmd on Mac
Type text on keyboard
METHOD
playwright.ts
TYPESCRIPT
1
await page.keyboard.type('Hello World', { delay: class="hl-number">50 });
Hold and release a key
METHOD
playwright.ts
TYPESCRIPT
1234
await page.keyboard.down('Shift');
await page.keyboard.press('ArrowLeft');
await page.keyboard.press('ArrowLeft');
await page.keyboard.up('Shift');
Insert text (no key events)
METHOD
playwright.ts
TYPESCRIPT
1
await page.keyboard.insertText('Pasted text');

Mouse

Click at coordinates
METHOD
playwright.ts
TYPESCRIPT
123
await page.mouse.click(class="hl-number">100, class="hl-number">200);
await page.mouse.dblclick(class="hl-number">100, class="hl-number">200);
await page.mouse.click(class="hl-number">100, class="hl-number">200, { button: 'right' });
Move mouse to coordinates
METHOD
playwright.ts
TYPESCRIPT
1
await page.mouse.move(class="hl-number">100, class="hl-number">200);
Manual drag with mouse
METHOD
playwright.ts
TYPESCRIPT
1234
await page.mouse.move(class="hl-number">0, class="hl-number">0);
await page.mouse.down();
await page.mouse.move(class="hl-number">100, class="hl-number">100);
await page.mouse.up();
Scroll with mouse wheel
METHOD
playwright.ts
TYPESCRIPT
1
await page.mouse.wheel(class="hl-number">0, class="hl-number">300); // deltaX, deltaY

Touchscreen

Tap at coordinates
METHOD
playwright.ts
TYPESCRIPT
1
await page.touchscreen.tap(class="hl-number">150, class="hl-number">300);

Value Assertions

Assert strict equality
METHOD
playwright.ts
TYPESCRIPT
12
expect(class="hl-number">1 + class="hl-number">1).toBe(class="hl-number">2);
expect('hello').toBe('hello');
Assert deep equality
METHOD
playwright.ts
TYPESCRIPT
12
expect({ name: 'QA' }).toEqual({ name: 'QA' });
expect([class="hl-number">1, class="hl-number">2, class="hl-number">3]).toEqual([class="hl-number">1, class="hl-number">2, class="hl-number">3]);
Assert truthy / falsy
METHOD
playwright.ts
TYPESCRIPT
123
expect(class="hl-number">1).toBeTruthy();
expect('').toBeFalsy();
expect(null).toBeFalsy();
Assert null / undefined
METHOD
playwright.ts
TYPESCRIPT
123
expect(null).toBeNull();
expect(undefined).toBeUndefined();
expect('hello').toBeDefined();
Assert NaN
METHOD
playwright.ts
TYPESCRIPT
1
expect(NaN).toBeNaN();

Number Assertions

Assert greater / less than
METHOD
playwright.ts
TYPESCRIPT
1234
expect(class="hl-number">10).toBeGreaterThan(class="hl-number">5);
expect(class="hl-number">10).toBeGreaterThanOrEqual(class="hl-number">10);
expect(class="hl-number">5).toBeLessThan(class="hl-number">10);
expect(class="hl-number">5).toBeLessThanOrEqual(class="hl-number">5);
Assert number roughly equals
METHOD
playwright.ts
TYPESCRIPT
1
expect(class="hl-number">0.class="hl-number">1 + class="hl-number">0.class="hl-number">2).toBeCloseTo(class="hl-number">0.class="hl-number">3, class="hl-number">5);

String & Array Assertions

Assert string / array contains
METHOD
playwright.ts
TYPESCRIPT
12
expect('Hello World').toContain('World');
expect([class="hl-number">1, class="hl-number">2, class="hl-number">3]).toContain(class="hl-number">2);
Assert string matches regex
METHOD
playwright.ts
TYPESCRIPT
1
expect('hello@example.com').toMatch(/@example/);
Assert array / string length
METHOD
playwright.ts
TYPESCRIPT
12
expect([class="hl-number">1, class="hl-number">2, class="hl-number">3]).toHaveLength(class="hl-number">3);
expect('hello').toHaveLength(class="hl-number">5);
Assert object has property
METHOD
playwright.ts
TYPESCRIPT
12
expect({ name: 'QA', age: class="hl-number">25 }).toHaveProperty('name');
expect({ a: { b: class="hl-number">1 } }).toHaveProperty('a.b', class="hl-number">1);
Assert function throws
METHOD
playwright.ts
TYPESCRIPT
123
expect(() => { throw new Error('fail'); }).toThrow();
expect(() => { throw new Error('fail'); }).toThrow('fail');
expect(() => { throw new Error('fail'); }).toThrow(/fail/);

Negation & Soft

Negate any assertion
METHOD
playwright.ts
TYPESCRIPT
123
expect(class="hl-number">1).not.toBe(class="hl-number">2);
expect([]).not.toContain(class="hl-number">5);
expect('hello').not.toMatch(/world/);
Soft assertions (non-blocking)
METHOD
playwright.ts
TYPESCRIPT
12
expect.soft(class="hl-number">1).toBe(class="hl-number">2); // continues test
expect.soft('a').toBe('b'); // collects all failures
Poll until assertion passes
METHOD
playwright.ts
TYPESCRIPT
1234
await expect.poll(async () => {
const res = await page.evaluate(() => window.status);
return res;
}).toBe('ready');

Page-Level Assertions

Auto-retrying assertions that wait for the condition to be met.

Assert page title
METHOD
playwright.ts
TYPESCRIPT
12
await expect(page).toHaveTitle('Dashboard');
await expect(page).toHaveTitle(/Dashboard/);
Assert page URL
METHOD
playwright.ts
TYPESCRIPT
12
await expect(page).toHaveURL('https://example.com/dashboard');
await expect(page).toHaveURL(/.*dashboard/);
Assert page does NOT have title
METHOD
playwright.ts
TYPESCRIPT
1
await expect(page).not.toHaveTitle('Login');

Visibility & State

Assert element is visible / hidden
METHOD
playwright.ts
TYPESCRIPT
123
await expect(page.locator('#dashboard')).toBeVisible();
await expect(page.locator('#spinner')).toBeHidden();
await expect(page.locator('#modal')).not.toBeVisible();
Assert element is enabled / disabled
METHOD
playwright.ts
TYPESCRIPT
12
await expect(page.locator('#submit-btn')).toBeEnabled();
await expect(page.locator('#submit-btn')).toBeDisabled();
Assert checkbox is checked
METHOD
playwright.ts
TYPESCRIPT
12
await expect(page.getByLabel('Accept terms')).toBeChecked();
await expect(page.getByLabel('Accept terms')).not.toBeChecked();
Assert element is editable
METHOD
playwright.ts
TYPESCRIPT
1
await expect(page.locator('#name-input')).toBeEditable();
Assert element is focused
METHOD
playwright.ts
TYPESCRIPT
1
await expect(page.locator('#search')).toBeFocused();
Assert element is empty
METHOD
playwright.ts
TYPESCRIPT
1
await expect(page.locator('#output')).toBeEmpty();
Assert element is attached to DOM
METHOD
playwright.ts
TYPESCRIPT
12
await expect(page.locator('#app')).toBeAttached();
await expect(page.locator('#removed')).not.toBeAttached();

Text & Value

Assert element text
METHOD
playwright.ts
TYPESCRIPT
12
await expect(page.locator('.alert')).toHaveText('Success!');
await expect(page.locator('.alert')).toHaveText(/success/i);
Assert element contains text
METHOD
playwright.ts
TYPESCRIPT
1
await expect(page.locator('.card')).toContainText('Premium');
Assert input value
METHOD
playwright.ts
TYPESCRIPT
12
await expect(page.getByLabel('Email')).toHaveValue('user@qa.com');
await expect(page.getByLabel('Email')).toHaveValue(/qa\.com/);
Assert select has values
METHOD
playwright.ts
TYPESCRIPT
123
await expect(page.locator('select')).toHaveValues(
[/red/, /green/]
);

Attributes & Styles

Assert element attribute
METHOD
playwright.ts
TYPESCRIPT
12
await expect(page.locator('a')).toHaveAttribute('href', '/home');
await expect(page.locator('img')).toHaveAttribute('src', /logo/);
Assert element has CSS class
METHOD
playwright.ts
TYPESCRIPT
12
await expect(page.locator('.btn')).toHaveClass(/active/);
await expect(page.locator('.btn')).toHaveClass('btn btn-primary');
Assert element CSS property
METHOD
playwright.ts
TYPESCRIPT
12
await expect(page.locator('.box')).toHaveCSS('color', 'rgb(0, 0, 0)');
await expect(page.locator('.box')).toHaveCSS('display', 'flex');
Assert element ID
METHOD
playwright.ts
TYPESCRIPT
1
await expect(page.locator('.main')).toHaveId('app-root');
Assert number of elements
METHOD
playwright.ts
TYPESCRIPT
1
await expect(page.locator('.list-item')).toHaveCount(class="hl-number">5);
Assert visual screenshot
METHOD
playwright.ts
TYPESCRIPT
123
await expect(page.locator('.card')).toHaveScreenshot(
'card.png'
);

Frame Locators

Locate iframe by selector
METHOD
playwright.ts
TYPESCRIPT
12
const frame = page.frameLocator('iframe#payment');
await frame.getByLabel('Card Number').fill('4111...');
Locate nested iframes
METHOD
playwright.ts
TYPESCRIPT
1234
const inner = page
.frameLocator('#outer')
.frameLocator('#inner');
await inner.locator('#btn').click();
Get frame by URL
METHOD
playwright.ts
TYPESCRIPT
12
const frame = page.frame({ url: /api\.example/ });
await frame?.locator('#submit').click();
Get frame by name
METHOD
playwright.ts
TYPESCRIPT
12
const frame = page.frame('editor-frame');
await frame?.locator('textarea').fill('Hello');
Get all frames on page
METHOD
playwright.ts
TYPESCRIPT
12
const frames = page.frames();
console.log(`Found ${frames.length} frames`);

Handling Dialogs

Accept alert / confirm dialog
METHOD
playwright.ts
TYPESCRIPT
12345
page.on('dialog', async (dialog) => {
console.log(dialog.message());
await dialog.accept();
});
await page.getByRole('button', { name: 'Delete' }).click();
Dismiss a dialog
METHOD
playwright.ts
TYPESCRIPT
1
page.on('dialog', (dialog) => dialog.dismiss());
Fill prompt dialog
METHOD
playwright.ts
TYPESCRIPT
123
page.on('dialog', async (dialog) => {
await dialog.accept('My Input');
});
Handle dialog only once
METHOD
playwright.ts
TYPESCRIPT
1
page.once('dialog', (dialog) => dialog.accept());

Popups & New Windows

Handle popup / new tab
METHOD
playwright.ts
TYPESCRIPT
123456
const [popup] = await Promise.all([
page.waitForEvent('popup'),
page.getByRole('link', { name: 'Open' }).click(),
]);
await popup.waitForLoadState();
console.log(await popup.title());
Get all pages in context
METHOD
playwright.ts
TYPESCRIPT
12
const pages = context.pages();
console.log(`${pages.length} pages open`);

Intercepting & Mocking

Mock an API response
NETWORK
playwright.ts
TYPESCRIPT
1234567
await page.route('**/api/users', async (route) => {
await route.fulfill({
status: class="hl-number">200,
contentType: 'application/json',
body: JSON.stringify([{ name: 'QA' }]),
});
});
Abort a network request
NETWORK
playwright.ts
TYPESCRIPT
1
await page.route('**/*.{png,jpg}', (route) => route.abort());
Modify and continue a request
NETWORK
playwright.ts
TYPESCRIPT
12345678
await page.route('**/api/**', async (route) => {
await route.continue({
headers: {
...route.request().headers(),
'X-Custom': 'test',
},
});
});
Modify API response data
NETWORK
playwright.ts
TYPESCRIPT
123456
await page.route('**/api/users', async (route) => {
const response = await route.fetch();
const json = await response.json();
json.push({ name: 'Extra User' });
await route.fulfill({ json });
});
Remove route handler
NETWORK
playwright.ts
TYPESCRIPT
1
await page.unroute('**/api/users');

Waiting for Network

Wait for a network response
NETWORK
playwright.ts
TYPESCRIPT
1234
const response = await page.waitForResponse(
'**/api/users'
);
console.log(await response.json());
Wait for a network request
NETWORK
playwright.ts
TYPESCRIPT
1234
const request = await page.waitForRequest(
'**/api/submit'
);
console.log(request.postData());
Wait for download event
NETWORK
playwright.ts
TYPESCRIPT
123456
const [download] = await Promise.all([
page.waitForEvent('download'),
page.getByText('Download').click(),
]);
const path = await download.path();
console.log(path);

API Request Context

Make direct API GET request
NETWORK
playwright.ts
TYPESCRIPT
12345
const response = await page.request.get(
'https://api.example.com/users'
);
const data = await response.json();
console.log(data);
Make direct API POST request
NETWORK
playwright.ts
TYPESCRIPT
1234
const response = await page.request.post(
'https://api.example.com/users',
{ data: { name: 'QA', email: 'qa@test.com' } }
);
Assert API response
NETWORK
playwright.ts
TYPESCRIPT
123
const resp = await page.request.get('/api/health');
await expect(resp).toBeOK();
expect(resp.status()).toBe(class="hl-number">200);

Capture Screenshots

Screenshot current viewport
METHOD
playwright.ts
TYPESCRIPT
1
await page.screenshot({ path: 'viewport.png' });
Screenshot entire page
METHOD
playwright.ts
TYPESCRIPT
1234
await page.screenshot({
path: 'full.png',
fullPage: true,
});
Screenshot specific element
METHOD
playwright.ts
TYPESCRIPT
123
await page.locator('.card').screenshot({
path: 'card.png',
});
Screenshot clipped region
METHOD
playwright.ts
TYPESCRIPT
1234
await page.screenshot({
path: 'region.png',
clip: { x: class="hl-number">0, y: class="hl-number">0, width: class="hl-number">500, height: class="hl-number">300 },
});
Get screenshot as buffer
METHOD
playwright.ts
TYPESCRIPT
12
const buffer = await page.screenshot();
console.log(buffer.length);
Mask elements in screenshot
METHOD
playwright.ts
TYPESCRIPT
12345
await page.screenshot({
path: 'masked.png',
mask: [page.locator('.dynamic-ad')],
maskColor: '#FF00FF',
});

PDF Generation

Generate PDF (Chromium only)
METHOD
playwright.ts
TYPESCRIPT
12345
await page.pdf({
path: 'page.pdf',
format: 'A4',
printBackground: true,
});
PDF with custom margins
METHOD
playwright.ts
TYPESCRIPT
1234567
await page.pdf({
path: 'page.pdf',
margin: {
top: '1cm', bottom: '1cm',
left: '1.5cm', right: '1.5cm',
},
});

Video Recording

Record video of page
METHOD
playwright.ts
TYPESCRIPT
123456
const context = await browser.newContext({
recordVideo: { dir: './videos' },
});
const page = await context.newPage();
// ... do work ...
await context.close(); // video saved on close
Record video with custom size
METHOD
playwright.ts
TYPESCRIPT
123456
const context = await browser.newContext({
recordVideo: {
dir: './videos',
size: { width: class="hl-number">1280, height: class="hl-number">720 },
},
});
Get video file path
METHOD
playwright.ts
TYPESCRIPT
12
const path = await page.video()?.path();
console.log('Video saved at:', path);

Basic Configuration

Create basic config file
METHOD
playwright.ts
TYPESCRIPT
123456789
import { defineConfig } from '@playwright/test';
 
export default defineConfig({
testDir: './tests',
timeout: 30_000,
retries: class="hl-number">2,
workers: class="hl-number">4,
reporter: 'html',
});
Set base URL for relative navigation
METHOD
playwright.ts
TYPESCRIPT
12345678
export default defineConfig({
use: {
baseURL: 'http://localhost:3000',
},
});
 
// In tests:
await page.goto('/login'); // goes to localhost:3000/login
Configure retries
METHOD
playwright.ts
TYPESCRIPT
123
export default defineConfig({
retries: process.env.CI ? class="hl-number">2 : class="hl-number">0,
});
Configure parallel workers
METHOD
playwright.ts
TYPESCRIPT
1234
export default defineConfig({
workers: process.env.CI ? class="hl-number">1 : undefined, // serial in CI
fullyParallel: true,
});
Forbid test.only in CI
METHOD
playwright.ts
TYPESCRIPT
123
export default defineConfig({
forbidOnly: !!process.env.CI,
});

Projects & Browsers

Configure multiple browser projects
METHOD
playwright.ts
TYPESCRIPT
12345678910
import { defineConfig, devices } from '@playwright/test';
 
export default defineConfig({
projects: [
{ name: 'chromium', use: { ...devices['Desktop Chrome'] } },
{ name: 'firefox', use: { ...devices['Desktop Firefox'] } },
{ name: 'webkit', use: { ...devices['Desktop Safari'] } },
{ name: 'mobile', use: { ...devices['iPhone 14'] } },
],
});
Launch web server during tests
METHOD
playwright.ts
TYPESCRIPT
1234567
export default defineConfig({
webServer: {
command: 'npm run dev',
port: class="hl-number">3000,
reuseExistingServer: !process.env.CI,
},
});

Reporter

Configure test reporter
METHOD
playwright.ts
TYPESCRIPT
1234567
export default defineConfig({
reporter: [
['html', { open: 'never' }],
['json', { outputFile: 'results.json' }],
['list'],
],
});
Auto-capture screenshots on failure
METHOD
playwright.ts
TYPESCRIPT
1234567
export default defineConfig({
use: {
screenshot: 'only-on-failure',
video: 'retain-on-failure',
trace: 'retain-on-failure',
},
});
Share authentication state
METHOD
playwright.ts
TYPESCRIPT
12345
export default defineConfig({
use: {
storageState: './auth.json',
},
});

Tests & Groups

Declare a test case
METHOD
playwright.ts
TYPESCRIPT
123456
import { test, expect } from '@playwright/test';
 
test('should work', async ({ page }) => {
await page.goto('/');
await expect(page).toHaveTitle(/Home/);
});
Group tests into suites
METHOD
playwright.ts
TYPESCRIPT
1234
test.describe('Login', () => {
test('success', async ({ page }) => { /* ... */ });
test('invalid password', async ({ page }) => { /* ... */ });
});
Break test into steps
METHOD
playwright.ts
TYPESCRIPT
123456789
test('checkout flow', async ({ page }) => {
await test.step('Add item to cart', async () => {
await page.goto('/shop');
await page.getByText('Add').click();
});
await test.step('Proceed to checkout', async () => {
await page.getByText('Checkout').click();
});
});
Override options for file/group
METHOD
playwright.ts
TYPESCRIPT
1234
test.use({
viewport: { width: class="hl-number">375, height: class="hl-number">812 },
locale: 'fr-FR',
});

Hooks

Run before each test
METHOD
playwright.ts
TYPESCRIPT
123456
test.beforeEach(async ({ page }) => {
await page.goto('/login');
await page.getByLabel('Email').fill('user@test.com');
await page.getByLabel('Password').fill('pass');
await page.getByRole('button', { name: 'Login' }).click();
});
Run after each test
METHOD
playwright.ts
TYPESCRIPT
123
test.afterEach(async ({ page }) => {
await page.close();
});
Run once before all tests
METHOD
playwright.ts
TYPESCRIPT
1234
test.beforeAll(async () => {
// seed database, start server, etc.
console.log('Setup complete');
});
Run once after all tests
METHOD
playwright.ts
TYPESCRIPT
1234
test.afterAll(async () => {
// cleanup database, stop server, etc.
console.log('Teardown complete');
});

Fixtures

Use built-in page fixture
METHOD
playwright.ts
TYPESCRIPT
123456
test('test', async ({ page, context, browser, request }) => {
// page — isolated browser page
// context — isolated browser context
// browser — shared browser instance
// request — API request context
});
Create custom fixture
METHOD
playwright.ts
TYPESCRIPT
123456789101112
import { test as base } from '@playwright/test';
 
const test = base.extend<{ todoPage: any }>({
todoPage: async ({ page }, use) => {
await page.goto('/todos');
await use(page);
},
});
 
test('todo test', async ({ todoPage }) => {
await todoPage.getByText('Add').click();
});

Focus & Skip

Run only specific tests
METHOD
playwright.ts
TYPESCRIPT
123
test.only('focused test', async ({ page }) => {
// only this test runs
});
Skip a test
METHOD
playwright.ts
TYPESCRIPT
12345678
test.skip('broken test', async ({ page }) => {
// this test is skipped
});
 
// Conditional skip
test('conditional', async ({ page, browserName }) => {
test.skip(browserName === 'webkit', 'Not supported');
});
Mark test as TODO
METHOD
playwright.ts
TYPESCRIPT
123
test.fixme('need to implement', async ({ page }) => {
// will not run, marked as fixme
});
Mark test as expected to fail
METHOD
playwright.ts
TYPESCRIPT
1234
test('known bug', async ({ page }) => {
test.fail();
// test passes if it fails, fails if it passes
});
Mark test as slow (3x timeout)
METHOD
playwright.ts
TYPESCRIPT
1234
test('slow test', async ({ page }) => {
test.slow();
// runs with 3x the default timeout
});

Tags & Custom Annotations

Tag tests for filtering
METHOD
playwright.ts
TYPESCRIPT
1234567
test('smoke test @smoke', async ({ page }) => {
// run with: npx playwright test --grep @smoke
});
 
test('regression @regression @slow', async ({ page }) => {
// run with: npx playwright test --grep @regression
});
Add custom annotations
METHOD
playwright.ts
TYPESCRIPT
123456
test('annotated', async ({ page }) => {
test.info().annotations.push({
type: 'issue',
description: 'https://github.com/org/repo/issues/123',
});
});
Set custom test timeout
METHOD
playwright.ts
TYPESCRIPT
123
test('long test', async ({ page }) => {
test.setTimeout(120_000); // 2 minutes
});

Tracing

Start and stop tracing
METHOD
playwright.ts
TYPESCRIPT
1234567891011
await context.tracing.start({
screenshots: true,
snapshots: true,
sources: true,
});
 
// ... do work ...
 
await context.tracing.stop({
path: 'trace.zip',
});
View trace file
METHOD
playwright.ts
TYPESCRIPT
1
npx playwright show-trace trace.zip
Auto-record traces in config
METHOD
playwright.ts
TYPESCRIPT
12345
export default defineConfig({
use: {
trace: 'on-first-retry', // or 'on', 'retain-on-failure'
},
});

Debugging

Run tests in debug mode
METHOD
playwright.ts
TYPESCRIPT
123
PWDEBUG=class="hl-number">1 npx playwright test
# or
npx playwright test --debug
Pause execution in test
METHOD
playwright.ts
TYPESCRIPT
12345
test('debug me', async ({ page }) => {
await page.goto('/');
await page.pause(); // opens Playwright Inspector
await page.getByText('Submit').click();
});
Listen to console messages
METHOD
playwright.ts
TYPESCRIPT
1234567
page.on('console', (msg) => {
console.log(`[${msg.type()}] ${msg.text()}`);
});
 
page.on('pageerror', (err) => {
console.error('Page error:', err.message);
});
Enable verbose API logging
METHOD
playwright.ts
TYPESCRIPT
1
DEBUG=pw:api npx playwright test

CLI Commands

Run specific test file or test
METHOD
playwright.ts
TYPESCRIPT
123
npx playwright test tests/login.spec.ts
npx playwright test -g "should login"
npx playwright test --project=chromium
List all tests without running
METHOD
playwright.ts
TYPESCRIPT
1
npx playwright test --list
Update snapshots
METHOD
playwright.ts
TYPESCRIPT
1
npx playwright test --update-snapshots

Web Workers

Listen for new web workers
METHOD
playwright.ts
TYPESCRIPT
1234567
page.on('worker', (worker) => {
console.log('Worker created:', worker.url());
});
 
page.on('worker', (worker) => {
worker.on('close', () => console.log('Worker closed'));
});
Get all active workers
METHOD
playwright.ts
TYPESCRIPT
12
const workers = page.workers();
console.log(`${workers.length} workers active`);

WebSockets

Listen for WebSocket connections
WORKER
playwright.ts
TYPESCRIPT
123456
page.on('websocket', (ws) => {
console.log('WebSocket opened:', ws.url());
ws.on('framesent', (e) => console.log('Sent:', e.payload));
ws.on('framereceived', (e) => console.log('Recv:', e.payload));
ws.on('close', () => console.log('WebSocket closed'));
});
Wait for WebSocket message
WORKER
playwright.ts
TYPESCRIPT
123
const ws = await page.waitForEvent('websocket');
const frame = await ws.waitForEvent('framereceived');
console.log('Message:', frame.payload);

Page Events

Listen for page load events
METHOD
playwright.ts
TYPESCRIPT
12
page.on('load', () => console.log('Page loaded'));
page.on('domcontentloaded', () => console.log('DOM ready'));
Listen for page close
METHOD
playwright.ts
TYPESCRIPT
1
page.on('close', () => console.log('Page closed'));
Listen for network requests
METHOD
playwright.ts
TYPESCRIPT
1234567
page.on('request', (req) => {
console.log(`${req.method()} ${req.url()}`);
});
 
page.on('response', (res) => {
console.log(`${res.status()} ${res.url()}`);
});
Handle file chooser dialog
METHOD
playwright.ts
TYPESCRIPT
12345
const [fileChooser] = await Promise.all([
page.waitForEvent('filechooser'),
page.getByText('Upload').click(),
]);
await fileChooser.setFiles('data/report.pdf');

Evaluate & Execute

Execute JavaScript in browser context
METHOD
playwright.ts
TYPESCRIPT
123
const result = await page.evaluate(() => {
return { width: window.innerWidth, height: window.innerHeight };
});
Pass arguments to evaluate
METHOD
playwright.ts
TYPESCRIPT
12345
const user = 'QA';
const greeting = await page.evaluate(
(name) => `Hello ${name}`,
user
);
Inject script into every page
METHOD
playwright.ts
TYPESCRIPT
123456
await context.addInitScript(() => {
window.isAutomation = true;
});
 
// or from file
await context.addInitScript({ path: './inject.js' });
Expose function to page
METHOD
playwright.ts
TYPESCRIPT
123456
await page.exposeFunction('sha256', (text: string) => {
return crypto.createHash('sha256').update(text).digest('hex');
});
 
// Call from page:
// const hash = await window.sha256('hello');
Get full page HTML
METHOD
playwright.ts
TYPESCRIPT
12
const html = await page.content();
console.log(html);
Set page HTML content
METHOD
playwright.ts
TYPESCRIPT
1
await page.setContent('<h1>Hello World</h1>');