Why visual testing runs up against manual checks
A change to a shared component — a button, input field, product card — goes into release and breaks the layout across dozens of pages at once.
A developer checks three or four screens where the component is in plain sight, but it breaks where it was inserted a year ago with a non-standard margin. Such a layout regression surfaces after rollout, and users are the first to see it.
UI discrepancies are almost never visible on the "average" screen — they hide in a narrow set of states: empty list, long name, validation error, table overflow.
Going through these states manually across all resolutions and roles is impossible, so manual layout checks cover only a small share of real combinations.
Then release acceptance kicks in: the designer and analyst open mockups and page by page compare spacing, colors, and line breaks by eye. Pre-release mockup review stretches over days, disputed spots are handled out of turn — and the release is delayed.
This is a bottleneck in release acceptance, not a one-off overhead: the more pages there are, the lower the chance anyone can look at everything by eye.
We break down how this is closed: a snapshot of every page and every state on every change, automatic comparison with a baseline, and a report only on the UI areas that actually changed.
Such a process — for example, on Chromatic — removes manual review from acceptance and leaves the human to decide on disputed discrepancies.
What regular comparison of interface builds provides
Comparing every build with a baseline UI snapshot gives three measurable effects: early detection of discrepancies, predictable release acceptance time, and lower load on UI support.
All are a consequence of one mechanism: deviation from the baseline is recorded on a specific change, not at the moment when a customer has already opened the page.
How many discrepancies are caught before release
With configured tolerances and masks for dynamic zones — dates, counters, avatars, ad inserts — comparison noise drops severalfold, while real shifts remain noticeable.
Before release, about nine out of ten discrepancies can be caught: grid shift on narrow screens, truncated text in localization, a block that "moved" after editing a shared component.
The remainder are rare states such as empty results or long names; they are covered by separate scenarios. The class of layout failures moves from release into build history, where each deviation shows the author of the change and the date.
Acceptance time and missed release deadlines
When discrepancy checking is in the build pipeline, release acceptance shrinks from several days to hours: instead of an exhaustive pass through pages, the team reviews a short list of deviations with diff highlighting.
Release deadlines stop slipping because of last-day findings — disputed spots surface at the edit stage, when they take minutes to fix. Load on UI support drops: tickets like "on mobile the button overlaps text" stop arriving in batches after every update.
Overall, regular build comparison changes the economics of release: less manual checking, a shorter acceptance cycle, predictable UI support.
Comparison of approaches to visual testing
Choosing an approach comes down to where a discrepancy is caught and how much manual work remains for the team. Automation is built on comparing UI snapshots, and Chromatic covers the "build — baseline — report" link. Below are four alternatives teams choose between.
| Option | When it fits | Limitations |
|---|---|---|
| Snapshots at the build stage | Stable layout, frequent releases | Requires baseline maintenance and clean dynamic data |
| Checking across different browser environments | Broad audience, complex layout | Run takes longer; some discrepancies are rendering artifacts |
| Manual review by checklist | New screens, animations, states without mockups | Does not scale: misses on peripheral pages |
| Mixed mode | Mature product with critical scenarios | Requires discipline: thresholds, priorities, queue triage |
Where the threshold boundary lies
The threshold defines the share of differing points below which a snapshot is considered matching. For text blocks it is kept minimal, for image cards higher, otherwise the run gets noisy from smoothing.
Checking at different resolutions requires a separate baseline set: what is unnoticeable on a wide screen breaks the layout on a narrow one.
Updating baselines without stopping releases
Baseline approval mode is enabled selectively: a new snapshot is accepted as baseline after the cause of the discrepancy is reviewed. The update goes as a separate change and does not disable checking entirely — otherwise control disappears exactly where layout was edited.
Implementation sequence: from mockup review to handoff to the team
Implementing visual testing is not connecting a service but building a process: without baselines and rules for updating them, checks quickly turn into a stream of false discrepancies that the team stops reading. We work in stages — by handoff, a working process remains, not one-off settings.
Baseline preparation and state inventory
- Inventory of pages and states: collect a list of routes, screen resolutions, and UI variants — modals, validation errors, empty lists, guest and authenticated views. Record coverage in a table so new screens do not remain outside checks.
- Take baseline snapshots from a verified build on fixed data, not from the current environment: otherwise other people's edits and random content get into the comparison base.
- Running checks in the build: embed comparison via Chromatic into the pipeline so it runs on every change in the branch and blocks merge on discrepancy, and a report with diff highlighting opens directly from the task.
Cutting off false positives
- Break down false discrepancies by cause: animations, font loading, dates, random data, lazy image loading. Mask unstable blocks, freeze time and animations, replace dynamic data with predictable values.
- Baseline update process: who may update a snapshot, when it is a conscious layout edit rather than suppressing an error, and how the reason is recorded in history.
- Team training: developers and testers read the report themselves and distinguish a false discrepancy from a real defect.
Outcome — checks run on every change, the false-positive rate drops to single digits, and baselines are updated by rule, not by agreement in chat.
Repository artifacts: configurations, maps, processes
Implementation ends not with a report on work but with a set of files in the repository that the team uses to continue checking the interface without us.
Everything sits next to the code and is versioned with it — during migration or a contractor change, nothing needs to be restored from chat.
- Check configuration file: which builds are compared, with what tolerance, and under what conditions a discrepancy blocks merge of changes.
- Page and state coverage map — a table where for each route it is noted which screen resolutions, themes, and data variants are included in comparison.
- Set of baseline snapshots tied to branch and release tag: rollback to the previous version does not require re-shooting.
- Baseline update instructions — who confirms the new UI state and in what order.
- Discrepancy triage process: how to separate a real layout break from noise from animations, fonts, and data loading.
- Permissions scheme: who can view reports, who can approve baselines.
- Checklist for connecting a new section: what to add to the coverage map so a page does not remain without checks.
Access policies for reports and baselines
Report viewing is open to the whole team — both developer and tester see a discrepancy. Only those responsible for the interface can approve baselines, otherwise a disputed state will silently become the norm.
We grant rights through existing groups in the version control system, not separate accounts: when a person leaves, access closes automatically.
Baseline update process
Baselines change in the same code change where the interface changes — otherwise checking breaks at the next merge.
A disputed discrepancy is not approved on the fly but reviewed according to the checklist above; a mass update is submitted as a separate change with an explanation of the reason.
Case: eliminated false discrepancies after a layout change
What it was before: manual review and missed defects
The project — an online store with catalog, cart, and customer account: 40 key screens and several states on each.
Before release, two engineers went through them by eye using a checklist — this took 3-4 hours and left blind spots: behavior after a validation error, long product names, empty cart.
In a quarter, six layout defects made it into release: broken card grid on narrow screens, a button overlapping text with localized labels, truncated price block. Manual review did not scale — the more screens were added, the less time remained for each.
What it became after: coverage and acceptance time
We connected Chromatic to the build: every commit captures snapshots of components and pages in an isolated environment, discrepancies arrive in review with a "before/after" overlay.
Coverage grew from two dozen states that a person had time to check to 180 snapshots — including loading states, errors, and different screen widths.
Separate work — false positives. In the first weeks, snapshots "shook" on animations and font loading; we disabled animations during snapshot capture, froze fonts, and masked dynamic blocks such as the item counter in the cart.
The false-positive rate remained below 5% — an engineer opens a discrepancy and immediately sees whether it is a defect or noise.
Release acceptance time dropped from 3-4 hours to 40 minutes, and missed layout defects in release — from six per quarter to zero in the last three releases. If there are no discrepancies, the release ships without a manual walkthrough.
What to do if interface checks are already set up
Partially configured checks are a common situation: visual testing runs but covers one service or a few key screens, and baselines were collected manually. Some snapshots are outdated, the threshold is fuzzy, and the result is read "by eye."
The next step depends on the coverage share and on how well baselines reflect the current UI state.
| Path | When it fits | Limitations and transition effort |
|---|---|---|
| Expanding coverage | Base scenarios are already green; states are needed: modals, empty and overflowing lists, validation errors | The number of snapshots grows — component grouping and rules for allowable differences are required |
| Moving checks into the build | Checks are run manually or as a separate job after release | The environment must be stabilized and animations disabled; baselines will have to be approved anew |
| Rebuilding from scratch | Baselines are outdated, differences outnumber matches, there is no trust in results | A full pass through screens and states, but false-positive debt is cleared |
Baseline migration is the heaviest part of any path: snapshots taken in a different environment, window size, or fonts produce discrepancies out of nowhere.
In Chromatic, snapshots are tied to the build, so when the rendering mode changes, baselines are approved anew — one-time work, but it must be planned.
We start with an inventory: which screens and states are covered, which differences are marked as allowed, where thresholds are disabled. Based on it, we choose the path and define the points at which checking becomes mandatory for release.
Technical doubts: noise, stability, maintenance
Visual testing breaks not on the first run but on the tenth: snapshots start failing because of dates and sliders, and the team stops trusting them. Below are five doubts that come up before implementation and how we address them.
Dynamic content creates noise — how to handle it?
Blocks with dates, counters, sliders, and avatars are masked — comparison runs on the rest of the layout. Animations and carousels are disabled at snapshot time, and fixed data is substituted.
Styling updates often — do baselines have to be rewritten manually?
No. New snapshots are accepted as a new baseline version and go into review together with the code — you can see which styling edits were made consciously and which slipped through accidentally.
Is a separate environment needed for runs?
Usually a stable environment with fixed test data and one set of fonts is enough, so a snapshot does not depend on the developer's machine. Data from external services is replaced with stubs.
Where are baselines stored, and what happens to them during branching?
Baselines live in the repository next to the code and are tied to the commit, so rolling back a branch also restores snapshots. Version history remains transparent: you can see who approved a change and when.
Who maintains this after handoff?
We hand over the configuration, naming conventions, and triage of typical failures, and train the team. After that, your engineers run the checks independently — or we stay on support.
Let's discuss the task and come back with an estimate and plan
Describe the task — we will come back with an estimate and plan.
To make the scope estimate substantive rather than "by feel," it is enough to send read access to the repository, a description of environments, and a list of critical pages; we will clarify the rest in a conversation.
- read access to the repository and the build command — this is enough to understand how checks are run;
- description of environments: where branches are deployed, which environment is considered release, and how data gets into them;
- list of critical pages and states: authentication, empty and overflowing lists, form errors, modals, long texts;
- current acceptance rules: who approves UI edits and what they look at before deployment;
- known pain points: where layout differs between browsers and what most often breaks during updates;
- reporting preferences: where to send discrepancies and who triages them first.
In response, we send the coverage composition — which screens and states visual testing will cover and which will remain under manual review — a diagram of the check implementation stages, and a work plan with the order of result acceptance.
We set up checks on Chromatic and enable them first on one service: remove noise from dynamic blocks, agree on the discrepancy threshold, and only then expand coverage.
This way the first result is noticeable quickly, and acceptance rules do not have to be rewritten along the way.







