Playwright Cheat Sheet
Complete reference guide for Playwright with interactive examples and live playground links
Click on any section to jump directly to it
Getting Started
Installation
Install Playwright using your preferred package manager
npm init playwright@latest
# or
yarn create playwright
# or
pnpm create playwright
Basic Test Structure
Basic test structure with navigation and assertions
import { test, expect } from '@playwright/test';
test('basic test example', async ({ page }) => {
// Navigate to a website
await page.goto('https://example.com');
// Assert page title
await expect(page).toHaveTitle(/Example Domain/);
});
Common Test Patterns
Page Navigation & Assertions
Common patterns for page navigation and assertions
import { test, expect } from '@playwright/test';
test('page navigation and assertions', async ({ page }) => {
// Navigate to the target website
await page.goto('https://your-app.com');
// Check page title using regex
await expect(page).toHaveTitle(/Your App/);
// Check exact page title
await expect(page).toHaveTitle('Home | Your App');
// Check if element is visible
await expect(page.getByRole('heading', { name: 'Welcome' })).toBeVisible();
});
Form Interactions
Handling form submissions and interactions
import { test, expect } from '@playwright/test';
test('form submission', async ({ page }) => {
await page.goto('https://your-app.com/login');
// Fill in form fields
await page.getByLabel('Email').fill('user@example.com');
await page.getByLabel('Password').fill('password123');
// Click submit button
await page.getByRole('button', { name: 'Sign in' }).click();
// Assert successful login
await expect(page.getByText('Welcome back')).toBeVisible();
});
Selectors & Locators
Common Selectors
Different ways to select elements in Playwright
// By role (recommended)
// <button>Submit</button>
await page.getByRole('button', { name: 'Submit' }).click();
// By text content
// <span>Click me</span>
await page.getByText('Click me').click();
// By label
// <label for="username">Username</label>
// <input id="username" type="text">
await page.getByLabel('Username').fill('john');
// By placeholder
// <input type="email" placeholder="Enter email">
await page.getByPlaceholder('Enter email').fill('test@example.com');
// By test ID
// <button data-testid="submit-button">Submit</button>
await page.getByTestId('submit-button').click();
CSS & XPath Selectors
Using CSS and XPath selectors
// CSS selector
// <button class="submit-button">Submit</button>
await page.locator('.submit-button').click();
// XPath
// <button>Submit Form</button>
await page.locator('//button[contains(text(), "Submit")]').click();
// Multiple selectors
// <button>Submit Form</button>
await page.locator('button:has-text("Submit")').click();
// Complex CSS selectors
// <div class="form">
// <input type="text" class="username">
// <button class="submit">Submit</button>
// </div>
await page.locator('.form .username').fill('john');
await page.locator('.form .submit').click();
// Attribute selectors
// <input type="text" required>
await page.locator('input[required]').fill('required field');
// Nth element
// <ul>
// <li>First item</li>
// <li>Second item</li>
// <li>Third item</li>
// </ul>
await page.locator('li').nth(1).click(); // Clicks "Second item"
Assertions & Expectations
Common Assertions
Common assertion patterns in Playwright
// Check element visibility
await expect(page.getByText('Success')).toBeVisible();
// Check element state
await expect(page.getByRole('button')).toBeEnabled();
// Check text content
await expect(page.getByText('Welcome')).toHaveText('Welcome to our app');
// Check element count
await expect(page.getByRole('listitem')).toHaveCount(5);
// Check element attributes
await expect(page.getByRole('img')).toHaveAttribute('alt', 'Logo');
Best Practices
Test Organization
Best practices for organizing tests
// Group related tests
test.describe('User Authentication', () => {
test('successful login', async ({ page }) => {
// Test code
});
test('failed login', async ({ page }) => {
// Test code
});
});
// Use test fixtures for common setup
test.beforeEach(async ({ page }) => {
await page.goto('https://your-app.com');
});
Handling Async Operations
Best practices for handling asynchronous operations
// Wait for network requests
await page.waitForLoadState('networkidle');
// Wait for specific element
await page.waitForSelector('.loading-spinner', { state: 'hidden' });
// Wait for navigation
await Promise.all([
page.waitForNavigation(),
page.click('a[href="/dashboard"]')
]);
Playwright Commands
Basic Commands
Essential Playwright CLI commands
# Run all tests
npx playwright test
# Run tests in UI mode
npx playwright test --ui
# Run tests in specific browser
npx playwright test --project=chromium
# Run tests in debug mode
npx playwright test --debug
# Run specific test file
npx playwright test example.spec.ts
# Run tests matching a pattern
npx playwright test -g "test name pattern"
# Show test report
npx playwright show-report
# Generate code from user actions
npx playwright codegen example.com
# Install browsers
npx playwright install
# Install specific browser
npx playwright install chromium
Test Configuration
Common configuration options in playwright.config.ts
import { defineConfig, devices } from '@playwright/test';
export default defineConfig({
// Run tests in files matching pattern
testMatch: '**/*.spec.ts',
// Run tests in parallel
workers: 3,
// Retry failed tests
retries: 2,
// Timeout for each test
timeout: 30000,
// Reporter configuration
reporter: [
['html'],
['list']
],
// Browser configuration
projects: [
{
name: 'chromium',
use: { ...devices['Desktop Chrome'] },
},
{
name: 'firefox',
use: { ...devices['Desktop Firefox'] },
},
{
name: 'webkit',
use: { ...devices['Desktop Safari'] },
},
],
});
Screenshots & Visual Testing
Taking Screenshots
Different ways to capture screenshots in Playwright
// Take full page screenshot
await page.screenshot({ path: 'screenshot.png', fullPage: true });
// Take element screenshot
await page.locator('.header').screenshot({ path: 'header.png' });
// Take screenshot on failure
test('visual test', async ({ page }) => {
await page.goto('https://example.com');
await expect(page).toHaveScreenshot('page.png');
});
// Compare screenshots
await expect(page.locator('.component')).toHaveScreenshot('component.png', {
maxDiffPixels: 100, // Allow some pixel differences
threshold: 0.2, // 20% threshold for color differences
});
Visual Testing Best Practices
Best practices for visual testing with Playwright
// Ignore dynamic content
await expect(page).toHaveScreenshot('page.png', {
mask: [
page.locator('.timestamp'),
page.locator('.dynamic-content')
]
});
// Handle animations
await page.evaluate(() => {
// Disable CSS animations
document.body.style.setProperty('animation', 'none');
document.body.style.setProperty('transition', 'none');
});
// Compare specific regions
await expect(page.locator('.main-content')).toHaveScreenshot('content.png', {
clip: { x: 0, y: 0, width: 800, height: 600 }
});
Network & API Testing
Network Interception
Intercepting and mocking network requests
// Intercept API requests
await page.route('**/api/users', async route => {
// Mock response
await route.fulfill({
status: 200,
body: JSON.stringify({ users: [] })
});
});
// Wait for network requests
await page.waitForResponse(response =>
response.url().includes('/api/data')
);
// Mock API response
await page.route('**/api/data', async route => {
const json = { data: 'mocked data' };
await route.fulfill({ json });
});
API Testing
Testing API endpoints with Playwright
// Test API endpoint
test('API test', async ({ request }) => {
// GET request
const response = await request.get('/api/users');
expect(response.ok()).toBeTruthy();
// POST request
const postResponse = await request.post('/api/users', {
data: {
name: 'John',
email: 'john@example.com'
}
});
expect(postResponse.status()).toBe(201);
// PUT request
const putResponse = await request.put('/api/users/1', {
data: {
name: 'John Updated'
}
});
expect(putResponse.ok()).toBeTruthy();
});
Debugging & Troubleshooting
Debugging Tools
Tools and techniques for debugging tests
// Pause execution
await page.pause();
// Slow down operations
await page.setDefaultTimeout(5000);
await page.setDefaultNavigationTimeout(10000);
// Debug selectors
const element = page.locator('.my-element');
console.log(await element.count());
console.log(await element.isVisible());
// Take screenshot on failure
test.afterEach(async ({ page }, testInfo) => {
if (testInfo.status !== testInfo.expectedStatus) {
await page.screenshot({
path: `failure-${testInfo.title}.png`,
fullPage: true
});
}
});
Tracing & Logging
Using Playwright tracing and logging features
// Start tracing
await context.tracing.start({ screenshots: true, snapshots: true });
// Your test code here
await page.goto('https://example.com');
await page.click('.button');
// Stop tracing and save
await context.tracing.stop({ path: 'trace.zip' });
// View trace
// npx playwright show-trace trace.zip
// Enable debug logging
process.env.DEBUG = 'pw:api';
// or
const browser = await chromium.launch({ logger: {
isEnabled: (name, severity) => true,
log: (name, severity, message, args) => console.log(`${name} ${message}`)
}});
Playwright - Interactive Developer Reference
Hover over code blocks to copy or run in live playground