8 / 74 · 10 Visual & Accessibility Testing · Commercial Visual Regression Tools← prev⊞ allnext →☰ Read as one page
2.1Percy (BrowserStack)
Percy captures screenshots across browsers and viewports, then highlights visual changes with smart diffing. It integrates with all major test frameworks and provides a web dashboard for reviewing and approving changes.
// tests/visual/homepage.spec.ts
import { test } from '@playwright/test';
import percySnapshot from '@percy/playwright';
test('homepage visual regression', async ({ page }) => {
await page.goto('/');
await page.waitForLoadState('networkidle');
// Capture at multiple widths
await percySnapshot(page, 'Homepage', {
widths: [375, 768, 1280],
minHeight: 1024,
percyCSS: `
/* Stabilize dynamic content for consistent screenshots */
[data-testid="timestamp"] { visibility: hidden; }
[data-testid="avatar"] { visibility: hidden; }
.animated { animation: none !important; }
`,
});
});
test('product card visual regression', async ({ page }) => {
await page.goto('/products');
// Wait for images to load
await page.waitForFunction(() => {
const images = document.querySelectorAll('img');
return Array.from(images).every(img => img.complete);
});
await percySnapshot(page, 'Product Listing', {
widths: [375, 1280],
});
});
test('checkout flow visual regression', async ({ page }) => {
// Navigate through checkout steps
await page.goto('/cart');
await percySnapshot(page, 'Cart Page', { widths: [375, 1280] });
await page.click('[data-testid="proceed-to-checkout"]');
await percySnapshot(page, 'Checkout - Shipping', { widths: [375, 1280] });
await page.fill('[data-testid="shipping-name"]', 'John Doe');
await page.fill('[data-testid="shipping-address"]', '123 Main St');
await page.click('[data-testid="continue-to-payment"]');
await percySnapshot(page, 'Checkout - Payment', { widths: [375, 1280] });
});
Percy CI Configuration
# .github/workflows/percy.yml
name: Percy Visual Tests
on: [pull_request]
jobs:
visual:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm ci
- run: npx playwright install --with-deps
- name: Run Percy snapshots
env:
PERCY_TOKEN: ${{ secrets.PERCY_TOKEN }}
run: npx percy exec -- npx playwright test tests/visual/
Percy's approval workflow: screenshots from the PR branch are compared against the base branch. Unchanged screenshots are auto-approved. Changed screenshots appear in the Percy dashboard for review. Approved changes become the new baseline when the PR merges.