npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

pw-ui-review

v0.1.1

Published

Local web UI for reviewing Playwright visual snapshot test failures

Readme

pw-ui-review

CI npm version License: MIT

A local, open-source CLI that opens a web UI for reviewing Playwright visual snapshot test failures. It replaces the blunt --update-snapshots flag with a deliberate, per-assertion approve/reject workflow: see what changed, in what context, and decide — before any baseline PNG is touched.

Strictly local-first. No cloud, no accounts, no third-party services. Nothing leaves your machine.


Demo

A full walkthrough — reviewing real visual failures from start to finish:

pw-ui-review demo walkthrough


Tool interface

Reviewing real toMatchSnapshot() failures — Expected / Actual / Diff side by side, with the failing assertion and its test steps:

pw-ui-review reviewing a visual snapshot failure

A draggable slider overlays the expected and actual screenshots:

Slider compare mode

Light and dark themes (follows your OS prefers-color-scheme, with a manual toggle):

Dark theme


Features (v0.1)

  • Post-run review UI — review every failed toHaveScreenshot() / toMatchSnapshot() assertion from your most recent run.
  • Expected / Actual / Diff — the three images side by side, zoomable, with a full-screen overlay.
  • Approve / RejectUpdate baseline promotes the actual screenshot; Keep current baseline leaves everything untouched. In-session undo.
  • External baseline import — bring in a PNG from outside the test run (e.g. a design export), with dimension validation before anything is written.
  • Session state — your progress is saved to a local sidecar file so you can close and reopen without losing your place.
  • Dependency validation — thorough startup checks with actionable messages.
  • Light & dark themes — follows your OS prefers-color-scheme.

Test steps: the detail view shows the action sequence (goto, click, screenshot, …) leading to the failed assertion. Current Playwright versions omit a per-step steps array from JSON reporter output, so pw-ui-review ships a tiny custom reporter that captures the sequence into a sidecar file. Add one line to your config (below). We never parse trace.zip.


Install

npm install -g pw-ui-review

Global install. It does not modify your project's package.json, node_modules, or playwright.config.ts.

Prerequisite — reporters

Your playwright.config.ts needs two reporters: the JSON reporter (failure metadata + screenshot attachments) and the bundled pw-ui-review reporter (the test-step sequence):

reporter: [
  ['json', { outputFile: 'test-results/results.json' }],
  ['pw-ui-review/reporter'],   // ← captures step context into a sidecar
  // ...other reporters
],

The pw-ui-review reporter writes test-results/pw-ui-review-steps.json next to results.json. It's optional — without it everything works, but the Steps section shows a fallback instead of the action sequence. The startup checks tell you if it's missing.


Usage

Run from your Playwright project root, after a test run that produced visual failures:

pw-ui-review

It validates dependencies, starts a local server, and opens your browser:

pw-ui-review startup: dependency checklist and local server

Options

| Argument | Default | Description | |---|---|---| | --results <path> | ./test-results/results.json | Playwright JSON reporter output | | --snapshots <path> | auto | Root directory of snapshot baselines | | --port <number> | 3456 | Port for the local web server | | --clean | — | Remove tool sidecar files from this project and exit | | -h, --help | — | Show help |

pw-ui-review \
  --results ./custom-results/results.json \
  --snapshots ./e2e/__snapshots__ \
  --port 4242

Stop with Ctrl+C. Decisions already written to disk remain.


Getting started for development

This repo links the demo Playwright project pw-visual-tests-demo as a git submodule at ./demo. The submodule is the development and integration-test fixture — we never scaffold a sample project inside this repo.

# 1. Clone pw-ui-review with the submodule
git clone --recurse-submodules https://github.com/abhivaikar/pw-ui-review

# If you already cloned without --recurse-submodules
git submodule update --init

# 2. Install pw-ui-review dependencies
npm install

# 3. Install demo project dependencies
cd demo && npm install && npx playwright install

# 4. Generate baselines in the demo project (first time only)
npx playwright test --update-snapshots

# 5. Run demo tests to produce results
npx playwright test

# 6. Run pw-ui-review against the demo results
cd .. && node bin/pw-ui-review.js \
  --results ./demo/test-results/results.json \
  --snapshots ./demo/snapshots

With the submodule initialised and the demo tests run, node bin/pw-ui-review.js with no arguments also works from the repo root — the tool falls back to ./demo/test-results/results.json and ./demo/snapshots automatically.

Triggering visual failures for development

The tool only has something to display when at least one assertion fails. After generating baselines, make any change to the demo app and run the demo tests again without --update-snapshots. The demo also ships a variant config that surfaces failures directly:

cd demo && npm run simulate:failures   # runs the v2 variant against v1 baselines

See the demo repo's README for the full explanation.

Build the UI bundle

The CLI serves a built UI from dist/. During development:

npm run build      # production bundle into dist/
npm run dev        # Vite dev server with /api proxied to a running tool

Tests

npm test           # full unit + component suite (Vitest)
npm run test:watch

The codebase is split so that all logic lives in framework-free modules under src/core (parser, path resolution, validation, file operations) with the Express server (src/server) and CLI (bin/) as thin adapters. This keeps the core fast to unit test and ready for the ./demo-backed integration suite.


Architecture

bin/pw-ui-review.js     CLI entry — args, validation output, server start, --clean
src/core/               framework-free logic (pure, heavily unit tested)
  parser.js             JSON reporter -> failure model (handles both shapes)
  steps.js              step shaping + reporter-sidecar correlation/merge
  paths.js              --results/--snapshots resolution + ./demo fallback
  validation.js         startup dependency checks
  fileops.js            session, provenance, approve/restore, import (the only writer)
src/reporter/           bundled Playwright reporter ('pw-ui-review/reporter')
src/server/             Express adapter over the core
  store.js              in-memory review state for one run
  app.js                HTTP routes (state, image streaming, decisions, import)
  serve.js              bootstrap (store + app + listen)
src/ui/                 React + Vite single-page UI (light/dark)
src/cli/report.js       terminal rendering of the validation checklist

File ownership (what the tool writes)

  • __snapshots__/ (or your snapshot dir) — written only on explicit approve or external import.
  • .playwright-review-session.json — review progress. Gitignored.
  • .playwright-baseline-provenance.json — external-import provenance. Commit this — it's a team artifact.
  • test-results/ and playwright.config.ts are never written.

Known limitations (v0.1)

  • Test step sequence requires the bundled pw-ui-review/reporter (one line in your config) because current Playwright versions omit a steps array from JSON reporter output. We deliberately do not parse trace.zip (it's an internal, version-unstable format). Without the reporter the UI shows a clear fallback in the Steps section.
  • Baseline history (git timeline of a baseline PNG) is out of scope for v0.1.

Contributing

Issues and PRs welcome on the public tracker. MIT licensed.

Updating the demo submodule pointer

When the demo repo is updated, update the submodule pointer in pw-ui-review with:

cd demo && git pull origin main && cd ..
git add demo
git commit -m "chore: update demo submodule to latest"

Integration tests

The ./demo submodule is the intended surface for integration tests: run npx playwright test inside ./demo, then invoke the tool's core logic against the produced results and assert on parsing, file writes on approve, no writes on reject, and session-state updates. (Integration tests are not included in v0.1; the architecture and path conventions are in place to add them.)


Compatibility

  • Node.js ≥ 18
  • @playwright/test ≥ 1.40
  • macOS, Linux, Windows
  • Desktop browser, minimum 1024px wide