shotlist
v0.5.0
Published
Repeatable, annotated UI screenshots from declarative recipes. No code per shot.
Maintainers
Readme
shotlist
Take annotated UI screenshots from YAML recipes, using Playwright.
shotlist opens your running site, drives it to the state you describe, clips a region, draws callouts on it, and writes the image where you want it. Each screenshot is a YAML file. There is no per-screenshot code.
shotlist.dev/docs is the reference — every key, every step verb, every query primitive. This file is the short version.
Install
This is a Node.js module available through the npm registry.
Before installing, download and install Node.js. Node.js 20 or higher is required.
If this is a brand new project, make sure to create a package.json first with
the npm init command.
Installation is done using the
npm install command:
npm install -D shotlist playwrightpnpm and yarn work the same way.
Playwright is an optional peer dependency — shotlist does not install it, because its
postinstall downloads browsers. You need it whenever shotlist writes an image, which
includes --check and a source: file recipe, since the callouts are drawn in a page.
--init, --help and listing recipes need no browser and launch none.
Quick start
npx shotlist --initwrites a commented shotlist.config.yaml and a first recipe. Or set the two up by hand:
1. Configure the project once — shotlist.config.yaml in the project root:
site:
url: http://localhost:3000
viewport: { width: 1440, height: 900 }
scale: 2
theme: dark
install:
guide: content/guide/images2. Write a recipe — screenshots/recipes/order-row.yaml:
name: order-row
install: guide
setup:
- click: { role: button, name: Orders }
clip:
css: '.order-row'
contains: Acme Corp
pad: 20
marks:
amount: { within: clip, text: $42.00 }
status: { within: clip, text: Open }
callouts:
- { mark: amount, text: What they owe }
- { mark: status, text: Where it stands }3. Shoot it:
npx shotlist order-row --installThe image is written to screenshots/out/order-row.png, and --install copies it to
content/guide/images/order-row.png. PNG is the default; image.format also takes jpeg
and webp, per project or per recipe.
Documentation
| Page | What it covers |
| ------------------------------------------------------------------------------------------------ | --------------------------------------------- |
| Your first screenshot | A lesson: install, a recipe, a callout |
| Add shotlist to a project | Setting up in an app you already have |
| Configuration file | Every key, starting the site, style and fonts |
| Recipe file | Every field, and annotating an existing image |
| Steps | The step vocabulary |
| Queries | Sources, filters, traversal, frames, finders |
| Callouts and masks | Labels, numbered discs, masking |
| Macros and data files | Sharing setup, driving a shot from a list |
| Command line | Every flag, the API, editor and agent support |
| Keeping a screenshot current | --check, diffs, and a shot that changes |
| Undo what a shot changed | teardown, for a recipe that writes |
| What a configuration can do | What a run is allowed to reach |
Commands
npx shotlist --init # write a starter config and recipe
npx shotlist # list every recipe
npx shotlist <name> [<name>…] # shoot into paths.out
npx shotlist <name> --install # …and copy to its install destination
npx shotlist --all --install # shoot everything
npx shotlist --all --keep-going # …carrying on past a recipe that fails
npx shotlist --check # compare against committed images
npx shotlist --check --diff # …and write a before/after/changed image
npx shotlist --check --json # …and report it as JSON on stdout
npx shotlist --lint # check every YAML; no browser, no site needed
npx shotlist --login admin # sign in by hand, and save the session
npx shotlist --help # the full list, from the toolA recipe is data
A recipe is data. There is no step that evaluates JavaScript and there will not be one: if a screenshot cannot be described, that is a missing verb or query primitive, and it gets added. See CONTRIBUTING.md.
Running a config you did not write
shotlist also runs in automation, where the config may come from a fork's pull request or
from whoever submitted it. A shot list only ever opens its own site, and never reads or
writes .env, .git, .ssh and their like — in every mode, with no flag to set. For the
rest, --untrusted starts no processes, opens nothing on the runner's own network, and
stays inside the project.
Full detail, and what it does not cover, at shotlist.dev/docs/explanation/security-model.
Contributing
Any constructive contribution is welcome! You may contribute in any way you feel comfortable, from code for bug fixes and enhancements, to additions and fixes to documentation, additional tests, fixing a typo, and more!
Everything you need is in CONTRIBUTING.md: setup, the commands, the code style, and what "done" means.
License
MIT © Nicola Mustone — see LICENSE.
