| name | ui-demo |
| description | Record a polished demo/walkthrough video of a web application with a browser automation driver (Playwright). Produces a WebM with a visible arrow cursor, natural human pacing, on-screen step subtitles, and a storytelling flow — not a jittery instant-fill capture. The defining discipline is a three-phase method: Discover the real page (dump the actual interactive elements before scripting), Rehearse (verify every selector resolves, failing loudly), then Record. Use when someone asks for a demo video, screen recording, product walkthrough, or tutorial video of a running web app for docs, onboarding, or a stakeholder showcase.
|
| metadata | {"activation_triggers":["record a demo video / walkthrough / screen recording / tutorial of a web app","showcase a feature or workflow visually as a video","produce a WebM with a visible cursor and natural pacing","a demo recording keeps breaking on missing selectors or a too-fast capture","need a video for documentation, onboarding, or a stakeholder demo"]} |
| version | 1.0.0 |
| risk_class | low |
| source | affaan-m/ecc@81af4076 skills/ui-demo/ |
| license | MIT |
UI Demo Video Recorder
Drive a headless browser through an app and record the session as a WebM, with
an injected cursor overlay, deliberate pacing, and step subtitles so the result
looks like a guided tour rather than a script running at machine speed.
Risk note (why risk_class: low). This skill drives a real browser and
types into real forms, including login screens, and can record whatever is
on screen. Never hardcode real credentials or PII into a demo script, never
point it at production data you would not want in a shared video, and prefer
a seeded demo/staging account. Treat the recorded artifact as shareable — so
nothing secret should ever appear in frame.
When to Activate
- Someone asks for a "demo video", "screen recording", "walkthrough", or
"tutorial" of a web app.
- Someone wants to show a feature or workflow visually for docs, onboarding, or
a stakeholder update.
- A prior recording keeps breaking because selectors were assumed, or it looks
bad because it runs too fast with a teleporting/dot cursor.
The three phases — never skip to recording
Every demo goes Discover -> Rehearse -> Record. Skipping discovery is why
recordings break silently; skipping rehearsal is why they break on camera.
Phase 1 — Discover
You cannot script what you have not seen. A field you assumed was a <textarea>
may be an <input>; a dropdown you assumed was a <select> may be a custom
component; a comment box may support @mentions or #tags. Wrong assumptions
fail silently mid-recording.
Navigate to each page in the flow and dump its visible interactive
elements before writing a single step. In the page context, collect the tag,
type, name, placeholder, trimmed text, contenteditable, and role for every
visible input, select, textarea, button, [contenteditable], and log it as
JSON.
Then look specifically for:
- Field kind — real
<select> vs. custom dropdown vs. combobox.
- Select options — dump both
value and visible text. Placeholder options
often carry value="0" or value="" and look real; skip options whose text
starts with "Select" or whose value is "0".
- Rich text — does the comment box support
@mentions, #tags, markdown,
or emoji? The placeholder usually tells you.
- Required fields — which fields block submit? Try submitting empty to
surface validation.
- Dynamic fields — do some appear only after others are filled?
- Exact button labels —
Submit vs. Submit Request vs. Send.
- Table columns — for table-driven modals, map each numeric input to its
column header rather than assuming all numeric inputs mean the same thing.
Output a small field map per page — the source of truth for the selectors
you will script.
Phase 2 — Rehearse
Run the whole flow without recording and verify every selector resolves.
Silent selector failures are the number-one cause of broken recordings, and
rehearsal catches them cheaply.
Wrap each lookup in a helper that logs loudly and, on failure, dumps the
currently-visible interactive elements so you can find the correct selector
immediately. Walk an ordered list of { label, selector } steps; if any step
fails to resolve, print the visible-element dump and exit non-zero. Only
proceed to recording once every selector passes. When one fails: read the dump,
fix the selector, re-run rehearsal.
See references/playwright-helpers.md for ensureVisible and a rehearsal
harness.
Phase 3 — Record
Only after discovery and rehearsal pass.
Storytelling flow. Plan the video as a story. Follow the requested order,
or default to: Entry (log in / land on the start page) -> Context (pan the
surroundings so viewers orient) -> Action (the main workflow) -> Variation
(a secondary feature — settings, theme, locale) -> Result (the outcome or
confirmation).
Pacing. Deliberate pauses are what make it watchable:
| Moment | Pause |
|---|
| After login | ~4s |
| After navigation | ~3s |
| After clicking a button | ~2s |
| Between major steps | ~1.5-2s |
| After the final action | ~3s |
| Typing | ~25-40ms/char |
Visible cursor. Inject an SVG arrow cursor (a real arrow, not a dot) that
follows mousemove. The overlay is destroyed on navigation, so re-inject it
after every page load — this is the single most common thing people forget.
Never teleport the cursor. Move the mouse to the target in steps, pause,
then click. Give every click a descriptive label for debugging.
Type visibly. Clear the field, then type character-by-character with a small
delay — never instant-fill.
Scroll smoothly (behavior: 'smooth'), and when showing a dashboard, pan
the cursor across a few key elements so the eye follows.
Step subtitles. Inject a bottom subtitle bar (also re-injected after every
navigation) and set short Step N - Action captions (< ~60 chars) at each
major transition; clear it during long pauses where the UI speaks for itself.
The reusable helpers — injectCursor, injectSubtitleBar/showSubtitle,
moveAndClick, typeSlowly, panElements, and a full script skeleton with a
--rehearse flag — are in references/playwright-helpers.md.
Recording settings
- Headless browser, viewport and video size both
1280x720.
- Record to a video directory; after the run, copy the randomly-named video
file to a stable output name (e.g.
demo-<feature>.webm) so the artifact
path is predictable.
- Popups open as separate pages and produce separate video files — capture
popup pages explicitly and merge later if the flow needs them.
Pre-recording checklist
Common pitfalls
- Cursor vanishes after navigation — re-inject it.
- Video too fast — add pauses.
- Cursor is a dot — use the SVG arrow overlay.
- Cursor teleports — move before clicking.
- Modals feel abrupt — add a read pause before confirming.
- Random video filename — copy to a stable output name.
- Selector failures swallowed — never use silent catch blocks.
- Field types assumed — discover them first.
- Features assumed — inspect the real UI before scripting.
- Placeholder select values look real — watch for
"0" and "Select...".
Changelog
- 1.0.0 — Initial authored version. Teaches the Discover -> Rehearse ->
Record method, natural pacing, visible-cursor and subtitle overlays,
move-then-click and visible-typing discipline, and stable artifact output.
Clean-room rewrite; helper implementations live in
references/playwright-helpers.md.
Skill-Import-Attestation: reviewed-by=AE9B236FDAF0462874060C6BCFCFACF00335DC74; sha256=16c19c5fc562e2710e9ebb32483a80790a31cc531ccd4b0e82348baab5738c65