Video Recording
Record browser sessions as WebM videos with chapter markers and action callouts.
Commands
| Command | Description |
|---|---|
video-start [filename] | Start recording |
video-stop | Stop and save |
video-chapter <title> | Show a full-screen chapter card and mark the position |
video-show-actions | Annotate subsequent actions with a callout and highlight |
video-hide-actions | Stop annotating actions |
Basic recording
playwright-cli open https://example.com
playwright-cli video-start demo.webm
playwright-cli click e5
playwright-cli fill e3 "test"
playwright-cli video-stop
# Video saved to: .playwright-cli/demo.webm
Without a filename the video is saved as video-{timestamp}.webm in the output directory.
Video size
playwright-cli video-start --size=800x600
If --size is omitted, the recording is scaled to fit 800x800.
Chapter markers
video-chapter blurs the page and shows a chapter card for the given duration, then removes it —
useful for section transitions in a walkthrough.
playwright-cli video-start
playwright-cli video-chapter "Step 1: Login" --description="Signing in as a returning user" --duration=2000
playwright-cli goto https://app.example.com/login
playwright-cli fill e3 "user@example.com"
playwright-cli fill e5 "password"
playwright-cli click e7
playwright-cli video-chapter "Step 2: Navigate to settings"
playwright-cli goto /settings
playwright-cli video-chapter "Step 3: Update profile"
playwright-cli fill e10 "New Display Name"
playwright-cli click e15
playwright-cli video-stop
Action callouts
video-show-actions makes every subsequent command narrate itself in the recording: a callout
names the action and the target element is highlighted, with an animated pointer moving between
action points.
playwright-cli video-start walkthrough.webm
playwright-cli video-show-actions --duration=600 --position=top-right
playwright-cli click e5
playwright-cli fill e3 "test"
playwright-cli video-hide-actions
playwright-cli video-stop
| Option | Description |
|---|---|
--duration=<ms> | How long each callout stays on screen (default 500) |
--position=<pos> | top-left, top, top-right, bottom-left, bottom, bottom-right (default top-right) |
--cursor=<mode> | pointer animates a mouse pointer (default), none disables it |
Scripted videos
For a polished recording — controlled pacing, realistic typing, custom overlays — drive the whole
scenario from a single script with run-code instead of issuing commands one
at a time. Explore the page with the CLI first to collect the locators, then write the script:
// hero.js
async page => {
await page.screencast.start({ path: 'video.webm', size: { width: 1280, height: 800 } });
await page.goto('https://demo.playwright.dev/todomvc');
// Chapter card: blurs the page, blocks for the duration, then auto-removes.
await page.screencast.showChapter('Adding Todo Items', {
description: 'We will add several items to the todo list.',
duration: 2000,
});
const input = page.getByRole('textbox', { name: 'What needs to be done?' });
await input.pressSequentially('Walk the dog', { delay: 60 });
await input.press('Enter');
await page.waitForTimeout(1000);
// Sticky overlay: pointer-events are disabled, so it never blocks interaction.
const annotation = await page.screencast.showOverlay(`
<div style="position: absolute; top: 8px; right: 8px; padding: 6px 12px;
background: rgba(0,0,0,0.7); border-radius: 8px; font-size: 13px; color: white;">
✓ Item added successfully
</div>
`);
await input.pressSequentially('Buy groceries', { delay: 60 });
await input.press('Enter');
await page.waitForTimeout(1500);
await annotation.dispose();
await page.screencast.stop();
}
playwright-cli run-code --filename=hero.js
Overlay API
| Method | Use case |
|---|---|
page.screencast.start(options) / stop() | Start and stop the recording |
page.screencast.showChapter(title, { description?, duration?, styleSheet? }) | Full-screen chapter card with a blurred backdrop |
page.screencast.showOverlay(html, { duration? }) | Custom HTML overlay — callouts, labels, highlights |
page.screencast.showActions(options) / hideActions() | The API behind video-show-actions |
disposable.dispose() | Remove a sticky overlay added without a duration |
page.screencast.hideOverlays() / showOverlays() | Temporarily hide or show all overlays |
Overlays are pointer-events: none, so they can stay visible while you click, fill, or interact
with the page. To position one over a specific element, read its box first:
const bounds = await page.getByText('Walk the dog').boundingBox();
Video vs tracing
| Feature | Video | Tracing |
|---|---|---|
| Output | WebM file | Trace files viewable in the Trace Viewer |
| Shows | Visual recording | DOM snapshots, network, console, actions |
| Best for | Demos, documentation, bug reports | Debugging and analysis |
| Size | Larger | Smaller |
Use cases
| Scenario | Approach |
|---|---|
| Bug reproduction | Record steps, attach to issue |
| Test documentation | Record with chapter markers |
| Agent monitoring | Record agent sessions for review |
| Demo creation | Script the scenario with run-code and overlays |