Visual regression

Beyond pass/fail assertions, Qassandra screenshots every step and compares it to a baseline so you catch layout regressions, missing elements, and accidental visual changes.

How comparisons work

For each step in a flow, Qassandra captures a screenshot. After the check completes, each screenshot is compared against the equivalent step from the most recent baseline run on your app's main branch.

Differences are quantified as a percentage and classified into severity buckets so you can triage at a glance:

SeverityDifferenceWhat it usually means
Trivial< 1%Anti-aliasing, font rendering, animation frames — usually safe to ignore.
Minor1–5%Spacing tweaks, copy edits, small icon changes.
Moderate5–20%Component redesigns, color changes, layout shifts.
Major> 20%Whole-page redesigns or genuinely broken pages.

Choosing a baseline

By default, the baseline is the latest finished check on your app's main branch — configurable in App settings → Visual diff (defaults to main).

If Qassandra can't auto-detect a baseline (for example a brand new app), you'll be asked to select a baseline check manually from the visual diff section of any check report.

Retention

Screenshots cost storage. To keep your bill predictable while preserving usefulness:

  • Main branch screenshots are stored indefinitely so you always have a baseline.
  • All other branches are deleted after 90 days.

Intent-aware diff handling

Not every visual difference is a bug. When a check is triggered with PR metadata (description, branch, commit messages), Qassandra cross-references the diff against what the PR claims to do:

  • If the PR description mentions a redesign of a page and that page is the only thing that changed, the diff is marked expected and won't fail the check.
  • If the PR description mentions changing button colours from green to blue, but only some buttons changed, Qassandra flags the inconsistency.
  • Differences on dynamic content (timestamps, recent activity, randomised previews) are auto-resolved as noise rather than regressions.

Visual diff is opt-out, not opt-in

It runs automatically for every check. If you don't want a particular flow compared (e.g. a date picker that always shows today), exclude its screenshots from the baseline in the flow's settings.