Last updated 2026-05-07
video-capture
Records a walkthrough video and screenshots of a web, Android, or iOS
app, driven by a YAML scenario. Implementation lives in
platform/actions/video-capture/.
Inputs
| Input | Required | Default | Notes |
|---|---|---|---|
platform | yes | web | android | ios | |
scenario | yes | Path to the scenario YAML file. | |
app-url | web only | URL the browser opens. | |
output-dir | no | ./artifacts/video-capture | Where the video, thumbnail, and screenshots are written. |
video-quality | no | medium | low | medium | high |
viewport-width | web only | 1280 | |
viewport-height | web only | 720 | |
device | mobile | e.g. "Pixel 7" or "iPhone 15". | |
headless | web only | true | Set false for a visible browser (for debugging). |
Outputs
| Output | Description |
|---|---|
video-path | Path to the generated demo video. |
screenshot-paths | JSON array of screenshot file paths. |
thumbnail-path | Path to a still thumbnail. |
duration | Video duration in seconds. |
Scenario format
Scenarios are YAML files with a name,
description, and an ordered list of steps. The runner
interprets each step against the chosen platform.
name: "Onboarding walkthrough"description: "First-run experience for new users"steps: - action: pause duration: 2000 screenshot: launch-screen
- action: click selector: "[data-testid='get-started']" wait: 1000 screenshot: account-form
- action: type selector: "input[name='email']" text: "demo@example.com"
- action: click selector: "button[type='submit']" wait: 2500 screenshot: dashboard
- action: scroll direction: down amount: 400 wait: 800
- action: hover selector: "[data-testid='profile']" wait: 500 screenshot: profile-hover
- action: navigate url: "{{app-url}}/settings" wait: 2000 screenshot: settingsRecognised action values:
pause— wait fordurationms.click— clickselector.type— typetextintoselector.hover— hover overselector.scroll— scrolldirectionbyamountpx.navigate— go tourl(placeholders like{{app-url}}are substituted).
All steps accept an optional wait (ms after the action)
and an optional screenshot name.
Web example
name: Demo Videoon: workflow_dispatchjobs: capture: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: { node-version: '22' } - run: pnpm install && pnpm build - run: pnpm start & - run: npx wait-on http://localhost:3000
- id: video uses: ./platform/actions/video-capture with: platform: web app-url: http://localhost:3000 scenario: ./scenarios/onboarding.yml video-quality: high
- uses: actions/upload-artifact@v4 with: name: demo-video path: ${{ steps.video.outputs.video-path }}Android example
- uses: ./platform/actions/video-capture with: platform: android device: "Pixel 7" scenario: ./scenarios/android.ymliOS example
- uses: ./platform/actions/video-capture with: platform: ios device: "iPhone 15" scenario: ./scenarios/ios.ymlHow outputs flow into the dashboard
When this action runs as part of a feature workflow, the dashboard
discovers the video and screenshots via
/api/features/[slug]/video and
/api/features/[slug]/screenshots/[filename], and renders
them on the feature page. See Recipe — Capturing a video demo for a full end-to-end flow.