Reorders all documented and scripted `make` invocations from the `VAR=value make target` shell-env prefix form to the make-native `make target VAR=value` form. GNU Make auto-exports both command-line and inherited shell-env variables to recipe shells, so the change is purely about command-line shape: only the make-suffix form starts with `make` and is therefore matched by the `Bash(make*)` permission entry in .claude/settings.json, avoiding unnecessary approval prompts for agent runs. Adds an explicit CLAUDE.md rule with ✅/❌ examples and the underlying reason (permission prefix match, not Makefile semantics). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
4.5 KiB
Playwright Tests 🎭
This page is the SPOT for Playwright end-to-end test requirements, runner integration, and file contracts.
For implementation guidance when writing or updating role-local files, see
Agent playwright.spec.js and
Agent playwright.env.j2.
Framework 🧰
- Playwright runs inside Docker via the shared
test-e2e-playwrightrole. - There is no standalone
maketarget for Playwright. Tests run as part of local deploy flows (e.g.make deploy-fresh-purged-apps APPS=web-app-matomo FULL_CYCLE=true).
When to Write ✍️
- You MUST provide Playwright tests for every
web-*role. - You MUST update the Playwright suite when you add or change role-local
javascript.jsorstyle.css.
Role-Local Files 📁
Every Playwright-enabled role MUST provide exactly these two files:
| File | Purpose |
|---|---|
files/playwright.spec.js |
Test scenarios executed by the Playwright runner |
templates/playwright.env.j2 |
Rendered .env passed to the Playwright container |
package.json and playwright.config.js MUST remain centralized in roles/test-e2e-playwright/files/.
You MUST NOT duplicate or override them per role.
CI Image Source 🪞
The Playwright container image is declared in roles/test-e2e-playwright/defaults/main.yml as mcr.microsoft.com/playwright with an exact version tag. CI mirrors that image into GHCR through the standard mirror pipeline before deploy tests run, so Playwright jobs do not depend on direct pulls from MCR during the test phase.
The tag MUST stay pinned to an exact Playwright version and distro pair such as v1.58.2-noble. You MUST NOT switch this to a mutable tag such as latest, because mutable upstream tags are more vulnerable to CDN propagation delays and make flaky CI failures much harder to reason about.
Runner 🚀
The test-e2e-playwright role discovers Playwright-enabled roles through the presence of
templates/playwright.env.j2. For each discovered role it:
- stages the test project
- renders
.envfromplaywright.env.j2 - copies
files/playwright.spec.jsinto the project astests/playwright.spec.js - injects the shared
package.jsonandplaywright.config.js - waits until the app is reachable
- runs Playwright in Docker
File Requirements 📄
See the dedicated SPOT pages for authoring rules:
playwright.spec.js: scenario design, selector strategy, and live reviewplaywright.env.j2: rendered test input surface, variable naming, and entry-point selection
Recording Tests 🎬
Playwright Codegen (built-in) 🔧
Playwright ships a built-in code recorder:
npx playwright codegen https://<app-url>
This opens the Playwright Inspector alongside a browser. Every interaction is recorded and emitted as a runnable spec. Use the output as a starting draft and clean it up according to the authoring rules in playwright.spec.js.
playwright-recorder (Docker-based) 🐳
For infrastructure-heavy setups where Playwright should not live in the main repository, use playwright-recorder. It wraps Playwright codegen in Docker with X11/XWayland forwarding and an ephemeral workspace so no state leaks between recordings.
Requirements: Docker, X11 or XWayland, xhost
# Install
make install
# Record a flow starting at a specific URL
make codegen
# or directly:
./scripts/codegen.sh https://<app-url>/login
# Replay a recorded spec headlessly
make replay
# or directly:
./scripts/replay.sh recordings/login.spec.ts
Generated files are persisted in the local workspace (git-ignored). Copy the relevant parts into files/playwright.spec.js and adapt them.
Development Procedure 📋
- Analyze the deployed application in a running local stack.
- Build hypotheses about the expected user flows before writing tests.
- Optionally record a draft with Playwright codegen or
playwright-recorder. - Write or update
files/playwright.spec.jsandtemplates/playwright.env.j2. - Run the relevant deploy flow (e.g.
make deploy-fresh-purged-apps APPS=<role> FULL_CYCLE=true). - Run
make trust-caand open the app in your browser to confirm the flow manually. - Inspect the browser console for errors when the flow depends on injected JavaScript.
- Verify the suite finishes in a logged-out state.