feat: integrate visual regression testing for theme changes#69
Merged
Conversation
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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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
tests/visual/seed.shtests/visual/capture.mjsscripts/visual-diff.js --batchtests/visual/print-report.mjs.github/workflows/visual-regression.ymlKey decisions (from scoping)
content-seederagent —tests/visual/seed.shcreates 3 fixed-slug products (test-hoodie/test-beanie/test-tee) and normalizes every publish date to2025-01-15 12:00:00 UTCso dates can never cause a diff.maskparameter — selectors live intests/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.print-report.mjsemits::error file=…::workflow commands so failures show up inline on the PR's Files Changed view. No third-party PR-comment action.visual-diff.jsregion grid. Per-URL overrides intests/visual/thresholds.jsonfor cart/checkout/my-account which need looser tolerances while WooCommerce styles settle.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.scripts/visual-update-baselines.shruns capture insidemcr.microsoft.com/playwright:v1.60.0-jammy— the same image whose Chromium ships in CI — so locally-generated baselines match CI rendering.continue-on-error: trueuntil 2026-06-02 while baselines stabilize. Date and flip instruction documented inline in the workflow and intests/visual/README.md.package.jsonintroductionAdds a
private: trueNode 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. Theversionfield is intentionally0.0.0; repo version lives in.release-please-manifest.jsonand git tags.pnpm-lock.yamlis now tracked (was previously gitignored).Bootstrap (no baselines in this PR)
tests/visual/baselines/ships empty with a.gitkeep. After merge:visual-regression→ "Run workflow" withbootstrap: truechecked.mainastest(visual): bootstrap baselines [skip ci].Alternative: run
bash scripts/visual-update-baselines.shlocally and push.Files
.github/workflows/visual-regression.yml— CI workflowpackage.json,pnpm-lock.yaml,.npmrc— Node depstests/visual/{capture.mjs,print-report.mjs,seed.sh}— pipelinetests/visual/{urls,masks,thresholds}.json— configtests/visual/README.md— docs (how to add pages, update baselines, debug failures)tests/visual/.gitignore+ repo.gitignoreupdate — scratch dirsscripts/visual-capture.sh,scripts/visual-update-baselines.sh— local wrappersCONTRIBUTING.md— added "Visual regression" subsection under TestingTest plan
commitlintcheck passes on this PR.visual-regressionworkflow runs and reportswarning: No baselines committed(expected) — does not block merge thanks tocontinue-on-error: true.visual-regressionwithbootstrap: true. Verify ~40 PNGs appear intests/visual/baselines/via the bot commit.themes/flavian-shop/templates/index.htmlcolor). Verify the workflow flags the diff with a native GH annotation and uploads the diff artifact.continue-on-error: true→falsein.github/workflows/visual-regression.yml.🤖 Generated with Claude Code