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
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.
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:
- 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.
- Inject a fixed clock (
- Disable animations, transitions & blinking carets:
- Set
animations: 'disabled'andcaret: 'hide'in screenshot options (or injectprefers-reduced-motion: reduce), and pause any JS timers, canvas loops or video frames at a deterministic tick.
- Set
- Wait for fonts, images & layout stability:
- Await
document.fonts.readyand ensure local web fonts and SVG/icon assets have finished loading before capturing; missing fonts cause massive false-positive text diffs across OS environments.
- Await
- Pin viewport, device scale factor & color scheme:
- Explicitly declare the viewport matrix (e.g.,
1280x800desktop,768x1024tablet,375x667mobile,320x568reflow) and theme (lightvs.dark) as part of the test setup.
- Explicitly declare the viewport matrix (e.g.,
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:
- Intentional visual change: matches the task specification and design tokens -> update the baseline and document why in the handoff.
- Unintended regression: a token or CSS edit leaked into an unrelated component, broke alignment or clipped overflow -> fix the CSS/component bug!
- 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
