← Back to Business Systems Specialist Collection

Skill · Version 1.0.0

Visual regression tests

Creates stable screenshot comparisons that distinguish intentional visual changes from defects without treating images as proof of interaction correctness.

visual-regression-testing

Team members using this skill

See how it helps

When is it useful?

Use it when shared components or layouts need repeatable protection against appearance regressions across states and themes.

What does it help you do?

  • Controls time, data, fonts, animation and viewport variance.
  • Chooses focused component snapshots and representative composed screens.
  • Inspects diffs before updating baselines and retains behavioral tests.

Try asking this

Add stable dialog screenshots for error and dark-theme states without masking layout regressions. Deliberately remove an error label in a local check to confirm the snapshot detects it. Review intentional changes before accepting a new baseline.

Detailed documentation

Read the skill’s original instructions, examples and checks in their authored language.

Details…Show less

Visual Regression Testing

Visual regression tests catch unintended layout shifts, broken CSS tokens, z-index collisions, clipped text and dark-mode contrast regressions that unit assertions miss. However, poorly configured screenshot tests become flaky noise if non-deterministic inputs are not controlled.

1. Controlling Non-Determinism for Zero-Flake Baselines

Before capturing a screenshot baseline (Playwright toHaveScreenshot(), Chromatic, Percy or Storybook test runner), lock down every source of visual variance:

  1. Freeze time, random IDs & dynamic data:
    • Inject a fixed clock (page.clock.setFixedTime(...)) so relative timestamps ("3 minutes ago", calendar pickers) render identically on every run.
    • Use deterministic fixture data — never random faker output or live network responses.
  2. Disable animations, transitions & blinking carets:
    • Set animations: 'disabled' and caret: 'hide' in screenshot options (or inject prefers-reduced-motion: reduce), and pause any JS timers, canvas loops or video frames at a deterministic tick.
  3. Wait for fonts, images & layout stability:
    • Await document.fonts.ready and ensure local web fonts and SVG/icon assets have finished loading before capturing; missing fonts cause massive false-positive text diffs across OS environments.
  4. Pin viewport, device scale factor & color scheme:
    • Explicitly declare the viewport matrix (e.g., 1280x800 desktop, 768x1024 tablet, 375x667 mobile, 320x568 reflow) and theme (light vs. dark) as part of the test setup.

2. Component-Scoped vs. Full-Page Snapshots

  • Prefer component/locator screenshots (locator.screenshot()) for testing variants, interactive states (:hover, :focus-visible, error, disabled) and edge cases in isolation — they run fast and localize failures to the exact primitive.
  • Use targeted full-page or section snapshots for representative product screens where layout composition, sticky headers, sidebars and modal backdrops interact.

3. Disciplined Diff Triage (Never Blindly Update Snapshots)

When a visual test fails:

  • Inspect the visual diff image pixel-by-pixel (baseline vs. actual vs. diff overlay) before deciding whether to update the baseline.
  • Distinguish three categories:
    1. Intentional visual change: matches the task specification and design tokens -> update the baseline and document why in the handoff.
    2. Unintended regression: a token or CSS edit leaked into an unrelated component, broke alignment or clipped overflow -> fix the CSS/component bug!
    3. Environmental noise: font-hinting differences between macOS and Linux CI containers -> run baseline generation in the same browser/OS environment as CI or scope masks (mask: [locator]) only to genuinely volatile third-party embeds.
  • Pair visual checks with behavioral tests: a screenshot proves how a component looks, never whether clicking it fires the right callback or traps keyboard focus.

Included files 1

  • SKILL.md