Menguji visual regression: screenshot diff, pixel snapshots, threshold configuration, dan visual testing untuk mendeteksi perubahan UI

Setelah di episode 12 kita mengatasi flaky tests, pada episode ini kita membahas testing yang melengkapi functional testing: visual testing. Perubahan CSS yang tidak terdeteksi oleh functional tests bisa merusak UX.
// Full page screenshot
await page.screenshot({ path: 'screenshot.png', fullPage: true });
// Element screenshot
await page.locator('.header').screenshot({ path: 'header.png' });
// Viewport screenshot
await page.screenshot({ path: 'viewport.png' });// Compare dengan baseline
test('homepage visual', async ({ page }) => {
await page.goto('/');
await expect(page).toHaveScreenshot('homepage.png');
});
// Compare element
test('header visual', async ({ page }) => {
await expect(page.locator('.header')).toHaveScreenshot('header.png');
});// playwright.config.ts
export default defineConfig({
expect: {
toHaveScreenshot: {
maxDiffPixelRatio: 0.01, // 1% pixel difference
threshold: 0.2, // per-pixel color threshold
animations: 'disabled',
},
},
});Visual Regression Steps:
1. Generate baseline screenshots
2. Jalankan visual tests
3. Compare current vs baseline
4. Review diffs
5. Accept atau reject perubahan# Update baseline screenshots
npx playwright test --update-screenshots
# Update specific test
npx playwright test --update-screenshots homepage.visual.tsVisual Testing Best Practices:
├── Disable animations untuk consistent screenshots
├── Use fixed viewport sizes
├── Mock dynamic content (timestamps, avatars)
├── Set appropriate thresholds
├── Review diffs manually, jangan auto-accept
└── Baseline di version control// Freeze time
test('dashboard visual', async ({ page }) => {
await page.clock.setFixedTime(new Date('2026-01-15T12:00:00'));
await page.goto('/dashboard');
await expect(page).toHaveScreenshot('dashboard.png');
});
// Mock avatars
await page.route('**/avatars/**', route => {
route.fulfill({ path: 'tests/fixtures/default-avatar.png' });
});Note
Visual testing menangkap perubahan yang functional tests miss — misalnya text overflow, misalignment, atau color changes yang merusak UX.
import { test, expect } from '@playwright/test';
test('homepage visual regression', async ({ page }) => {
await page.goto('/');
await expect(page).toHaveScreenshot('homepage.png', {
maxDiffPixelRatio: 0.01,
});
});
test('login page visual regression', async ({ page }) => {
await page.goto('/login');
await expect(page).toHaveScreenshot('login.png', {
maxDiffPixelRatio: 0.01,
});
});Di episode 14 selanjutnya kita akan membahas performance in automation — mengintegrasikan performance checks dalam automated tests. Sampai jumpa di episode 14!