Last Updated: November 21, 2025
Playwright
Cross-browser automation framework
Installation
npm init playwright@latest
Initialize Playwright project
npx playwright test
Run all tests
npx playwright test --ui
Run tests in UI mode
npx playwright test --debug
Run in debug mode
npx playwright codegen
Generate tests with codegen
Basic Test
import { test, expect } from '@playwright/test';
test('homepage has title', async ({ page }) => {
await page.goto('https://playwright.dev/');
// Expect a title "to contain" a substring
await expect(page).toHaveTitle(/Playwright/);
// Click the get started link
await page.getByRole('link', { name: 'Get started' }).click();
// Expect URL to contain intro
await expect(page).toHaveURL(/intro/);
});
Locators
| Item | Description |
|---|---|
page.getByRole('button')
|
By ARIA role |
page.getByText('Submit')
|
By text content |
page.getByLabel('Email')
|
By label text |
page.getByPlaceholder('name')
|
By placeholder |
page.getByTestId('submit')
|
By test ID |
page.locator('.btn')
|
By CSS selector |
Assertions
// Page assertions
await expect(page).toHaveTitle('My Page');
await expect(page).toHaveURL(/dashboard/);
// Element assertions
await expect(locator).toBeVisible();
await expect(locator).toBeHidden();
await expect(locator).toHaveText('Hello');
await expect(locator).toContainText('partial');
await expect(locator).toHaveValue('input value');
await expect(locator).toHaveCount(5);
Multi-Browser Testing
// playwright.config.ts
export default {
projects: [
{ name: 'chromium', use: { ...devices['Desktop Chrome'] } },
{ name: 'firefox', use: { ...devices['Desktop Firefox'] } },
{ name: 'webkit', use: { ...devices['Desktop Safari'] } },
{ name: 'mobile', use: { ...devices['iPhone 12'] } },
],
};
💡 Pro Tips
Quick Reference
Playwright auto-waits for elements before actions