Migrate from reg-suit
Move a reg-suit setup to Snapvisor - how regconfig.json, key generators, storage publishers and notifier plugins translate, and how to keep your capture tool (storycap or plain Playwright screenshots) or switch to the Snapvisor SDKs.
This guide moves a reg-suit setup (reg-suit with a regconfig.json, a key generator plugin, a storage publisher plugin and a notifier plugin) to Snapvisor. You keep your tests and stories. What changes is where baselines live, how a run is compared, and how the result reaches your pull request. Because reg-suit does not capture anything itself, there are two ways to migrate, covered below.
reg-suit facts come from the reg-suit 0.14.5 README and the READMEs of its plugin packages. Snapvisor facts were read from the published @snapvisor/cli 7.0.0, @snapvisor/playwright 8.0.0 and @snapvisor/storybook 7.0.0 packages. Check the versions you run, as plugin options have changed between reg-suit releases.
The one change that matters
With reg-suit, a key generator decides which stored set of images is the "expected" one (the plugins reg-keygen-git-hash-plugin and reg-simple-keygen-plugin are the usual choices). reg-suit run fetches the expected images from your bucket, compares them with the directory your capture tool just wrote, and publishes the report. A notifier plugin posts the result.
Snapvisor keeps baselines for you, per reference branch. You upload the screenshots from a run, and Snapvisor compares them with the approved screenshots for the branch. You approve changes in the review UI, and they become the new baseline for that branch. There is no bucket, no key to compute and no sync step. See Baseline builds.
Your stored expected images do not carry over, and there is no import path. Your first Snapvisor build on your base branch becomes the baseline. Plan the switch for a moment when your base branch is visually correct.
Concept mapping
| reg-suit | Snapvisor equivalent |
|---|---|
regconfig.json core.actualDir | The directory you pass to npx @snapvisor/cli upload <directory>, or no directory at all when an SDK uploads from the test run. |
core.workingDir (default .reg) | Not needed. Nothing is staged locally. |
reg-suit run, reg-suit compare, reg-suit publish | One upload. The comparison happens on Snapvisor and the result shows in the build and the pull request check. |
reg-keygen-git-hash-plugin, reg-simple-keygen-plugin | Not needed. The reference commit is resolved from your base branch. See Baseline builds. |
reg-publish-s3-plugin, reg-publish-gcs-plugin | Not needed. Screenshots are stored by Snapvisor. |
reg-notify-github-plugin, reg-notify-github-with-api-plugin, reg-notify-gitlab-plugin | The Snapvisor status check. See GitHub or GitLab. |
reg-notify-slack-plugin | Snapvisor's Slack integration. Connect your workspace in team or account settings (team admins only). See Slack notifications. The pull request status check still reports the result. |
core.thresholdRate, core.thresholdPixel, core.matchingThreshold, core.enableAntialias | One setting, threshold. See Tolerances. |
core.concurrency | Not needed. |
| Capture tool (storycap, Playwright, Puppeteer) | Keep it and upload with the CLI, or switch to the SDK. See Choose a path. |
Choose a path
Path A: keep your capture tool. Your tool still writes images to a directory, as it does for reg-suit's actualDir. You replace reg-suit run with an upload of that directory. This is the smallest change and works with any tool that writes PNG or JPEG files.
Path B: switch to the matching Snapvisor SDK. The SDK captures inside your test run (and stabilizes the page first) and uploads when the run ends. You trade your capture script for the SDK's capture call.
You can start on Path A and move to Path B later without changing how you review.
Path A: upload the directory
Install the CLI:
npm install --save-dev @snapvisor/cliThen upload the directory your capture tool writes to, with the project token in ARGOS_TOKEN:
npx @snapvisor/cli upload ./__screenshots__What the upload command does, read from the package source:
- It takes one
<directory>argument. - It uploads files matching
**/*.{png,jpg,jpeg}by default. Use--filesto choose other globs and--ignoreto leave files out. - The token comes from
--token, or from theARGOS_TOKENenvironment variable. --build-namenames the build when one CI job creates several.--parallel,--parallel-total,--parallel-indexand--parallel-noncesplit a run across machines. Combine them withfinalize. See Parallel testing.--reference-branchand--reference-commitoverride the baseline Snapvisor would resolve for you.--thresholdsets the sensitivity. See Tolerances.--subsetmarks a build that holds only part of your screenshots.
A screenshot's name is its path relative to the uploaded directory (for example button/primary.png), so files in different folders never collide. If you rename or move files between runs, Snapvisor sees a different screenshot.
In CI, the reg-suit step is replaced by the upload:
# before
- run: npx storycap http://localhost:6006
- run: npx reg-suit run # AWS credentials below, or your CI's AWS role
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
# after
- run: npx storycap http://localhost:6006
- run: npx @snapvisor/cli upload ./__screenshots__
env:
ARGOS_TOKEN: ${{ secrets.ARGOS_TOKEN }}Copy the project token from your project's settings in the app, and store it as a CI secret, never in the repository. See Access tokens. More workflows, including merge queues and fork pull requests, are in GitHub Actions recipes.
Path B: storycap to @snapvisor/storybook
storycap crawls a running Storybook with a headless browser and writes one image per story, by default into __screenshots__ (its --outDir option). With @snapvisor/storybook, your own Storybook test run renders the stories in a real browser and captures one screenshot per story. The setup, for both the Vitest addon and the Test Runner, is in the Storybook section of the Chromatic guide. Register the plugin like this:
// vitest.config.ts
import { defineConfig } from "vitest/config";
import { argosVitestPlugin } from "@snapvisor/storybook/vitest-plugin";
export default defineConfig({
plugins: [
argosVitestPlugin({
// Set to true to upload; nothing is uploaded when this is omitted.
uploadToArgos: process.env.CI === "true",
}),
],
});How storycap's options translate:
| storycap | Snapvisor |
|---|---|
--viewport (a list such as 800x600) | The Storybook viewport global and modes, one screenshot per mode. See Viewports and modes. |
--serverCmd | Not needed. Your Storybook test run starts its own server. |
--outDir, --parallel | Not needed. The plugin uploads from the run. |
withScreenshot decorator and per-story screenshot parameters | Story play functions for interaction, and the plugin options for the rest. |
In Storybook captures the aria-busy wait is off by default. Passing your own stabilize object replaces that default, so include waitForAriaBusy: false in it to keep the wait off.
Path B: Playwright screenshots to @snapvisor/playwright
If your reg-suit input is a script that calls page.screenshot() and writes into actualDir, move the capture into a Playwright test. Install the SDK and register the reporter, which uploads screenshots when the run finishes:
npm install --save-dev @snapvisor/playwright// playwright.config.ts
import { defineConfig } from "@playwright/test";
import { createArgosReporterOptions } from "@snapvisor/playwright/reporter";
export default defineConfig({
reporter: [
process.env.CI ? ["dot"] : ["list"],
[
"@snapvisor/playwright/reporter",
createArgosReporterOptions({ uploadToArgos: !!process.env.CI }),
],
],
});Then change the capture:
import { test } from "@playwright/test";
+import { argosScreenshot } from "@snapvisor/playwright";
test("start page", async ({ page }) => {
await page.goto("http://localhost:3000");
- await page.screenshot({ path: "screenshots/start-page.png" });
+ await argosScreenshot(page, "start-page");
});argosScreenshot takes Playwright's own screenshot options, so mask and clip work as in Playwright. Defaults worth knowing, all read from the package source:
- Full page. A capture of a page is full page unless you pass
fullPage: false. Passelementto capture one element. - Animations are disabled unless you pass
animations: "allow". - Masks.
[data-visual-test="blackout"]is masked by default. Passing your ownmaskreplaces that default, so includepage.locator('[data-visual-test="blackout"]')in your array if you rely on it. - Stabilization is on by default: fonts, images and
aria-busyregions settle first, carets and scrollbars are hidden, and font anti-aliasing is normalized. - Viewports. Pass
viewportsto capture one screenshot per size from a single call.
See SDKs for the full option list.
Tolerances
reg-suit's comparison settings do not carry over. Its thresholdRate and thresholdPixel decide how many changed pixels are tolerated, matchingThreshold sets per-pixel sensitivity, and enableAntialias ignores anti-aliasing differences. Snapvisor has one setting, threshold, a sensitivity between 0 and 1 that defaults to 0.5. Higher means less sensitive. The two scales are not interchangeable, so do not copy a number across. Set it per screenshot, on the Storybook plugin for all stories, or with --threshold on the CLI:
await argosScreenshot(page, "chart", { threshold: 0.7 });Start from the default and adjust only when a specific screenshot is noisy. A change is flagged for review, not failed, so a small difference is a decision for a reviewer and not a red build.
Run both side by side
You do not have to switch in one pull request. Keep reg-suit run and add the Snapvisor upload next to it:
- Add the Snapvisor upload (or SDK) and merge it to your base branch so the first Snapvisor build becomes the baseline.
- Keep reg-suit as your gate, and the Snapvisor check optional, while you compare results.
- When the Snapvisor builds match your expectations on a few pull requests, make the Snapvisor check required, then remove reg-suit.
Make the Snapvisor check the gate
The upload finishes once the build has been created, whether or not it contains changes. A failed upload (bad token, unresolvable commit, network) is an error. The review gate is the commit status check Snapvisor posts to the pull request, which asks for review until someone approves or rejects the changes.
What you can delete
Once builds are landing in Snapvisor and the check is required:
regconfig.jsonand thereg-suitdependency, plus the key generator, publisher and notifier plugin packages.- The
reg-suit run(orcompareandpublish) steps in CI. - The storage bucket and its credentials, and the notifier webhook or GitHub app that reg-suit used. Remove the bucket only after you no longer need the old reports.
- The
.regworking directory from.gitignore. - Your capture script, if you moved to an SDK.
First-build checklist
After the first Snapvisor build on your base branch:
- Open the build and confirm it has a screenshot for each image reg-suit compared.
- Look through the screenshots for fonts, images and animations that did not settle. Fix those first, before any threshold change.
- Run the same build twice on one commit and check that nothing shows as changed.
- Open a pull request with one small visual change. Confirm the Snapvisor status check appears, asks for review, and clears after you approve.
- Make the Snapvisor check required in branch protection.
Frequently asked questions
- Does reg-suit take the screenshots?
- No. reg-suit compares two directories of images and publishes the report. The images come from a separate capture tool such as storycap or your own Playwright script. That split decides your migration path: keep the capture tool and upload its output with the Snapvisor CLI, or switch to the matching Snapvisor SDK.
- Can I import my reg-suit expected images as baselines?
- No. There is no import path. Your first Snapvisor build on your base branch becomes the new baseline: it has nothing to compare against, so it is approved automatically. Run it when your base branch is visually correct.
- Do I still need a storage bucket?
- No. reg-suit needs a publisher plugin (S3 or GCS) to keep expected images and reports between runs. Snapvisor stores screenshots and baselines for you, so there is no bucket to configure and no key generator to choose.
- Can I run reg-suit and Snapvisor side by side while I switch?
- Yes. They are independent. Keep reg-suit running, add a Snapvisor upload next to it, and remove reg-suit once the Snapvisor check is your gate.
Migrate from Happo
Move a Happo suite to Snapvisor - how happo.config targets, the happo wrapper, happoScreenshot with component and variant, Storybook parameters and report approval translate to the Playwright, Cypress and Storybook SDKs.
Baseline builds
The baseline is the last approved build on your base branch. Learn how Snapvisor picks the reference build and resolves the base branch for every comparison.