| name |
description |
| record-walkthroughs |
Record narrated screen-capture walkthroughs of an app's critical paths, driven by browser automation. Use when asked for demo videos, product walkthroughs, or Loom-style recordings, or to refresh them after a UI change. |
Recording Product Walkthroughs
Automated screen recordings of an app's critical paths, driven through the real
UI. Cheap to regenerate, so they stay current instead of rotting the week after
they were made.
When to Use
| Need |
Approach |
| Prove a change works |
Screenshot or a test |
| Show a flow to a human |
Walkthrough recording |
| Assert a flow keeps working |
E2E test, not a recording |
Recordings and tests are different artifacts. Keep both: the test fails the
build, the recording explains the product. Never make one do the other's job.
Rules
- Drive the real UI, not a script of screenshots. If the recording cannot be
produced by clicking through the app, it is a mockup — say so.
- Run against seeded/mock data, never production. Deterministic input is what
makes a re-record reproducible.
- Keep the video on failure. A broken step must be visible in the footage;
discarding failed takes hides the regression.
- Captions as a sidecar (WebVTT), never burned in. Timestamp narration
against the video clock during the run. Burnt-in text cannot be toggled,
translated, or corrected without re-recording.
- Pace for a human. Add explicit holds between actions and a visible cursor;
automation-speed clicks are unwatchable.
- State what is compressed or simulated in a README beside the output —
shortened waits, injected fixtures, faked devices.
Capture Quality
Recorder output is the master; nothing downstream recovers detail it never had.
In order of impact:
- Pixels on the subject. A UI scaled down to fit a frame gets few pixels and
looks grainy. Author the stage in a fixed design space and scale the whole
tree to the capture viewport — browsers re-rasterise a transformed subtree at
its composited scale, so glyphs are drawn at final size rather than
upscaled. Then capture well above delivery resolution.
- Downsample on encode. Delivering below capture resolution averages out the
recorder's compression noise. This is usually what removes "grain".
- Encode near-lossless (x264 CRF ~16 for flat UI). Compare the output
bitrate against the source — an encode emitting well under its input is
destroying more than the capture did.
Measure before tuning: ffprobe -show_entries format=bit_rate on both ends.
Traps
- Fixed headers/footers swallow clicks. Automation visibility checks pass for
an element sitting under a fixed overlay, then the click lands on nothing and
the step silently no-ops. Scroll the element into genuine reach.
- Multi-device flows need an explicit handoff. Where one actor produces
something a second consumes (a QR code, a link, a code), have the first step
write an artifact and the second consume it. Two independent runs prove
nothing about the pair.
- Simulated hardware must match what the app requests. A fake camera feed
below the app's requested resolution gets upscaled, and decoding turns
intermittent.
- Runners commonly wipe their output directory per invocation. If flows run
as separate invocations, stash each take before the next starts.
- Mock layers sitting above the network are invisible to request
interception. Route stubs only work if a request is actually made.
Reference Implementation
pay2u — apps/web/tests/demo/ (Playwright + mock mode + a root-scaled stage
page), with a project-level skill of the same name carrying that app's selectors
and flow specifics. Copy the shape, not the selectors.
1---2name: record-walkthroughs3description: | name | description |4---5| name | description |6| --- | --- |7| record-walkthroughs | Record narrated screen-capture walkthroughs of an app's critical paths, driven by browser automation. Use when asked for demo videos, product walkthroughs, or Loom-style recordings, or to refresh them after a UI change. |89# Recording Product Walkthroughs1011Automated screen recordings of an app's critical paths, driven through the real12UI. Cheap to regenerate, so they stay current instead of rotting the week after13they were made.1415## When to Use16| Need | Approach |17|------|----------|18| Prove a change works | Screenshot or a test |19| Show a flow to a human | Walkthrough recording |20| Assert a flow keeps working | E2E test, not a recording |2122Recordings and tests are different artifacts. Keep both: the test fails the23build, the recording explains the product. Never make one do the other's job.2425## Rules2627- **Drive the real UI, not a script of screenshots.** If the recording cannot be28 produced by clicking through the app, it is a mockup — say so.29- **Run against seeded/mock data**, never production. Deterministic input is what30 makes a re-record reproducible.31- **Keep the video on failure.** A broken step must be visible in the footage;32 discarding failed takes hides the regression.33- **Captions as a sidecar (WebVTT), never burned in.** Timestamp narration34 against the video clock during the run. Burnt-in text cannot be toggled,35 translated, or corrected without re-recording.36- **Pace for a human.** Add explicit holds between actions and a visible cursor;37 automation-speed clicks are unwatchable.38- **State what is compressed or simulated** in a README beside the output —39 shortened waits, injected fixtures, faked devices.4041## Capture Quality4243Recorder output is the master; nothing downstream recovers detail it never had.44In order of impact:45461. **Pixels on the subject.** A UI scaled down to fit a frame gets few pixels and47 looks grainy. Author the stage in a fixed design space and scale the whole48 tree to the capture viewport — browsers re-rasterise a transformed subtree at49 its composited scale, so glyphs are *drawn* at final size rather than50 upscaled. Then capture well above delivery resolution.512. **Downsample on encode.** Delivering below capture resolution averages out the52 recorder's compression noise. This is usually what removes "grain".533. **Encode near-lossless** (x264 CRF ~16 for flat UI). Compare the output54 bitrate against the source — an encode emitting well under its input is55 destroying more than the capture did.5657Measure before tuning: `ffprobe -show_entries format=bit_rate` on both ends.5859## Traps6061- **Fixed headers/footers swallow clicks.** Automation visibility checks pass for62 an element sitting under a fixed overlay, then the click lands on nothing and63 the step silently no-ops. Scroll the element into genuine reach.64- **Multi-device flows need an explicit handoff.** Where one actor produces65 something a second consumes (a QR code, a link, a code), have the first step66 write an artifact and the second consume it. Two independent runs prove67 nothing about the pair.68- **Simulated hardware must match what the app requests.** A fake camera feed69 below the app's requested resolution gets upscaled, and decoding turns70 intermittent.71- **Runners commonly wipe their output directory per invocation.** If flows run72 as separate invocations, stash each take before the next starts.73- **Mock layers sitting above the network are invisible to request74 interception.** Route stubs only work if a request is actually made.7576## Reference Implementation7778`pay2u` — `apps/web/tests/demo/` (Playwright + mock mode + a root-scaled stage79page), with a project-level skill of the same name carrying that app's selectors80and flow specifics. Copy the shape, not the selectors.