flowshot
v0.2.0
Published
Flow-based visual regression dashboard for Playwright. One command, one HTML file — screenshots connected as user flows with diff slider.
Maintainers
Readme
flowshot
Flow-based visual regression dashboard for Playwright. One command, one HTML file — screenshots connected as user flows with diff slider.

Why
Existing visual regression tools show screenshots as flat galleries. Flowshot shows them as user flows — screens connected with arrows, so you see the journey, not just the pages.
- No server, no account — generates a single HTML file
- Works with your existing Playwright snapshots
- Diff mode with drag slider to compare expected vs actual
- Dark/light theme, sidebar navigation, lightbox zoom
Quick Start
# 1. Install
npm i -D flowshot
# 2. Create config
npx flowshot init
# 3. Edit flowshot.config.json — define your flows
# 4. Run Playwright visual tests
npx playwright test e2e/visual.spec.ts
# 5. Generate report
npx flowshotHow Diff Detection Works
Flowshot integrates with Playwright's built-in visual comparison. Here's the full workflow:
1. Create baseline screenshots
Run your visual tests to capture baseline screenshots:
npx playwright test e2e/visual.spec.ts --update-snapshotsThis saves baseline PNGs to your snapshotDir (e.g. e2e/visual.spec.ts-snapshots/).
2. Make changes to your app
Edit components, styles, layouts — anything visual.
3. Run visual tests again
npx playwright test e2e/visual.spec.ts || trueWhen Playwright detects a difference, it generates three files in test-results/:
*-expected.png— the baseline*-actual.png— what the screen looks like now*-diff.png— pixel diff highlighted in red
4. Generate the flow report
npx flowshotFlowshot scans test-results/ for those diff files, copies them to .flowshot/diffs/, and generates an HTML report.
5. Review diffs in the dashboard
Open the report and click Diff in the top bar:
- CHANGED (red badge) — screens that differ from baseline
- OK (green badge) — screens that match
- Drag slider on each card to compare expected vs actual side-by-side
- Fullscreen button (top-right of each card) — opens fullscreen slider compare
- Sidebar shows warning icons on flows with changes
- Summary bar shows total changed vs unchanged count
6. Accept or fix
# If the changes are intentional — update baselines:
npx playwright test e2e/visual.spec.ts --update-snapshots
# If something broke — fix your code and re-run:
npx playwright test e2e/visual.spec.tsOne-command shortcut
Combine test + report in one step:
npx playwright test e2e/visual.spec.ts || true && npx flowshotOr add to your Makefile:
test-visual-review: ## Visual test + open flow dashboard
npx playwright test e2e/visual.spec.ts --project=chromium || true
npx flowshotRecommended Playwright threshold
Playwright's default maxDiffPixelRatio is 0 (exact match). Common settings:
const screenshotOpts = {
maxDiffPixelRatio: 0.05, // allow 5% pixel diff
threshold: 0.2, // Playwright default color threshold
}Setting maxDiffPixelRatio too high (e.g. 0.35) will cause real changes to go undetected.
Screenshots
Flow View — Dark Theme

Flow View — Light Theme

Single Flow Detail

Diff Mode

Config
flowshot.config.json:
{
"snapshotDir": "e2e/visual.spec.ts-snapshots",
"testResultsDir": "test-results",
"platform": "chromium-darwin",
"views": ["mobile", "desktop"],
"outDir": ".flowshot",
"flows": [
{
"name": "Auth Flow",
"steps": [
{ "screen": "auth", "label": "Login", "path": "/auth" },
{ "screen": "home", "label": "Home", "path": "/" }
]
}
],
"components": [
{ "screen": "header-component", "label": "Header" }
]
}| Field | Description |
|-------|-------------|
| snapshotDir | Where Playwright stores baseline screenshots |
| testResultsDir | Where Playwright writes test results (diffs on failure) |
| platform | Snapshot filename suffix, e.g. chromium-darwin |
| views | Viewport names matching your snapshot filenames |
| outDir | Output directory for report and collected diffs |
| flows | Array of user flows, each with ordered steps |
| components | Shared UI components (header, footer, etc.) |
Snapshot naming convention
Flowshot expects Playwright snapshots named as:
{screen}-{view}-{platform}.pngFor example: home-mobile-chromium-darwin.png, auth-desktop-chromium-darwin.png
Auto-Detect Flows
Flowshot can automatically discover your app's screens and generate flows — two ways:
flowshot detect — from test files + snapshots (no running app needed)
Scans your Playwright snapshot directory and test files to find screens and build flows:
flowshot detect # preview detected flows
flowshot detect --write # create flowshot.config.json from detected
flowshot detect --merge # add new flows to existing configHow it works:
- Scans
e2e/visual.spec.ts-snapshots/for screenshot files - Parses
e2e/*.spec.tsforpage.goto()andtoHaveScreenshot()patterns - Groups screens by section (heal-your-heart, know-your-self, etc.)
- Detects component screenshots (header, footer)
flowshot crawl — by actually browsing your app with Playwright
Opens your app in a real browser, finds links, clicks them, takes screenshots:
# Start your app first, then:
flowshot crawl --url http://localhost:3000
# Options:
flowshot crawl --url http://localhost:3000 --mobile # mobile viewport
flowshot crawl --url http://localhost:3000 --max-pages 20 # limit pages
flowshot crawl --url http://localhost:3000 --max-depth 2 # limit link depth
flowshot crawl --url http://localhost:3000 --write # save to configHow it works:
- Opens the URL in Playwright Chromium
- Finds all
<a href>links on the page - Visits each link, takes a screenshot
- Follows links from discovered pages (up to max-depth)
- Groups pages by URL section into flows
- Screenshots saved to
.flowshot/crawl-snapshots/
Requires playwright as a peer dependency: npm i -D playwright
flowshot init — smart init
When you run flowshot init, it automatically tries detect first. If snapshots exist, it generates config from them. Otherwise, creates an example config.
Commands
flowshot # collect diffs + generate report + open browser
flowshot init # auto-detect flows or create example config
flowshot detect # detect flows from snapshots + test files
flowshot crawl # discover pages by crawling your app
flowshot collect # collect diff images from test-results/
flowshot report # generate HTML report
flowshot report --open # generate and open in browser
flowshot report --inline # embed images as base64 (portable for CI)
flowshot report --collect # collect diffs before generatingCI Usage
Generate a portable report with embedded images:
npx flowshot report --collect --inlineUpload .flowshot/report.html as a CI artifact.
GitHub Actions example
- name: Visual regression
run: npx playwright test e2e/visual.spec.ts || true
- name: Generate flow report
run: npx flowshot report --collect --inline
- uses: actions/upload-artifact@v4
with:
name: flowshot-report
path: .flowshot/report.htmlLicense
MIT
