1---2name: playwright-visual-testing3description: Add, repair, or review Playwright visual regression tests for browser-facing .NET apps, including screenshot baselines, Pixelmatch thresholds, deterministic rendering, and GitHub Actions artifacts. USE FOR: toHaveScreenshot, page.screenshot visual checks, Pixelmatch/pngjs comparison scripts, visual baseline updates, screenshot diff triage, or CI workflows for UI regression screenshots. DO NOT USE FOR: pure unit tests, accessibility audits, browser-debugging sessions, or frontend linting.4---56# Playwright Visual Testing78## Trigger On910- the user asks for pixel, screenshot, visual, or UI regression testing with Playwright11- a .NET repo needs visual baselines for ASP.NET Core, Blazor, WebAssembly, static pages, or generated frontend assets12- GitHub Actions should run Playwright screenshots and expose expected, actual, and diff artifacts13- tests fail with screenshot mismatches, noisy baselines, or unstable visual snapshots1415## Do Not Use For1617- pure .NET unit or integration tests without a browser surface18- accessibility, SEO, PWA, or security-header audits; route those to `webhint`19- browser debugging or live DOM inspection; route that to `chrome-devtools-mcp`20- JavaScript, TypeScript, CSS, or HTML linting; route those to `biome`, `eslint`, `stylelint`, or `htmlhint`2122## Load References2324- Read [CI and snapshot patterns](references/ci-and-snapshot-patterns.md) when adding a new visual test suite, wiring GitHub Actions, choosing between Playwright snapshots and a standalone Pixelmatch script, or stabilizing screenshot diffs.2526## Current Upstream Notes2728- The August 2026 Playwright CI and visual-comparison docs still require browser dependencies to be installed explicitly in CI and warn that screenshot rendering varies by host OS, browser build, fonts, headless mode, and hardware. Generate and review baselines in the same environment used for comparison.29- The CI guide recommends against caching browser binaries by default: restoring them often costs as much as downloading, and OS dependencies still need an explicit install. If a runner must cache browsers, key it by the exact Playwright version and keep dependency installation in the job.30- Current CI examples use `actions/checkout@v6`, `actions/setup-node@v6`, and `actions/upload-artifact@v5`; use a full checkout only when `--only-changed` needs the pull-request base ref.31- Keep Playwright parallel by default. Do not set `workers: 1` merely because CI or screenshots are involved. Isolate test data and browser contexts, enable `fullyParallel` when tests are independent, and shard large suites across CI jobs. Reduce concurrency only for the smallest tests that destructively change the same external state.32- Playwright `v1.62.1` fixes TypeScript configuration resolution regressions, accessibility snapshots that dropped names or image-style actionable elements, and branded primitive arguments passed to `page.evaluate()`. Re-run config discovery, accessibility snapshots, and TypeScript compile checks before accepting new visual baselines.33- Keep `--update-snapshots` as an intentional local review action. Pull-request CI should retain expected, actual, diff, trace, and report artifacts instead of silently accepting a new baseline.3435## Workflow3637```mermaid38flowchart TD39 A["Need visual regression coverage"] --> B{"Uses Playwright Test"}40 B -->|"Yes"| C["Prefer expect(page).toHaveScreenshot"]41 B -->|"No or custom compare needed"| D["Capture page.screenshot output"]42 D --> E["Compare with pixelmatch and pngjs"]43 C --> F["Stabilize viewport, data, animation, and volatile regions"]44 E --> F45 F --> G["Commit reviewed baselines"]46 G --> H["Run in CI and upload reports or image diffs"]47 H --> I["Triage expected, actual, and diff before changing thresholds"]48```49501. Inspect the current browser-test surface:51 - nearest `AGENTS.md`52 - `package.json`, lockfile, Playwright config, test folders, and CI workflows53 - how the app starts locally: `dotnet run`, Aspire AppHost, static preview, or frontend dev server542. Choose the comparison path deliberately:55 - default to Playwright Test `expect(page).toHaveScreenshot()` when the repo can use Playwright Test snapshots56 - use `page.screenshot()` plus a standalone Pixelmatch script only when the repo needs article-style central `screenshots/baseline`, `screenshots/actual`, and `screenshots/diff` folders, non-Playwright image inputs, or custom reporting outside Playwright Test573. Make screenshots deterministic before tuning thresholds:58 - fix viewport, browser project, locale/time zone, color scheme, and device scale factor59 - use stable test data and wait for the app-specific ready state60 - disable animations or use Playwright screenshot options for animations61 - mask or hide volatile regions such as ads, time, avatars, random IDs, spinners, and third-party iframes624. Keep baseline updates explicit:63 - generate missing baselines once, review them, and commit them64 - update intended Playwright snapshots with `npx playwright test --update-snapshots`65 - do not auto-create or auto-update baselines in pull-request CI665. Wire CI for repeatability:67 - use `npm ci`, then `npx playwright install --with-deps`, then the focused Playwright command68 - preserve Playwright's parallel workers; use `fullyParallel` for isolated tests and CI sharding for large suites69 - constrain only a narrow destructive shared-state collision, never the whole visual suite for generic stability70 - optionally run `npx playwright test --only-changed=origin/$GITHUB_BASE_REF` first on pull requests for faster feedback, but always follow it with the full suite because changed-test selection is heuristic71 - use the same OS, browser build, fonts, headless mode, and rendering environment that produced the committed baselines; an official Playwright container is useful when host drift keeps changing pixels72 - upload the Playwright HTML report and `test-results/`, or upload `screenshots/baseline`, `screenshots/actual`, and `screenshots/diff` for a custom Pixelmatch flow736. Triage failures from artifacts:74 - inspect expected, actual, and diff images together75 - classify the mismatch as intentional design change, rendering nondeterminism, app bug, or baseline drift76 - fix nondeterminism before increasing `maxDiffPixels`, `maxDiffPixelRatio`, or Pixelmatch mismatch thresholds7778## Deliver7980- a Playwright visual-test path that matches the repo's existing package manager and test layout81- committed reviewed baseline images or a clear command to generate and review them82- deterministic screenshot controls for dynamic UI regions83- GitHub Actions report or diff artifacts that make failures reviewable84- a short note on whether the implementation uses built-in Playwright snapshots or a custom Pixelmatch comparison script8586## Validate8788- `npm ci`89- `npx playwright install --with-deps`90- `npx playwright test` or the repo's focused visual-test script91- `npx playwright test --update-snapshots` only when accepting intentional baseline changes92- in CI changes, confirm artifact upload uses maintained GitHub Actions versions and runs on pull requests without requiring secrets9394## Common Pitfalls9596- capturing screenshots before the UI is stable97- generating baselines on one OS and comparing them on another98- sharing one mutable browser context across tests99- masking too much of the page and removing the regression signal100- raising thresholds to hide animation, font, clock, or data nondeterminism101- forcing one CI worker instead of fixing data/context isolation or sharding the suite102- using a custom Pixelmatch script when Playwright's built-in screenshot assertion would give better trace, report, and snapshot integration