Playwright Cheat Sheet
Complete reference guide for Playwright with interactive examples and live playground links
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