Introduction
Visual regression testing captures screenshots of your UI and automatically detects unintended changes. It’s essential for catching layout bugs, style regressions, and responsive issues. This guide covers tools and implementation.
What Is Visual Regression Testing?
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Visual Regression Testing Flow โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ โ
โ Build Capture Compare Result โ
โ โโโโโ โโโโโโโ โโโโโโโ โโโโโโ โ
โ โ
โ โโโโโโโโ โโโโโโโโ โโโโโโโโ โ
โ โ Page โโโโโโถโScreenshotโโโโโโถโ Diff โโโโโโถ Pass/Fail โ
โ โโโโโโโโ โโโโโโโโ โโโโโโโโ โ
โ โ โ
โ โโโโโโโโผโโโโโโโ โ
โ โ Changed? โ โ
โ โโโโโโโโโโโโโโโ โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Tools Comparison
tools:
- name: "Percy"
type: "Cloud service"
features: "Visual review, CI integration"
pricing: "Free tier available"
- name: "Chromatic"
type: "Cloud service"
features: "Storybook integration, component testing"
pricing: "Free tier available"
- name: "Playwright Screenshot"
type: "Built-in"
features: "Local comparison, full control"
pricing: "Free (own infrastructure)"
- name: "BackstopJS"
type: "Open source"
features: "Self-hosted, local comparison"
pricing: "Free"
Playwright Visual Testing
Setup
npm install -D @playwright/test
npx playwright install chromium
Screenshot Tests
import { test, expect } from '@playwright/test';
test('homepage visual snapshot', async ({ page }) => {
await page.goto('https://example.com');
// Take screenshot
await expect(page).toHaveScreenshot('homepage.png');
});
test('login page visual', async ({ page }) => {
await page.goto('https://example.com/login');
await expect(page).toHaveScreenshot('login.png', {
fullPage: true,
});
});
Visual Comparison Options
test('with comparison options', async ({ page }) => {
await page.goto('https://example.com');
await expect(page).toHaveScreenshot('page.png', {
// Pixel match threshold (0-1)
maxDiffPixelRatio: 0.1,
// Ignore certain elements
mask: [
page.locator('[data-testid="dynamic-content"]'),
page.locator('.advertisement'),
],
// Animations disabled
animations: 'disabled',
});
});
CI Integration
# GitHub Actions
- name: Visual Tests
run: npx playwright test --project=visual
env:
CI: true
Percy
Setup
npm install --save-dev @percy/cli @percy/ember
# or
npm install --save-dev @percy/ng2
Configuration
# .percy.yml
version: 2
snapshot:
widths: [375, 768, 1280]
minHeight: 1024
static:
base-url: "http://localhost:3000"
files: "**/*.html"
Percy Test
import { test, expect } from '@playwright/test';
test.percy('homepage', async ({ page }) => {
await page.goto('https://example.com');
await percySnapshot(page, 'Homepage');
});
Chromatic (Storybook)
Setup
npx chromatic --project-token=YOUR_TOKEN
GitHub Action
# .github/workflows/chromatic.yml
name: Chromatic
on: push
jobs:
chromatic:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 18
- name: Install dependencies
run: npm ci
- name: Publish to Chromatic
uses: chromaui/action@v1
with:
projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}
Best Practices
best_practices:
- "Test at multiple viewports (mobile, tablet, desktop)"
- "Disable animations for consistent results"
- "Mask dynamic content (dates, ads)"
- "Use CI to catch regressions automatically"
- "Review visual changes in PRs before merging"
Key Takeaways
- Visual testing catches UI bugs - Layout, style regressions
- Percy/Chromatic - Cloud services, great review workflow
- Playwright - Built-in, self-controlled
- Essential for UI libraries - Component testing
Comments