Modern QA2026Stabilizing Screenshots for Comparison
Log inJoin
6 / 11 · Book 10 · AI-Powered Visual Comparison← prev⊞ allnext →Get the book →

1.6Stabilizing Screenshots for Comparison

Dynamic content is the enemy of visual regression testing. Before capturing, stabilize the page:

async function stabilizeForScreenshot(page) {
    await page.evaluate(() => {
        // 1. Hide dynamic content
        const dynamicSelectors = [
            '[data-testid="timestamp"]',
            '[data-testid="avatar"]',
            '[data-testid="live-counter"]',
            '[data-testid="ad-slot"]',
        ];
        dynamicSelectors.forEach(sel => {
            document.querySelectorAll(sel).forEach(
                el => (el as HTMLElement).style.visibility = 'hidden'
            );
        });

        // 2. Disable all animations and transitions
        const style = document.createElement('style');
        style.textContent = `
            *, *::before, *::after {
                animation-duration: 0s !important;
                animation-delay: 0s !important;
                transition-duration: 0s !important;
                transition-delay: 0s !important;
            }
        `;
        document.head.appendChild(style);

        // 3. Wait for all images to load
        return Promise.all(
            Array.from(document.images)
                .filter(img => !img.complete)
                .map(img => new Promise(resolve => {
                    img.onload = resolve;
                    img.onerror = resolve;
                }))
        );
    });

    // 4. Wait for web fonts to load
    await page.waitForFunction(() => document.fonts.ready);
}

Pro Tip: Always stabilize before capturing. Dynamic content like timestamps, avatars, live counters, and advertisements are the number one source of false positives in visual regression testing. Hide them with visibility: hidden rather than display: none so that they still occupy layout space and do not cause layout shifts.

Common Mistake: Using display: none to hide dynamic content. This removes the element from layout flow, causing surrounding elements to shift position and triggering additional false positives. Use visibility: hidden instead -- it makes the element invisible but preserves its space in the layout.