@rettangoli/vt
v1.0.5
Published
Rettangoli Visual Testing
Readme
Rettangoli Visual Testing
Visual regression testing for Rettangoli specs using Playwright screenshots.
Commands
rtgl vt generatertgl vt screenshotrtgl vt reportrtgl vt accept
Behavior split:
generatebuilds candidate HTML only (no Playwright capture)screenshotruns generate flow and captures candidate screenshotsreportcompares existing artifacts only (does not run generate/screenshot)
Public Screenshot Options
--headed--concurrency <number>--timeout <ms>--wait-event <name>--isolation <fast|strict>--folder <path>(repeatable)--group <section-key>(repeatable)--item <spec-path>(repeatable)
Public Report Options
--compare-method <method>--color-threshold <number>--diff-threshold <number>--folder <path>(repeatable)--group <section-key>(repeatable)--item <spec-path>(repeatable)
Scoped Runs
Use selectors to run only part of VT in both screenshot and report:
folder: matches specs by folder prefix undervt/specs(example:components/forms)group: matches derived section page key fromvt.sectionstitles (kebab-case(title))item: matches a single spec path relative tovt/specs(with or without extension)
Selector rules:
- selectors are unioned (OR); any matched item is included
- if no selector is provided, all items are included
Examples:
# Only specs under a folder
rtgl vt screenshot --folder components/forms
# Only one section/group key from vt.sections
rtgl vt screenshot --group components-basic
# Only one spec item (extension optional)
rtgl vt screenshot --item components/forms/login
rtgl vt screenshot --item components/forms/login.html
# Combine selectors (union)
rtgl vt screenshot --group components-basic --item pages/home
# Same selectors for report
rtgl vt report --folder components/forms
rtgl vt report --group components-basic
rtgl vt report --item components/forms/loginOther capture tuning remains internal and intentionally not user-configurable.
Config
rettangoli.config.yaml:
vt:
path: ./vt
port: 3001
url: http://127.0.0.1:4173
service:
start: bun run preview
concurrency: 4
timeout: 30000
waitEvent: vt:ready
isolationMode: strict
viewport:
id: desktop
width: 1280
height: 720
sections:
- title: Components Basic
files: componentsNotes:
vt.sectionsis required.vt.serviceis optional. When set, VT starts the command before capture, waits forvt.url, then stops it after capture.- when
vt.serviceis omitted andvt.urlis set, VT expects that URL to already be running. vt.isolationModeis optional:fastorstrict. Default isfast.strictuses a fresh browser context per captured spec and is recommended for real app routes or IndexedDB-backed state.- Section page keys are derived as
kebab-case(title)for flat sections and groupitems[].title. - Derived section page keys must be unique case-insensitively.
vt.viewportsupports object or array; each viewport requiresid,width,height.vt.captureis internal and must be omitted.- Viewport contract details:
docs/viewport-contract.md.
Spec Frontmatter
Supported frontmatter keys per spec file:
titledescriptiontemplateurlwaitEventwaitSelectorwaitStrategy(networkidle|load|event|selector)viewport(object or array of viewport objects)skipScreenshotskipInitialScreenshotspecssteps
Step action reference:
docs/step-actions.md- canonical format is structured action objects (
- action: ...); legacy one-line string steps are not supported. action: selectaccepts exactly one oftestIdorselectorfor interaction targeting.assertsupportsjsdeep-equal checks for object/array values.
Screenshot naming:
- By default, VT takes an immediate first screenshot before running
steps. - Set
skipInitialScreenshot: truein frontmatter to skip that immediate first screenshot. - First captured screenshot is
-01. - Then
-02,-03, up to-99. - When viewport id is configured, filenames include
--<viewportId>before ordinal (for examplepages/home--mobile-01.webp).
Docker
A pre-built Docker image with rtgl and Playwright browsers is available:
docker pull han4wluc/rtgl:playwright-v1.57.0-rtgl-v1.0.12Run commands against a local project:
docker run --rm -v "$(pwd):/workspace" han4wluc/rtgl:playwright-v1.57.0-rtgl-v1.0.12 rtgl vt screenshot
docker run --rm -v "$(pwd):/workspace" han4wluc/rtgl:playwright-v1.57.0-rtgl-v1.0.12 rtgl vt report
docker run --rm -v "$(pwd):/workspace" han4wluc/rtgl:playwright-v1.57.0-rtgl-v1.0.12 rtgl vt acceptNote:
- Image default working directory is
/workspace. - Use
-w /workspace/<subdir>only when running commands from a subfolder within the mounted project.
Supports linux/amd64 and linux/arm64.
Development
Run unit tests:
bun testDefault unit run behavior:
bun testskips the real-browser smoke tests inspec/e2e-smoke.spec.jsunlessVT_E2E=1.- Skipped smoke tests are:
runs generate, accept, and report with real screenshotssupports waitEvent readiness with real browser screenshotssupports managed service lifecycle with vt.service.start and vt.url
Run real-browser smoke:
VT_E2E=1 bun test spec/e2e-smoke.spec.jsRun Docker E2E tests (requires Docker daemon running):
# Full pipeline: build test image → run all E2E scenarios
bun run test:e2e:full
# Scenarios only (skip image build, assumes image already exists)
bun run test:e2eOptional benchmark fixture:
bun run bench:capture