Skip to main content

Video Recording

Record browser sessions as WebM videos with chapter markers and action callouts.

Commands

CommandDescription
video-start [filename]Start recording
video-stopStop and save
video-chapter <title>Show a full-screen chapter card and mark the position
video-show-actionsAnnotate subsequent actions with a callout and highlight
video-hide-actionsStop 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
OptionDescription
--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

MethodUse 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

FeatureVideoTracing
OutputWebM fileTrace files viewable in the Trace Viewer
ShowsVisual recordingDOM snapshots, network, console, actions
Best forDemos, documentation, bug reportsDebugging and analysis
SizeLargerSmaller

Use cases

ScenarioApproach
Bug reproductionRecord steps, attach to issue
Test documentationRecord with chapter markers
Agent monitoringRecord agent sessions for review
Demo creationScript the scenario with run-code and overlays