105 / 139 · 13 Browser Automation with Playwright · Visual Testing and Edge Cases← prev⊞ allnext →☰ Read as one page
12.2Visual Comparison (Screenshot Testing)
Playwright can capture screenshots and compare them pixel-by-pixel against baselines. Visual tests catch CSS regressions, layout shifts, and rendering issues that functional tests miss.
test('homepage matches visual baseline', async ({ page }) => {
await page.goto('/');
await expect(page).toHaveScreenshot('homepage.png');
});
test('product card renders correctly', async ({ page }) => {
await page.goto('/products');
const card = page.getByTestId('product-card').first();
await expect(card).toHaveScreenshot('product-card.png');
});
How It Works
- First run: Playwright captures a screenshot and saves it as the baseline in a
__snapshots__directory - Subsequent runs: Playwright captures a new screenshot and compares it pixel-by-pixel
- On mismatch: The test fails and generates a diff image showing exactly what changed
Dealing with Dynamic Content
// Mask dynamic elements (timestamps, avatars, ads)
await expect(page).toHaveScreenshot('dashboard.png', {
mask: [page.getByTestId('timestamp'), page.getByTestId('avatar')],
});
// Allow a small pixel difference threshold
await expect(page).toHaveScreenshot('chart.png', {
maxDiffPixelRatio: 0.01, // Allow 1% of pixels to differ
});
// Wait for animations to settle
await expect(page).toHaveScreenshot('animated-widget.png', {
animations: 'disabled',
});