Modern QA2026Implementing AI Visual Comparison
Log inJoin
5 / 11 · Book 10 · AI-Powered Visual Comparison← prev⊞ allnext →Get the book →

1.5Implementing AI Visual Comparison

Basic Implementation with Playwright Screenshots

// tests/visual/ai-comparison.spec.ts
import { test, expect } from '@playwright/test';
import { compareWithAI } from '../utils/ai-visual-compare';

test('homepage visual regression with AI triage', async ({ page }) => {
    await page.goto('/');
    await page.waitForLoadState('networkidle');

    // Stabilize dynamic content
    await page.evaluate(() => {
        // Hide timestamps, avatars, ads
        document.querySelectorAll('[data-testid="timestamp"]').forEach(
            el => (el as HTMLElement).style.visibility = 'hidden'
        );
        // Disable animations
        document.querySelectorAll('.animated').forEach(
            el => (el as HTMLElement).style.animation = 'none'
        );
    });

    // Capture current screenshot
    const screenshot = await page.screenshot({ fullPage: true });

    // Compare with baseline
    const baseline = await loadBaseline('homepage');

    if (baseline) {
        const pixelDiff = await pixelCompare(baseline, screenshot);

        if (pixelDiff.ratio > 0.001) {
            // More than 0.1% pixels differ -- use AI triage
            const aiResult = await compareWithAI(baseline, screenshot, {
                pageName: 'homepage',
                viewport: '1440x900',
            });

            if (aiResult.category === 'breaking') {
                throw new Error(`Visual regression: ${aiResult.description}`);
            } else if (aiResult.category === 'significant') {
                console.warn(`Visual change detected: ${aiResult.description}`);
                // In CI, this would create a review task
            }
            // Minor and no-change categories are auto-approved
        }
    } else {
        // First run: save as baseline
        await saveBaseline('homepage', screenshot);
    }
});