SDODS
Workshop

7 · Screenshots and visual baselines

Before-and-after captures per step, a baseline that fails the first time on purpose, and the @a11y and @perf tags.

What you'll learn

What SDODS captures during a run and when, how a visual baseline is created and compared, why the first run of a baseline scenario always fails, and what the @a11y and @perf tags add.

Time: 15 minutes · You need: chapter 6 finished, the application running.

Screenshots are a narrative, not an afterthought

The capture policy is per suite tag, so a smoke run stays fast while a regression run documents every step:

projects/rwa-bank/sdods.project.yaml
screenshots:
  policy:
    default: on-failure
    '@smoke': scenario # one at the start, one at the end
    '@regression': step # before and after every step
    '@visual': visual # compared against a baseline
  viewport: { width: 1280, height: 720 }
  mask: ['[data-test="sidenav-user-balance"]']

mask blanks regions that change on every run — a balance, a date, an avatar — so a diff means a change in behaviour rather than a change in the clock.

sdods run -p rwa-bank -e local -b chromium -t "@regression and @account"
sdods report --last --open

The report pairs the before and after image of each step with the step text, which is what makes a failure explainable to someone who was not there.

A visual baseline

projects/rwa-bank/features/account/visual.feature
@ui @account @visual
Feature: The sign-in page does not drift

  @regression @visual
  Scenario: The sign-in page matches its baseline
    Given I am on the sign-in page
    Then the page should match the visual baseline "signin"
sdods run -p rwa-bank -e local -l ui -b chromium -t @visual

The first run fails. There was no baseline, so it wrote one and told you it had nothing to compare against. Run it again and it passes:

projects/rwa-bank/features/__screenshots__/rwa-bank--ui--chromium/darwin/signin.png

The path contains the browser and the platform, because font rendering differs between macOS and Linux. A baseline recorded on a laptop will not match on a CI runner: record the CI baseline on CI with the visual-baselines workflow, and keep visual scenarios out of the suite that gates a merge until you have. This project has both: the darwin/ baseline from a laptop, and a linux/ one rendered in CI against the application started inside the job (chapter 10).

When the page changes on purpose, the check fails with a diff. Review it and accept it rather than re-recording everything:

sdods baselines diff
sdods baselines accept signin --run <runId>

See Screenshots and visual testing.

Accessibility and performance

Two more tags turn an ordinary scenario into a check:

  • @a11y: when the scenario ends, SDODS audits the page it finished on with axe-core (WCAG A and AA). The scenario fails on any violation at or above a11y.failOn in the project yaml (serious by default).
  • @perf: SDODS records the vitals of every page the scenario loads and compares them with perf.budgets (pageLoadMs, lcpMs, fcpMs, ttfbMs), and compares the p95 of its API calls with apiP95Ms. An environment with no budgets fails the scenario instead of passing it.

Try it on the sign-in baseline scenario above: add @a11y to it and run it again. If axe finds a serious violation, the error names the rule and the elements, and the full result is attached as sdods/a11y-scenario. For @perf, first add a perf: block with budgets to the project yaml. Without one, a @perf scenario fails with CONFIG_INVALID.

A process can require both with gates: { a11y: true, perfBudgets: true }. The options, the explicit steps and the gates are covered in Accessibility and performance budgets.

Checkpoint

sdods run -p rwa-bank -e local -l ui -b chromium -t @visual

Green on the second run, with a committed baseline under features/__screenshots__/. Next: reports, insights and healing.

Using an AI coding agent? Install SDODS:

Install the SDODS plugin in Claude Code: skills, subagents, commands and the MCP server.

  1. /plugin marketplace add https://sdods.com/skills.git
  2. /plugin install sdods@sdods
Learn more about using SDODS with AI tools

On this page