Skip to content

Visual regression: Storybook Loki + test-runner + a11y infrastructure

Visual regression: Storybook Loki + test-runner + a11y infrastructure

Status: Delivered
CAS: CAS-2740
Delivered: 2026-05-14
PRs: #733

What’s new

Storybook’s CI verification is now split into three explicit parallel jobs so failures are immediately attributable:

  • storybook-visual-diff — Loki pixel-level comparison against baselines (generates baselines on first run)
  • storybook-test-runner — runs every story’s play() function and interaction tests end-to-end
  • storybook-a11y — axe-core accessibility pass across all stories, reports violations without blocking (violations are tracked for follow-up)

Previously all Storybook verification ran as a single step, making it impossible to distinguish a visual regression from an a11y violation from a broken interaction test.

How to use it

Running locally:

Terminal window
npm run build-storybook # build static Storybook
npm run storybook:test-runner # run interaction tests + a11y

Loki visual diffs require a running Storybook server:

Terminal window
npx storybook dev -p 6006 &
npx loki test # diff against stored baselines
npx loki update # update baselines after intentional changes

In CI: The three jobs run in parallel after the frontend job completes. Each posts its own status check — a failing a11y check won’t mask a passing visual-diff.

What changed under the hood

  • .github/workflows/ci.yml — Three separate storybook-* CI jobs, each with targeted npm run commands, replacing the single catch-all Storybook step.
  • package.json — Removed duplicate axe-playwright entry that was causing install warnings.

Why we built it

The CAS-2741 page-level stories exposed a gap: Storybook coverage expanded significantly but the CI verification was a single opaque step. When it failed, engineers had to re-run locally to isolate the cause. Splitting into three jobs makes the failure signal immediate and actionable — an engineer can see “a11y check failed, visual-diff passed” without a local re-run.

Known limitations / follow-on work

  • Loki baseline capture in CI requires find-free-port-sync resolution; the ENOBUFS behavior on the build machines defers Loki’s first baseline generation to a local npx loki update run and manual commit.
  • The a11y runner currently reports pre-existing violations across stories and components. These are tracked as follow-on work and do not block the merge gate — the CI job reports them without failing the build.