← Back to Tutorials
12. Visual Testing
Screenshots
// Full page screenshot
await page.screenshot({ path: 'screenshots/full-page.png', fullPage: true });
// Element screenshot
await page.locator('.header').screenshot({ path: 'screenshots/header.png' });
// Screenshot with mask (hide dynamic content)
await page.screenshot({
path: 'screenshots/dashboard.png',
mask: [page.locator('.user-avatar')]
});
Screenshot Assertions (Visual Diff)
import { test, expect } from '@playwright/test';
test('visual comparison', async ({ page }) => {
await page.goto('https://example.com');
await expect(page).toHaveScreenshot('homepage.png', {
maxDiffPixels: 100,
threshold: 0.2, // 0-1, lower = stricter
});
});
// Update baseline snapshots
// npx playwright test --update-snapshots
Visual Diff Algorithms
| Strategy | Description | When to Use |
| Pixel-by-pixel | Compare every pixel | Strict comparisons |
| Threshold | Allow small color differences | Cross-browser testing |
| Max diff pixels | Allow N pixels to differ | Animations, timestamps |
| Mask | Exclude regions from diff | Dynamic content areas |
Config for Visual Testing
// playwright.config.ts
use: {
screenshot: 'only-on-failure',
// OR
screenshot: 'on',
}
// For visual tests, set:
expect: {
toHaveScreenshot: {
maxDiffPixels: 200,
stylePath: './visual-overrides.css',
}
}
✏️ Exercise: Take a screenshot of a page, make a small CSS change (e.g., change a button color), re-run the visual test, and observe the diff output.