Documentation Menu

Managed Baselines Workflow

Take full control of your visual history by explicitly managing static "Golden Images" stored safely in the cloud.

What are Managed Baselines?

In this model, RegressionBot acts as your source of truth. Unlike the Preview vs. Production model (which renders production live on every test), Managed Baselines are static images. You decide exactly when a visual change becomes the new standard.

Baselines are stored in our S3 vaults, organized by your projectId. Every time you run a test, the API downloads these existing stored images and compares your new screenshots against them.

When to use Managed Baselines?

Use this if...

  • Production is highly dynamic (ads, randomized content).
  • You are building a Design System or Component Library (like Storybook).
  • You need a "Frozen" truth that doesn't change until explicitly approved.
  • You want a persistent historical record of UI changes.

Stick to Preview vs. Prod if...

  • You want the absolute lowest possible maintenance.
  • Your Production site is stable and is always the "source of truth".
  • You don't want to manage an explicit approval step in your PRs.

The Managed Lifecycle

1. Initial Run

The first time you run a test for a new Project, RegressionBot automatically saves the screenshots as the initial baselines.

2. Continuous Checking

Every subsequent PR run compares against those stored S3 images. If a developer changes a button color, the test will fail.

3. Manual Approval

To update the baselines (accept the new button color), you must call the /approve endpoint. This promotes the new PR screenshots to overwrite the old baselines.

How to Configure

Using the SDK, simply omit the .against(baseOrigin) call. RegressionBot will automatically default to Managed Baselines.

import { Visual } from 'regressionbot';

const visual = new Visual();

const job = await visual
  .test('https://preview.myapp.com')
  .forProject('design-system-v1') // Baselines are scoped to this ID
  .on(['Desktop Chrome'])
  // NOTICE: No .against() call here!
  .run();