Skip to content

feat: integrate visual regression testing for theme changes#69

Merged
PAMulligan merged 1 commit into
mainfrom
18-integrate-visual-regression-testing
May 20, 2026
Merged

feat: integrate visual regression testing for theme changes#69
PAMulligan merged 1 commit into
mainfrom
18-integrate-visual-regression-testing

Conversation

@PAMulligan
Copy link
Copy Markdown
Collaborator

Summary

Adds a Playwright-driven visual regression suite for themes/flavian-shop/. Diffs full-page screenshots at 4 breakpoints against committed baselines on every PR that touches the theme. Closes #18.

Pipeline shape

Stage File
Deterministic content seed tests/visual/seed.sh
Playwright capture w/ masking tests/visual/capture.mjs
Pixelmatch diff (existing engine) scripts/visual-diff.js --batch
Native GH Check annotations tests/visual/print-report.mjs
CI orchestration .github/workflows/visual-regression.yml

Key decisions (from scoping)

  • Deterministic seed script, not the existing content-seeder agent — tests/visual/seed.sh creates 3 fixed-slug products (test-hoodie / test-beanie / test-tee) and normalizes every publish date to 2025-01-15 12:00:00 UTC so dates can never cause a diff.
  • Dynamic-content masking via Playwright's built-in mask parameter — selectors live in tests/visual/masks.json (* keys apply to every URL, path-specific keys layer on top). Per m13v's warning about dynamic regions being the biggest pain point.
  • Native GitHub Check annotationsprint-report.mjs emits ::error file=…:: workflow commands so failures show up inline on the PR's Files Changed view. No third-party PR-comment action.
  • Thresholds: 0.5% full-page default (per m13v's recommendation), 0.1% region-fail / 1.0% region-warn inside the existing visual-diff.js region grid. Per-URL overrides in tests/visual/thresholds.json for cart/checkout/my-account which need looser tolerances while WooCommerce styles settle.
  • Baselines committed to repo under tests/visual/baselines/ (PRs surface them in the file viewer; reviewers can see what changed). Not LFS — ~40 PNGs × ~200KB doesn't justify the install overhead.
  • Subpixel stability across local + CI: scripts/visual-update-baselines.sh runs capture inside mcr.microsoft.com/playwright:v1.60.0-jammy — the same image whose Chromium ships in CI — so locally-generated baselines match CI rendering.
  • Soft-fail for 2 weeks: continue-on-error: true until 2026-06-02 while baselines stabilize. Date and flip instruction documented inline in the workflow and in tests/visual/README.md.

package.json introduction

Adds a private: true Node project to pin Playwright + pngjs + pixelmatch + commitlint reproducibly. The scoping doc asked for "more than minimal" — included scripts (visual:*, lint:commits*, test:visual, playwright:install) that lay groundwork for future Node-based CI without overreaching into Husky / Prettier / lint-staged territory. The version field is intentionally 0.0.0; repo version lives in .release-please-manifest.json and git tags. pnpm-lock.yaml is now tracked (was previously gitignored).

Bootstrap (no baselines in this PR)

tests/visual/baselines/ ships empty with a .gitkeep. After merge:

  1. Open Actions → visual-regression → "Run workflow" with bootstrap: true checked.
  2. Workflow captures fresh screenshots and pushes them to main as test(visual): bootstrap baselines [skip ci].
  3. From the next PR onward, real diffs run.

Alternative: run bash scripts/visual-update-baselines.sh locally and push.

Files

  • .github/workflows/visual-regression.yml — CI workflow
  • package.json, pnpm-lock.yaml, .npmrc — Node deps
  • tests/visual/{capture.mjs,print-report.mjs,seed.sh} — pipeline
  • tests/visual/{urls,masks,thresholds}.json — config
  • tests/visual/README.md — docs (how to add pages, update baselines, debug failures)
  • tests/visual/.gitignore + repo .gitignore update — scratch dirs
  • scripts/visual-capture.sh, scripts/visual-update-baselines.sh — local wrappers
  • CONTRIBUTING.md — added "Visual regression" subsection under Testing

Test plan

  • commitlint check passes on this PR.
  • visual-regression workflow runs and reports warning: No baselines committed (expected) — does not block merge thanks to continue-on-error: true.
  • After merge: manually trigger visual-regression with bootstrap: true. Verify ~40 PNGs appear in tests/visual/baselines/ via the bot commit.
  • Open a follow-up PR with a trivial theme change (e.g. tweak a themes/flavian-shop/templates/index.html color). Verify the workflow flags the diff with a native GH annotation and uploads the diff artifact.
  • Open a PR with no theme change. Verify the workflow does not run (paths filter).
  • On or after 2026-06-02, flip continue-on-error: truefalse in .github/workflows/visual-regression.yml.

🤖 Generated with Claude Code

Adds a Playwright-based visual regression suite that captures full-page
screenshots of every flavian-shop template at four breakpoints, masks
dynamic content (timestamps, cart totals, account history), and diffs
against committed baselines via the existing scripts/visual-diff.js
pixelmatch engine.

Pipeline:
- tests/visual/seed.sh seeds deterministic WP + WooCommerce content
  (fixed product slugs, normalized post dates) so renders are stable.
- tests/visual/capture.mjs drives Chromium via Playwright with masks
  loaded from masks.json and breakpoints from urls.json.
- tests/visual/print-report.mjs emits native GitHub Check annotations
  (no third-party PR-comment action).
- .github/workflows/visual-regression.yml runs on PRs touching themes/
  or visual config; soft-fails for two weeks (flip on or after 2026-06-02)
  while baselines stabilize.
- workflow_dispatch with bootstrap=true captures and commits baselines
  back to the branch, avoiding a local Docker run.

Local workflow:
- scripts/visual-capture.sh — capture against the running Docker stack.
- scripts/visual-update-baselines.sh — recapture inside the same
  Playwright Docker image used by CI so local baselines match CI
  rendering and avoid subpixel font drift.

Also introduces:
- package.json + pnpm-lock.yaml (pinned Playwright 1.60.0, pngjs,
  pixelmatch, @commitlint/cli, @commitlint/config-conventional). Lays
  groundwork for future Node-based CI tooling. The version field is
  intentionally 0.0.0 — repo version lives in .release-please-manifest.json
  and git tags.
- pnpm scripts: visual:capture, visual:diff, visual:update, visual:seed,
  lint:commits, test:visual, playwright:install.
- .npmrc — engine-strict, auto-install-peers.

baselines/ ships empty with a .gitkeep; first run uses the bootstrap
workflow trigger to populate. continue-on-error: true means PRs aren't
blocked during the stabilization window.

Refs #18

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@PAMulligan PAMulligan linked an issue May 20, 2026 that may be closed by this pull request
3 tasks
@PAMulligan PAMulligan merged commit 0c72a59 into main May 20, 2026
7 checks passed
@PAMulligan PAMulligan deleted the 18-integrate-visual-regression-testing branch May 20, 2026 03:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Integrate visual regression testing

1 participant