skills/running-visual-regression-tests/SKILL.md
Sets up and maintains visual regression testing: what to snapshot, baseline strategy, masking dynamic regions, threshold tuning, containerized baselines, and the review-and-update workflow. Use when styling regressions escape to production, when snapshots fail on every machine or every run, when baselines are being updated without being looked at, or when deciding whether visual testing is the right tool at all.
npx skillsauth add jaktestowac/awesome-copilot-for-testers running-visual-regression-testsInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Use this skill when appearance is the thing under test and functional assertions cannot express it: a broken layout at one breakpoint, a theme token that stopped applying, a component that shifted three pixels and swallowed a button.
Visual testing has one failure mode that dominates all others: a suite so noisy that --update-snapshots becomes reflex. At that point the baselines record whatever the code currently does, the diffs are never read, and the suite costs money while proving nothing. Everything below exists to prevent that.
Run through this before writing anything.
| The risk | Right tool |
| --- | --- |
| Wrong text, wrong label, wrong count | Assertion |
| Element missing or disabled | Assertion |
| Contrast, focus order, ARIA | auditing-accessibility |
| Layout broken at a breakpoint | Visual |
| Theme token stopped applying | Visual |
| Component spacing drifted | Visual, component-level |
| Chart or canvas rendering | Visual, with a fixed data seed |
| Third-party embed changed | Neither; stub it and test your side |
If most rows land outside the visual column, say so and stop. A visual suite added to compensate for missing assertions makes both worse.
Nothing about thresholds until this phase is finished. ./resources/masking-and-stabilization.md has the code for each item.
document.fonts.ready, or self-host and preload. A late webfont swap is the single most common cause of a one-off diff.animations: 'disabled'.mocking-network-and-time.The completion criterion for this phase is concrete: the same test run three times in a row on the same commit produces zero diffs. Do not proceed until that holds.
| Surface | Use for | Cost of a change |
| --- | --- | --- |
| Component / story | Design system, shared UI | One test per affected component |
| Region (locator.screenshot) | A card, a header, a table | Localized |
| Full page | Layout and page composition | One shared-component change reddens every page |
| Full page, fullPage: true | Long-scroll layouts | Highest noise; lazy-loading and sticky headers add diffs |
Default to region-level. Add full-page snapshots for a small set of layout-critical routes, and know that they will be the noisiest tests in the suite.
Decide and record, using ./resources/baseline-policy.md:
Start strict and loosen only against observed noise.
expect: {
toHaveScreenshot: {
maxDiffPixelRatio: 0.001,
threshold: 0.2, // per-pixel colour tolerance
animations: 'disabled',
caret: 'hide',
scale: 'css',
},
},
Rules for loosening:
maxDiffPixelRatio above roughly 0.01 hides a missing button; if you need that much, go back to Phase 1Config snippets, including the anti-aliasing and platform-difference cases, are in ./resources/visual-config-recipes.md.
The workflow in ./resources/visual-review-workflow.md, in short:
reporting-bugs.The verdict is mandatory per failing test. "Updated all snapshots" without per-test verdicts is the anti-pattern this skill is written to prevent.
Review periodically:
A visual suite is worth its cost when it has caught something. Write down what it has caught.
--update-snapshots across the whole suite to clear a red build./resources/masking-and-stabilization.md - fonts, animation, time, data, scrollbars, masking, and the three-identical-runs gate./resources/baseline-policy.md - where baselines are generated and stored, platform axes, update authority, containerized generation./resources/visual-config-recipes.md - Playwright config and per-test options, Docker baseline generation, CI artifact upload./resources/visual-review-workflow.md - the per-failure verdict process, pull request checklist, and escalation to a bugmocking-network-and-time - when snapshot instability comes from live data or a moving clockstabilizing-flaky-tests (planned) - when the instability is timing rather than renderingauditing-accessibility - when the concern is contrast, focus, or semantics rather than appearanceui-playwright-test-developer (planned) - when the visual checks sit inside a wider browser suiteautomating-ci-test-pipelines (planned) - for baseline containers, artifact retention, and sharding the visual suitereporting-bugs - when a diff is confirmed as a regressionThis skill is complete when:
testing
Tests the customization assets themselves - skills, prompts, custom agents, instructions - the way a product is tested: activation cases that check an asset fires when it should and stays quiet when it should not, output-contract cases, safety cases, collision cases between assets competing for the same trigger, a weighted rubric scored blind, and a baseline-versus-candidate gate before an edit ships. Use when a skill is edited and nobody knows whether behaviour changed, when two skills fight over the same request, when a description is being tuned for discoverability, when a collection has grown past manual spot-checking, or when the request mentions skill evals, prompt regression, or "does this skill actually work".
development
Shapes QA output for the person who has to act on it: result and blocker in the first two lines, one decision per report, findings ordered by what they cost, the long artifact in a file and the decisions in the message, and magnitude stated in units the reader can count. Use when a report is accurate but nobody acts on it, when a finding set is too long to read under time pressure, when the same findings must be retold for a developer, a release manager, and an on-call engineer, or when the request mentions "too long", "make this readable", "just tell me what to do", "so what", or "summarize this for stakeholders". Pairs with unslop-answers, which makes the same report honest.
testing
Verifies that the lines and branches a change actually touched are executed by tests, using LCOV or Cobertura diff coverage instead of whole-repo percentages, and escalates uncovered high-risk changes into a blocking finding. Use when a pull request needs a coverage gate that unrelated tests cannot satisfy, when total coverage looks healthy but the diff is untested, when wiring diff coverage into CI, or when someone claims a change is covered because the suite is green.
development
Cuts AI tells from test code: tests that pass without proving anything, tautological assertions, mock-only tests, hardcoded waits, coverage theater, vague names, swallowed errors, retries used as fixes. Use whenever test code is written, changed, or reviewed, including tests produced as a side effect of a feature task, and when the request mentions "review these tests", "are these tests any good", "this test always passes", "this suite is flaky", or "clean up these tests". Must always apply to test code.