Playwright Cheatsheet

Navigation

Use this Playwright reference while you build software engineering projects, review code for technical interview prep, or polish examples for a software engineer resume.

page.goto

await page.goto('https://example.com');
await page.goto('/relative-path');              // uses baseURL from config
await page.goto('https://example.com', { waitUntil: 'domcontentloaded' });
await page.goto('https://example.com', { waitUntil: 'networkidle' });
await page.goto('https://example.com', { waitUntil: 'commit' });  // headers received
await page.goto('https://example.com', { timeout: 10_000 });

waitUntil values

ValueWaits until
'load' (default)load event fires
'domcontentloaded'DOMContentLoaded event fires
'networkidle'≤2 active connections for ≥500 ms
'commit'HTTP response headers received

Back / forward / reload

await page.goBack();
await page.goForward();
await page.reload();
await page.reload({ waitUntil: 'domcontentloaded' });

Waiting for navigation

// Triggered by a click
await Promise.all([
  page.waitForNavigation(),         // deprecated, use waitForURL instead
  page.locator('a').click(),
]);

// Preferred
await page.locator('a').click();
await page.waitForURL('**/target-page');

// Or assert the URL
await page.locator('a').click();
await expect(page).toHaveURL('/target-page');

waitForURL

await page.waitForURL('https://example.com/success');
await page.waitForURL('**/success/**');          // glob
await page.waitForURL(/\/success/);              // regex
await page.waitForURL('**/done', {
  waitUntil: 'networkidle',
  timeout: 15_000,
});

baseURL

// playwright.config.ts
export default defineConfig({
  use: { baseURL: 'http://localhost:3000' },
});

// In tests — relative URLs work automatically
await page.goto('/login');     // resolves to http://localhost:3000/login

Current URL / title

const url   = page.url();
const title = await page.title();

Frames

// By selector
const frame = page.frameLocator('#my-iframe');

// By name or URL
const frameByName = page.frame('frame-name');
const frameByUrl  = page.frame({ url: /checkout/ });

// All frames
const frames = page.frames();

// Navigate within a frame
await frame.getByRole('button', { name: 'Submit' }).click();

// Nested iframes
const nested = page
  .frameLocator('#outer')
  .frameLocator('#inner');

Popups & new tabs

// Wait for popup opened by a click
const [popup] = await Promise.all([
  page.waitForEvent('popup'),
  page.locator('a[target="_blank"]').click(),
]);
await popup.waitForLoadState();
console.log(popup.url());

// Or use context.waitForEvent
const [newPage] = await Promise.all([
  context.waitForEvent('page'),
  page.locator('#open-tab').click(),
]);
await newPage.waitForLoadState();

Context storage state (auth persistence)

// Save storage state (cookies + localStorage) after login
await context.storageState({ path: 'auth.json' });

// Reuse in a new context
const context = await browser.newContext({
  storageState: 'auth.json',
});

// Via playwright.config.ts (all tests pre-authenticated)
export default defineConfig({
  use: { storageState: 'auth.json' },
});

Cookies

// Read cookies
const cookies = await context.cookies();
const specific = await context.cookies(['https://example.com']);

// Set cookies
await context.addCookies([{
  name: 'session',
  value: 'abc123',
  domain: 'example.com',
  path: '/',
  httpOnly: true,
  secure: true,
  sameSite: 'Lax',
  expires: Date.now() / 1000 + 3600,
}]);

// Clear cookies
await context.clearCookies();
await context.clearCookies({ name: 'session' });
await context.clearCookies({ domain: 'example.com' });

localStorage / sessionStorage

await page.evaluate(() => localStorage.setItem('token', 'abc'));
const token = await page.evaluate(() => localStorage.getItem('token'));
await page.evaluate(() => localStorage.clear());

// Initialize before page loads via context
await context.addInitScript(() => {
  localStorage.setItem('theme', 'dark');
});

Network conditions & offline mode

await context.setOffline(true);
await page.goto('/cache-test');
await context.setOffline(false);

Geolocation

const context = await browser.newContext({
  geolocation: { latitude: 37.7749, longitude: -122.4194 },
  permissions: ['geolocation'],
});

Permissions

await context.grantPermissions(['notifications']);
await context.grantPermissions(['clipboard-read'], { origin: 'https://example.com' });
await context.clearPermissions();

Extra HTTP headers

await context.setExtraHTTPHeaders({ 'X-Custom-Header': 'value' });
await page.setExtraHTTPHeaders({ Authorization: `Bearer ${token}` });

HTTP authentication

const context = await browser.newContext({
  httpCredentials: { username: 'user', password: 'pass' },
});

Dialogs (alert / confirm / prompt)

// Auto-dismiss dialogs
page.on('dialog', dialog => dialog.dismiss());

// Accept and provide value
page.on('dialog', async dialog => {
  console.log(dialog.message());  // dialog text
  console.log(dialog.type());     // 'alert' | 'confirm' | 'prompt' | 'beforeunload'
  await dialog.accept('input for prompt');
});

// One-time listener
page.once('dialog', dialog => dialog.accept());
await page.evaluate(() => alert('hello'));