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:
| Severity | Difference | What it usually means |
|---|---|---|
| Trivial | < 1% | Anti-aliasing, font rendering, animation frames — usually safe to ignore. |
| Minor | 1–5% | Spacing tweaks, copy edits, small icon changes. |
| Moderate | 5–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.