@reshotdev/screenshot
v0.0.1-beta.7
Published
CI/CD screenshot and video capture CLI
Maintainers
Readme
@reshotdev/screenshot
Product screenshots in documentation go stale within days of a deploy. Manually recapturing them across themes, viewports, and locales is tedious and error-prone. This CLI automates screenshot and video capture in CI/CD, comparing against baselines to detect visual drift before it reaches production docs.
Status: Beta (0.x). The API may change between minor versions.
Install
npm install -g @reshotdev/screenshotRequires Node.js >= 18. Playwright browsers are installed automatically on first run.
Quick Start
# 1. Interactive setup wizard
reshot setup
# 2. Capture screenshots from your config
reshot run
# 3. Review captures in the web UI
reshot studioConfiguration
Create reshot.config.json in your project root:
{
"baseUrl": "http://localhost:3000",
"assetDir": ".reshot/output",
"concurrency": 2,
"viewport": { "width": 1280, "height": 720 },
"timeout": 30000,
"headless": true,
"scenarios": [
{
"key": "homepage",
"name": "Homepage",
"url": "/",
"steps": [
{ "action": "wait", "ms": 1000 },
{ "action": "screenshot", "key": "hero", "description": "Hero section" }
]
},
{
"key": "dashboard",
"name": "Dashboard",
"url": "/dashboard",
"requiresAuth": true,
"readySelector": "[data-loaded='true']",
"steps": [
{ "action": "screenshot", "key": "overview", "description": "Dashboard overview" },
{ "action": "click", "selector": "button[data-tab='analytics']" },
{ "action": "wait", "ms": 500 },
{ "action": "screenshot", "key": "analytics", "description": "Analytics tab" }
]
}
]
}Commands
| Command | Description | Key Flags |
| --- | --- | --- |
| reshot setup | Interactive config wizard | --offline, --force |
| reshot run | Execute capture scenarios | --scenarios, --diff, --all-variants, --concurrency, --no-headless |
| reshot record [title] | Interactive recording via Chrome DevTools | --browser, --url, --port |
| reshot sync | Upload traces/docs to Reshot platform | --trace-dir, --dry-run |
| reshot studio | Launch web management UI | --port, --no-open |
| reshot validate | Check config and bindings | --strict, --fix |
| reshot status | View project status and sync history | --jobs, --drifts, --json |
| reshot publish | Upload assets with versioning | --tag, --message, --dry-run |
| reshot pull | Generate asset map for builds | --format json\|ts\|csv, --output, --status |
| reshot drifts | Manage visual drift notifications | approve, reject, ignore, approve-all |
| reshot import-tests | Import Playwright tests as scenarios | --dry-run, --no-interactive |
| reshot ci setup | Generate CI/CD workflow files | — |
| reshot ci run | Capture + publish in one step (CI) | --tag, --no-publish, --dry-run |
Step Types
Steps define a sequence of browser actions within a scenario:
| Step | Description | Key Properties |
| --- | --- | --- |
| wait | Pause execution | ms |
| screenshot | Capture current viewport | key, description |
| click | Click a DOM element | selector, optional |
| type | Type text into an input | selector, text |
| keyboard | Send keyboard input | key (e.g., "Meta+k", "Enter") |
| waitForSelector | Wait for element to appear | selector, timeout |
| navigate | Go to a URL | url |
| fillForm | Fill multiple form fields | fields (selector-to-value map) |
Variant System
Capture the same scenario across multiple dimensions (themes, locales, roles) without duplicating config:
{
"variants": {
"dimensions": {
"theme": {
"label": "Color Theme",
"options": {
"light": {
"name": "Light Mode",
"inject": [
{ "method": "localStorage", "key": "theme", "value": "light" },
{ "method": "browser", "colorScheme": "light" }
]
},
"dark": {
"name": "Dark Mode",
"inject": [
{ "method": "localStorage", "key": "theme", "value": "dark" },
{ "method": "browser", "colorScheme": "dark" }
]
}
}
},
"locale": {
"label": "Language",
"options": {
"en": {
"name": "English",
"inject": [
{ "method": "browser", "locale": "en-US" }
]
},
"de": {
"name": "German",
"inject": [
{ "method": "browser", "locale": "de-DE", "timezone": "Europe/Berlin" }
]
}
}
}
},
"presets": {
"all-themes": { "name": "All Themes", "dimensions": ["theme"] },
"matrix": { "name": "Full Matrix", "dimensions": ["theme", "locale"] }
}
}
}Run all variants:
reshot run --all-variants
# Captures: homepage/light/en, homepage/light/de, homepage/dark/en, homepage/dark/deInjection methods: localStorage, sessionStorage, browser (colorScheme, locale, timezone), cookie, queryParam.
Viewport Presets
Use preset names in your config or with the --viewport flag:
| Category | Preset | Resolution | Scale |
| --- | --- | --- | --- |
| Desktop | desktop-hd | 1920x1080 | 1x |
| Desktop | desktop | 1280x720 | 1x |
| Desktop | desktop-retina | 1280x720 | 2x |
| Tablet | tablet-landscape | 1024x768 | 2x |
| Tablet | tablet-portrait | 768x1024 | 2x |
| Mobile | mobile | 375x667 | 2x |
| Mobile | mobile-large | 414x896 | 3x |
| Docs | docs-wide | 1200x800 | 2x |
| Docs | docs-standard | 960x640 | 2x |
| Social | social-og | 1200x630 | 2x |
| Social | social-twitter | 1200x600 | 2x |
Visual Diffing
Compare captures against baselines to detect changes:
{
"diffing": {
"enabled": true,
"threshold": 0.1,
"antialiasing": true,
"ignoreRegions": [
{ "x": 0, "y": 0, "width": 1280, "height": 50 }
]
}
}# Run with diffing enabled
reshot run --diff
# Compare against cloud baselines
reshot run --diff --cloudPixel-level comparison using pixelmatch. The threshold (0-1) controls sensitivity — 0.1 means 10% pixel difference tolerance. antialiasing: true compensates for font rendering differences across platforms. ignoreRegions excludes dynamic areas like timestamps or ads.
Interactive Recording
Record scenarios by interacting with your app in a real browser:
# Launch Chrome and start recording
reshot record "Checkout Flow" --browser --url http://localhost:3000During recording:
- Press S to capture a screenshot step
- Press C to start/stop a video clip
- Press Q to quit and save
The recorded scenario is appended to reshot.config.json automatically.
Authentication
Storage State (from Playwright)
npx playwright codegen http://localhost:3000 --save-storage=.reshot/auth-state.json{
"storageStatePath": ".reshot/auth-state.json"
}Login Steps
{
"auth": {
"loginUrl": "http://localhost:3000/login",
"loginSteps": [
{ "action": "type", "selector": "input[name='email']", "text": "${EMAIL}" },
{ "action": "type", "selector": "input[name='password']", "text": "${PASSWORD}" },
{ "action": "click", "selector": "button[type='submit']" },
{ "action": "waitForSelector", "selector": "[data-authenticated='true']" }
]
}
}Environment variables (${EMAIL}, ${PASSWORD}) are interpolated at runtime.
Output Formats
Step-by-Step Images (default)
.reshot/output/dashboard/20260315-120000/theme-light/
├── step-0-overview.png
└── step-1-analytics.pngVideo Recording
Set "format": "summary-video" in scenario output config to record the full browser session as MP4.
Selective Capture (Crop)
{
"output": {
"crop": {
"enabled": true,
"selector": ".modal-dialog",
"padding": 16
}
}
}Crops the screenshot to the bounding box of the selected element.
CI/CD Integration
GitHub Actions
name: Visual Capture
on:
push:
branches: [main]
jobs:
capture:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: 20 }
- run: npm ci
- run: npm start & # start your app
- run: npx @reshotdev/screenshot ci run --tag ${{ github.sha }} --message "Deploy ${{ github.sha }}"
env:
RESHOT_TOKEN: ${{ secrets.RESHOT_TOKEN }}Or use the setup wizard:
reshot ci setupThis generates a .github/workflows/reshot.yml tailored to your project.
Asset Map for Builds
Generate a manifest of captured assets for use in documentation sites or marketing pages:
reshot pull --format json --output assets.json --status approved{
"assets": [
{
"key": "dashboard-overview",
"variant": "theme-light",
"url": "https://cdn.reshot.dev/abc123/dashboard-overview.png",
"format": "png",
"width": 1280,
"height": 720,
"version": "v1.2.0"
}
]
}Also supports --format ts (TypeScript with full metadata) and --format csv.
Drift Management
Visual drifts are flagged when captures differ from baselines:
# List pending drifts
reshot drifts
# Approve a specific drift (updates baseline)
reshot drifts approve drift-abc123
# Approve all pending drifts
reshot drifts approve-all
# Reject a drift (keeps old baseline)
reshot drifts reject drift-abc123Standalone Mode
Run without any cloud connection:
reshot setup --offlineAll capture, recording, diffing, and studio features work locally. Cloud features (publish, sync, drifts, pull) are disabled.
Limitations
- Beta release. The CLI interface and config format may change between minor versions.
- Playwright browsers are downloaded on first run (~200MB for Chromium).
- Video recording requires Chromium (Firefox and WebKit support screenshots only).
- Cloud features (publish, sync, drifts) require a Reshot account at reshot.dev.
- Privacy masking (automatic PII redaction) is best-effort and should not be relied on for compliance.
Documentation
License
MIT
