playwright-test
Run end-to-end browser tests using the Playwright Test CLI. Create test configs, write spec files with expect assertions, execute tests with npx playwright test, and analyze results. Pre-installed wit
Files2
View on GitHubSKILL.mdskills/teamday/playwright-test/SKILL.md
GitHubPlaywright Test CLI
Run end-to-end browser tests using the Playwright Test framework. @playwright/test and Chromium are pre-installed globally — no setup required.
Quick Start
1. Create a config file in the project root (or working directory):
// playwright.config.ts
import { defineConfig } from '@playwright/test';
export default defineConfig({
testDir: './tests',
use: {
baseURL: 'http://localhost:3000',
headless: true,
screenshot: 'only-on-failure',
},
reporter: [['list'], ['html', { open: 'never' }]],
retries: 1,
timeout: 30000,
});
2. Write a test file:
// tests/example.spec.ts
import { test, expect } from '@playwright/test';
test('homepage loads and has title', async ({ page }) => {
await page.goto('/');
await expect(page).toHaveTitle(/My App/);
});
test('navigation works', async ({ page }) => {
await page.goto('/');
await page.click('a[href="/about"]');
await expect(page).toHaveURL(/about/);
});
3. Run tests:
npx playwright test
CLI Reference
Running Tests
# Run all tests
npx playwright test
# Run a specific test file
npx playwright test tests/login.spec.ts
# Run tests matching a name/regex
npx playwright test -g "login flow"
# Run tests in a specific directory
npx playwright test tests/smoke/
# Run with a specific config
npx playwright test --config=playwright.ci.config.ts
Filtering & Debugging
# Run only tests tagged with @smoke
npx playwright test --grep @smoke
# Exclude tests tagged @slow
npx playwright test --grep-invert @slow
# Run a specific test by line number
npx playwright test tests/auth.spec.ts:15
# Run in debug mode (step through tests)
npx playwright test --debug
# Run with verbose output
npx playwright test --reporter=list
Execution Control
# Run tests in parallel (default)
npx playwright test --workers=4
# Run tests serially (useful for debugging)
npx playwright test --workers=1
# Retry failed tests
npx playwright test --retries=2
# Set timeout per test (ms)
npx playwright test --timeout=60000
# Stop on first failure
npx playwright test --max-failures=1
Reporters & Output
# List reporter (real-time output, good for CI)
npx playwright test --reporter=list
# Line reporter (minimal, one line per test)
npx playwright test --reporter=line
# JSON reporter (machine-readable)
npx playwright test --reporter=json
# HTML report (generates browsable report)
npx playwright test --reporter=html
# Multiple reporters
npx playwright test --reporter=list,html
# JUnit XML (for CI integration)
npx playwright test --reporter=junit
Updating Snapshots
# Update visual comparison screenshots
npx playwright test --update-snapshots
Test Patterns
Page Object Model
// tests/pages/login.page.ts
import { Page, Locator } from '@playwright/test';
export class LoginPage {
readonly emailInput: Locator;
readonly passwordInput: Locator;
readonly submitButton: Locator;
constructor(private page: Page) {
this.emailInput = page.locator('input[name="email"]');
this.passwordInput = page.locator('input[name="password"]');
this.submitButton = page.locator('button[type="submit"]');
}
async login(email: string, password: string) {
await this.emailInput.fill(email);
await this.passwordInput.fill(password);
await this.submitButton.click();
}
}
// tests/login.spec.ts
import { test, expect } from '@playwright/test';
import { LoginPage } from './pages/login.page';
test('successful login redirects to dashboard', async ({ page }) => {
const loginPage = new LoginPage(page);
await page.goto('/login');
await loginPage.login('user@example.com', 'password123');
await expect(page).toHaveURL(/dashboard/);
});
API Testing
import { test, expect } from '@playwright/test';
test('API returns valid response', async ({ request }) => {
const response = await request.get('/api/users');
expect(response.ok()).toBeTruthy();
const data = await response.json();
expect(data.users).toBeInstanceOf(Array);
expect(data.users.length).toBeGreaterThan(0);
});
Visual Regression
test('homepage matches screenshot', async ({ page }) => {
await page.goto('/');
await expect(page).toHaveScreenshot('homepage.png', {
maxDiffPixelRatio: 0.01,
});
});
Test Tags
// Tag tests for selective execution
test('login works @smoke', async ({ page }) => { /* ... */ });
test('complex workflow @slow', async ({ page }) => { /* ... */ });
// Run: npx playwright test --grep @smoke
Fixtures
import { test as base, expect } from '@playwright/test';
// Extend test with custom fixtures
const test = base.extend<{ authenticatedPage: Page }>({
authenticatedPage: async ({ page }, use) => {
await page.goto('/login');
await page.fill('input[name="email"]', 'test@example.com');
await page.fill('input[name="password"]', 'password');
await page.click('button[type="submit"]');
await page.waitForURL(/dashboard/);
await use(page);
},
});
test('dashboard shows user name', async ({ authenticatedPage }) => {
await expect(authenticatedPage.locator('.username')).toContainText('Test User');
});
Config Options
Common playwright.config.ts settings:
import { defineConfig, devices } from '@playwright/test';
export default defineConfig({
testDir: './tests',
fullyParallel: true,
forbidOnly: !!process.env.CI,
retries: process.env.CI ? 2 : 0,
workers: process.env.CI ? 1 : undefined,
reporter: 'list',
use: {
baseURL: process.env.BASE_URL || 'http://localhost:3000',
headless: true,
screenshot: 'only-on-failure',
trace: 'on-first-retry',
video: 'retain-on-failure',
},
// Multiple browser projects
projects: [
{ name: 'chromium', use: { ...devices['Desktop Chrome'] } },
{ name: 'mobile', use: { ...devices['Pixel 5'] } },
],
// Auto-start dev server before tests
webServer: {
command: 'npm run dev',
url: 'http://localhost:3000',
reuseExistingServer: true,
timeout: 30000,
},
});
Workflow
When asked to write or run Playwright tests:
- Check for existing config — look for
playwright.config.tsin the working directory - Create config if missing — use the Quick Start template, adjust
baseURLto match the user's app - Create test directory —
mkdir -p tests - Write test files — use
.spec.tsextension, import from@playwright/test - Run tests —
npx playwright testwith appropriate flags - Report results — parse output, highlight failures, suggest fixes
Tips
- Always use headless mode — the computer image has no display;
headless: trueis the default - Use
baseURL— set it in config so tests use relative paths (page.goto('/')instead of full URLs) - Prefer locators over selectors —
page.getByRole(),page.getByText(),page.getByTestId()are more resilient - Use
expectauto-waiting — Playwright assertions auto-retry, soawait expect(locator).toBeVisible()waits automatically - Capture traces on failure — set
trace: 'on-first-retry'in config for debugging failed tests - Only Chromium is available — don't configure Firefox or WebKit projects; only
chromiumis installed