Installation & Setup
- npm init playwright@latestInit project
- npx playwright installInstall browsers
- npx playwright testRun tests
- npx playwright show-reportView report
- npx playwright codegenRecord tests
Locators
- page.getByRole()By ARIA role
- page.getByText()By text content
- page.getByLabel()By label
- page.getByPlaceholder()By placeholder
- page.getByTestId()By data-testid
- page.locator()CSS/XPath
Actions
- .click()Click element
- .fill('text')Fill input
- .type('text')Type slowly
- .check() / .uncheck()Checkbox
- .selectOption()Select dropdown
- .hover()Mouse hover
- .press('Enter')Keyboard
Assertions
- toBeVisible()Is visible
- toBeHidden()Is hidden
- toHaveText()Has text
- toHaveValue()Input value
- toBeEnabled()Is enabled
- toHaveURL()Page URL
- toHaveTitle()Page title
Basic Test Structure
import { test, expect } from '@playwright/test';
test('user can login', async ({ page }) => {
await page.goto('https://example.com/login');
await page.getByLabel('Email').fill('user@example.com');
await page.getByLabel('Password').fill('password123');
await page.getByRole('button', { name: 'Sign in' }).click();
await expect(page).toHaveURL('/dashboard');
});
CLI Commands
# Run all tests
npx playwright test
# Run specific file
npx playwright test login.spec.ts
# Run in headed mode (see browser)
npx playwright test --headed
# Run in specific browser
npx playwright test --project=chromium
# Debug mode
npx playwright test --debug
# UI mode (interactive)
npx playwright test --ui
- page.goto(url)Navigate to URL
- page.goBack()Go back
- page.goForward()Go forward
- page.reload()Reload page
- page.waitForURL()Wait for URL
Waiting
- waitForSelector()Wait for element
- waitForLoadState()Wait for load
- waitForResponse()Wait for API
- waitForTimeout()Hard wait (avoid)
playwright.config.ts
export default defineConfig({
testDir: './tests',
timeout: 30000,
retries: 2,
use: {
baseURL: 'http://localhost:3000',
screenshot: 'only-on-failure',
video: 'retain-on-failure',
trace: 'on-first-retry',
},
projects: [
{ name: 'chromium', use: { ...devices['Desktop Chrome'] } },
{ name: 'firefox', use: { ...devices['Desktop Firefox'] } },
],
});
Page Object Model
class LoginPage {
constructor(page) {
this.page = page;
this.email = page.getByLabel('Email');
this.password = page.getByLabel('Password');
this.submit = page.getByRole('button');
}
async login(email, pass) {
await this.email.fill(email);
await this.password.fill(pass);
await this.submit.click();
}
}
Screenshots & Video
- page.screenshot()Capture page
- locator.screenshot()Capture element
- video: 'on'Record video
- trace: 'on'Record trace