ScreenshotNeo

BlogHow-to

How to Run Reg-suit Visual Tests in GitHub Actions

Set up visual regression testing with Reg-suit in GitHub Actions: generate screenshots, compare them with expected images, and publish reports.

By the ScreenshotNeo team4 October 20269 min read

To run Reg-suit visual tests in GitHub Actions, first generate screenshots of your application, then run npx reg-suit run to compare them with expected images and create a comparison report. Reg-suit is the comparator; it does not launch a browser or capture screenshots. Your browser or test step must create the image files before Reg-suit runs.

A typical workflow has four parts: build and serve the application, capture the pages under test, compare current screenshots with baselines, and publish the report or notify reviewers. Reg-suit can use configured plugins to find expected snapshots, publish results, and send notifications. The official Reg-suit README describes reg-suit run as combining expected-image sync, comparison, publication, and optional notification.

1. Add screenshot generation to the workflow

Save a workflow such as .github/workflows/visual-regression.yml. This example assumes your repository already has an npm script named screenshots that starts or connects to the application as needed and writes PNG, JPEG, or WebP screenshots into screenshots/. Replace that command and directory with your project’s capture setup.

name: Visual regression

on:
  pull_request:
  push:
    branches: [main]

permissions:
  contents: read

jobs:
  visual-regression:
    runs-on: ubuntu-latest
    steps:
      - name: Check out repository
        uses: actions/checkout@v6
        with:
          fetch-depth: 0

      - name: Set up Node.js
        uses: actions/setup-node@v7
        with:
          node-version: 22
          cache: npm

      - name: Install dependencies
        run: npm ci

      - name: Build application
        run: npm run build

      - name: Generate screenshots
        run: npm run screenshots

      - name: Run Reg-suit
        run: npx reg-suit run

The action versions shown use the current major-version examples in the official checkout and setup-node repositories. Review those repositories when updating pinned action versions. Choose a Node version supported by your application and dependencies; the example uses Node 22.

fetch-depth: 0 makes the full Git history available. This matters when your key-generation plugin walks Git history to select the comparison baseline. If your chosen snapshot plugin does not depend on Git history, a shallow checkout may be sufficient.

Make the capture command deterministic

Your screenshots script should complete only after the application is ready and all desired pages have been captured. For a browser-based test, configure a stable viewport, locale, timezone, fonts, animation handling, and test data. Wait for the specific page state your test requires instead of relying on a short arbitrary delay. Keep generated files in the same directory on every run and avoid including timestamps, random identifiers, or user-specific content in captured pages.

If the application needs a local server, start it in the workflow before the capture script and ensure the server stays alive until capture finishes. The exact command depends on your framework and browser automation tool; Reg-suit does not prescribe one. The official Reg-suit Puppeteer demo shows the separation: a capture script writes an image, then Reg-suit runs.

2. Configure Reg-suit

Create regconfig.json at the project root. The required core.actualDir property must point to the directory containing the screenshots your workflow just generated.

{
  "core": {
    "actualDir": "screenshots",
    "workingDir": ".reg",
    "thresholdRate": 0,
    "concurrency": 4
  },
  "plugins": {}
}

This minimal example deliberately leaves plugins empty: select and configure a key generator and, if desired, a publisher or notifier that suits your repository. Plugin-specific settings belong under plugins and must follow that plugin’s own documentation. Reg-suit lists S3 and Google Cloud Storage publisher plugins in its repository documentation.

Setting What it controls How to choose
actualDir Location of current screenshots to compare. Required. Set it to the exact output directory used by the capture step.
workingDir Reg-suit working data directory. Set a project-local path if you want the working data location explicit.
thresholdRate Allowed difference rate for an image comparison. Start with strict comparison; adjust only after reviewing real, expected rendering noise.
thresholdPixel Pixel-difference threshold option. Use when an absolute pixel threshold better matches your review policy. Check the Reg-suit README for supported values and behavior for your installed version.
matchingThreshold Matching sensitivity based on YUV color distance between pixels. Change carefully; it affects which pixel differences are treated as matching.
enableAntialias Controls treatment of antialiasing differences. Enable only if antialiasing variation is a known source of noise in your environment.
concurrency Number of comparisons performed concurrently. Lower it if runner memory or CPU is constrained; raise only if the job benefits from parallel comparison.
ximgdiff Enables x-img-diff reporting when configured. Use it if the x-img-diff style report helps reviewers inspect changes.
plugins Plugin-specific configuration for keys, publishers, and notifications. Follow each selected plugin’s official README for required names, options, and credentials.

Configuration names and plugin interfaces can evolve. Consult the Reg-suit README and the README for each installed plugin before copying a plugin configuration. Keep credentials in GitHub Actions secrets and expose them only to the step that needs them.

3. Select a baseline and report destination

Visual regression testing needs a stable expected image for each current screenshot. Your key-generation strategy determines which expected snapshot is selected. The Git-hash key generator uses the branch graph to identify a commit to compare against, so both history and branch context can affect the result.

Reg-suit’s publisher plugins can store expected and actual snapshots and the comparison report in external storage. The project documentation names S3 and GCS publisher options. This model is useful when expected images should persist independently of a particular workflow run, but it requires plugin-specific configuration and cloud credentials.

The separate reg-actions project uses a different workflow-artifact model: it compares branch artifacts, uploads test images and a report as artifacts, and can comment on a pull request or workflow summary. It also expects screenshots to exist already; its README explicitly says the action does not take screenshots. It documents comment modes always, changes, and never, and a default artifact retention period of 30 days.

Choice Who captures screenshots? Where reviewers get results Persistence and comparison model
Reg-suit CLI with publisher plugin Your browser or test step. From the configured report destination or notification plugin. Can publish snapshots and reports to external storage such as S3 or GCS; key selection depends on configured strategy.
reg-actions Your browser or test step. Workflow artifacts, pull request comments, or workflow summary. Uses workflow artifacts; the repository documents 30-day default retention. It compares branch artifacts rather than serving as a screenshot generator.

Choose based on how long baselines must remain available, who needs access to reports, and whether you want an external snapshot store or run-scoped workflow artifacts. Don’t assume artifact retention is permanent; adjust retention according to your review and audit needs.

4. Handle pull request branches and Git history

If a Git-hash key generator cannot identify the intended base commit, check that the workflow fetched enough history and that the event provides a usable branch name. Pull request workflows can check out a synthetic merge commit or a detached HEAD, depending on the event and checkout configuration. The Reg-suit demo documents a detached-HEAD workaround that supplies a branch name. Treat that as a troubleshooting option, not a mandatory step for every workflow.

  1. Inspect the checkout step and verify fetch-depth is sufficient; use 0 when the key generator needs the full graph.
  2. Check the workflow event and checkout ref to see whether the expected source or target branch context is available.
  3. Read the selected key generator’s docs to confirm which branch or commit it uses as the baseline.
  4. Apply a branch-name workaround only if your event/check-out combination lacks the context required by that generator, then verify it resolves the intended baseline.

5. Troubleshoot common failures

Symptom Likely cause Fix
No screenshots found or no meaningful comparisons The capture step did not run, wrote files elsewhere, or ran in a different working directory. Confirm the capture command succeeded and list its output files. Set actualDir to that exact directory.
Reg-suit runs before screenshots are ready The server or browser capture process is asynchronous or still waiting for application startup. Make the capture step wait for the app and finish writing all images before invoking Reg-suit.
Unexpected baseline or no matching expected snapshot Insufficient Git history, missing branch context, or a key-generation configuration that selects another key. Use full history if required, inspect event/ref context, and validate the key generator’s baseline selection.
Publisher authentication or upload error Missing, incorrectly scoped, or invalid plugin credentials/configuration. Follow the publisher plugin’s official instructions, check secret names and permissions, and ensure secrets are available in this event. Never print secrets in logs.
Report artifact is unavailable later Workflow artifact retention expired or the artifact was not uploaded. Check the upload step and retention settings. For longer-lived expected snapshots, consider an external publisher store.
Visual diffs change between identical commits Capture environment or page state is nondeterministic, such as fonts, data, animations, viewport, timing, or browser differences. Pin and stabilize the capture inputs; wait on application state and remove random or time-varying content from test fixtures.
Comparison job is slow or runs out of resources Large screenshots, many files, or too much comparison concurrency. Capture only necessary pages and regions, reduce image dimensions when valid for the test, and tune concurrency for the runner.

6. Performance, reliability, and cost

The browser capture step is often the part that depends most on application startup and page readiness; the comparison step then processes the generated image set. Keep the suite focused on pages and states that protect important UI behavior, and avoid unnecessarily large full-page images when a smaller target covers the requirement. The exact runtime and resource use depend on your browser, app, images, and runner; there is no universal benchmark.

For reliability, make capture inputs repeatable, keep the screenshot directory contract explicit, and ensure the comparison baseline selection is observable. Separate capture failures from visual diffs in logs so a failed page load is not mistaken for a passing comparison. Retain reports long enough for reviewers to investigate, and store long-lived baselines in an appropriate publisher store if workflow artifacts are too short-lived.

Reg-suit is open-source software. GitHub Actions usage and external storage may have costs under their respective service plans; the total depends on workflow frequency, runner usage, artifact volume, and storage. Check your organization’s current GitHub and cloud-storage pricing rather than assuming a fixed cost.

Or skip the browser setup

If your goal is to capture a page for a visual test, ScreenshotNeo is a website screenshot API and MCP server. A single request returns an image or PDF, so your workflow can fetch the current page capture without installing and operating a browser for that capture step. See the ScreenshotNeo API documentation for request options.

curl -G "https://api.screenshotneo.com/v1/shot" \
  -d access_key=YOUR_API_KEY \
  --data-urlencode url=https://stripe.com \
  -o shot.webp
import requests

r = requests.get(
    "https://api.screenshotneo.com/v1/shot",
    params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
    timeout=90,
)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({
  access_key: 'YOUR_API_KEY',
  url: 'https://stripe.com'
});
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
await Bun.write('shot.webp', res);

ScreenshotNeo removes cookie and consent banners, newsletter popups, and chat widgets before capture. Bot checks, blank pages, failed loads, timeouts, and cache hits are not billed. Its MCP server provides screenshot tools for AI agents. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 screenshots. Generated screenshots can feed your existing Reg-suit comparison workflow, but you still configure the capture and baseline steps you need.

Sign up for ScreenshotNeo free: 1,000 screenshots a month, no card required.

FAQ

Does Reg-suit take screenshots?

No. A browser automation or other capture step must write the current images before Reg-suit runs.

Can I run Reg-suit only on pull requests?

Yes. Set the workflow trigger to pull_request; include push events too if you want the baseline branch checked directly.

Do I need a cloud publisher?

No. A publisher is an optional part of the plugin configuration. Choose how to retain and expose snapshots and reports based on your team workflow.

Why fetch full Git history?

A Git-hash key generator may need to walk the branch graph to resolve the comparison baseline. Other configurations may not require full history.