Best practices
A short checklist. The loop itself is Stills.
One spec, two speeds
Do not keep a “CI walk” and a “demo walk.” E2E_DEMO changes chrome and timing, not the story.
| Flag | Use when |
|---|---|
| unset | Writing the walk, CI, reviewing stills |
E2E_DEMO=1 | The stills already look good and you need walk.mp4 |
shot owns the teaching still
Pass shot on the click, fill, or demoPoint the video would click. Capture is after the pointer and ring are on the control, before the action. Rest-frame demoScreenshot hides the pointer. Leave shot on the video run. Playwemo does not hold the ring or write a still while recordVideo is on. On video the ring pulses, then the click, then a short pause. Setup: Stills and Video.
Keep assertions on
Never skip expect to make a recording prettier.
Configure once
Import configureDemoWalk from playwright.config.ts. Init scripts take arguments; they cannot close over Node state.
Set Playwright outputDir to test-results/playwright so stamps under test-results/e2e-demo/stills/ and video/ survive each run.
Accumulate stamps
Leave prior runs on disk. Compare stills across stamps. E2E_DEMO_CLEAN=1 only when you mean to wipe them.
Do not minify overlay or cursor inits
addInitScript(fn) serializes function source. Minify breaks paint.
Personas stay in the app
Ids are strings. Colors, selectors, and /login labels belong in the consumer’s configureDemoWalk.
Show the beat, do not describe it
In a Cursor Cloud thread, copy stills / walk.mp4 into /opt/cursor/artifacts and inline them. See Cursor.
Agents: For agents.