Record captioned product walkthrough videos of any web app with Playwright + ffmpeg — proof videos for stakeholders, feature demos, bug-fix evidence
67
84%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
Passed
No findings from the security scan
Record a captioned walkthrough video of a running web app, verify it frame-by-frame, convert to mp4, and deliver it. Battle-tested on real client-feedback proof videos.
This is the harness's default visual validation for web projects: a demo video walks a real user flow end-to-end and doubles as a passing E2E test, so "it works" is proven visually, not claimed. It complements [[visual-validation]] (autonomous screenshot-regression checks) and [[playwright-testing]] (the E2E suite): screenshots catch pixel regressions, the suite proves behavior, and a demo video proves the whole user-facing flow the way a person would see it.
e2e/zz-<name>-video.spec.ts or scratchpad) that
walks the real flows as one continuous test. One test = one video.test.use({ video: { mode: 'on', size: { width: 1280, height: 800 } }, viewport: { width: 1280, height: 800 } })
test.setTimeout(240000)async function caption(page: Page, text: string) {
await page.evaluate((t) => {
let bar = document.getElementById('demo-caption')
if (!bar) {
bar = document.createElement('div')
bar.id = 'demo-caption'
bar.style.cssText =
'position:fixed;left:0;right:0;bottom:0;z-index:99999;background:#142b1e;color:#f7f5f0;' +
'font:600 15px/1.4 Inter,system-ui,sans-serif;padding:12px 20px;letter-spacing:0.01em'
document.body.appendChild(bar)
}
bar.textContent = t
}, text)
await page.waitForTimeout(2200)
}caption() re-creates it after
each page.goto (the element does not survive navigation — call caption AFTER navigating).scrollIntoViewIfNeeded
or step-scroll) before asserting/capturing.await expect(page.locator('#code')).toBeVisible()) before
reading outboxes/fixtures — racing the write is the #1 flake.a[href^="/x/"]:not([href$="/new"])).rm -rf test-results/zz-<name>* # stale videos have the same filename
npx playwright test e2e/zz-<name>-video.spec.ts
find test-results -name "video.webm" # the recording
# Convert to mp4 (universal playback, ~2-3x smaller)
ffmpeg -y -i "<video.webm>" -c:v libx264 -pix_fmt yuv420p -movflags +faststart out.mp4
# ALWAYS spot-check frames before delivering — extract a few and LOOK at them
ffmpeg -y -i out.mp4 -vf "select='eq(n\,60)+eq(n\,300)+eq(n\,600)'" -vsync vfr frame_%d.pngRead the extracted frames with the Read tool and confirm captions render and each chapter shows what it claims. Never deliver an unviewed video.
~/Documents/updates/<project>/,
the house archive for stakeholder updates), and send it to the user (SendUserFile or
equivalent).YYYY-MM-DD-NN-<project>-<what-it-proves>.mp4
— the date it was recorded, then a two-digit index so several videos on the same day
stay ordered and every video is uniquely identifiable at a glance. Allocate the
next free index with a no-clobber loop — never a count (wc -l), which reuses
an index if an earlier file was deleted and silently overwrites an existing mp4:
DIR=~/Documents/updates/<project>; DATE=$(date +%F); mkdir -p "$DIR"
NN=1
while printf -v F '%s/%s-%02d-<project>-<what-it-proves>.mp4' "$DIR" "$DATE" "$NN" && [ -e "$F" ]; do
NN=$((NN+1))
done
cp out.mp4 "$F"video.mp4, never a name without its date and index.@playwright/test) with a working dev/preview server.ffmpeg on PATH for the webm→mp4 conversion and frame extraction.alinaqi/maggy
55aabe2
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.