Snapvisor Docs

Migrate from Applitools

Move an Applitools Eyes Playwright suite to Snapvisor - how eyes.check, APPLITOOLS_API_KEY, batches, baselines, Ultrafast Grid browsers and match levels translate, and where the two comparison models differ.

This guide moves an existing Applitools Eyes suite to Snapvisor. You keep your test runner and your CI. What changes is the check call, the key, and where baselines and review live. It covers the Eyes Playwright SDK. For a side-by-side of the two products, see Snapvisor vs Applitools.

Snapvisor is focused on visual regression testing in CI. If you also use Applitools for other kinds of testing, those stay where they are.

The one change that matters

With Eyes, a test calls eyes.check at a checkpoint, and Applitools compares the result against a baseline using the match level you chose. Applitools describes its comparison as Visual AI.

Snapvisor takes a real screenshot in the browser your test is already running and compares it with the approved screenshot for the branch. argosScreenshot stabilizes the page and takes the picture, and your pipeline uploads the images. The comparison has a sensitivity setting, not match levels.

What this means in practice:

  • Browsers and sizes are capture work you do. Where Eyes lists browsersInfo for the Ultrafast Grid, you now ask for them in your tests: viewports on each call, and one Playwright project per browser engine. Snapvisor has no hosted grid; the closest equivalent is the mapping below.
  • Results will not match. The images and the comparison are different, so the first build will not resemble your Applitools baselines. That is expected.
  • Your baselines do not carry over. Snapvisor stores baselines server-side, per reference branch, and there is no import path. Your first Snapvisor build on your base branch becomes the new baseline. See Baseline builds.

Concept mapping

Applitools EyesSnapvisor equivalent
eyes.check(name, options) (@applitools/eyes-playwright)argosScreenshot(page, name, options) from @snapvisor/playwright
APPLITOOLS_API_KEYARGOS_TOKEN, your project token. On GitHub Actions you can skip it with tokenless authentication.
Batch (batch: { name })A build: one upload of screenshots for a commit.
Baseline, with branchName and parentBranchNameThe baseline: the approved screenshot on the reference branch, resolved for you. See Baseline builds.
Accepting or rejecting a checkpointApprove or reject a change in the review UI. Approving promotes it to the baseline for that branch. See Review workflow.
fully: truefullPage: true on argosScreenshot (Playwright's own screenshot option, passed through).
ignoreRegions: [page.locator(...)]mask: [page.locator(...)] (Playwright's own option, passed through).
Ultrafast Grid browsersInfoviewports on each call, plus one Playwright project per browser engine. See Browsers and sizes.
matchLevelthreshold, a different kind of setting. See Match levels and thresholds.
Eyes pull request and test statusThe Snapvisor commit status check. See Make the Snapvisor check the gate.

Eyes options not listed here (floatingRegions, IgnoreDisplacements, sendDom and others) have no mapping in this guide because we have not confirmed one. Check the SDK references before assuming a Snapvisor option of the same name exists.

Playwright

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 swap the check call. Eyes provides a test fixture with an eyes object; with Snapvisor you use Playwright's own test and import a function:

 // tests/visual.spec.ts
-import { test } from "@applitools/eyes-playwright/fixture";
+import { test } from "@playwright/test";
+import { argosScreenshot } from "@snapvisor/playwright";

-test("home", async ({ page, eyes }) => {
+test("home", async ({ page }) => {
   await page.goto("http://localhost:3000/");
-  await eyes.check("Home", {
-    fully: true,
-    ignoreRegions: [page.locator(".dynamic-banner")],
-  });
+  await argosScreenshot(page, "Home", {
+    fullPage: true,
+    mask: [page.locator(".dynamic-banner")],
+  });
 });

argosScreenshot stabilizes the page before capturing. It waits for web fonts, images and aria-busy regions to settle, hides carets and scrollbars and normalizes font anti-aliasing. It is on by default; beforeScreenshot runs your own code at the right moment if a particular page needs more. See Flaky test detection for how recurring changes are handled.

The Eyes configuration you kept in eyesConfig (app name, batch name, test name) has no Snapvisor counterpart to port. Screenshot names come from the name you pass, and builds are created for you.

Browsers and sizes

Eyes lets you list browsers, sizes and devices in browsersInfo for the Ultrafast Grid. With Snapvisor you describe them in your own Playwright setup.

Sizes go on each call. viewports takes complete viewport sizes, or named presets:

await argosScreenshot(page, "Home", {
  viewports: ["iphone-6", { width: 1440, height: 900 }],
});

Browser engines are Playwright projects:

// playwright.config.ts
import { defineConfig, devices } from "@playwright/test";

export default defineConfig({
  projects: [
    { name: "chromium", use: { ...devices["Desktop Chrome"] } },
    { name: "firefox", use: { ...devices["Desktop Firefox"] } },
    { name: "webkit", use: { ...devices["Desktop Safari"] } },
  ],
});

Each project runs the whole suite, so more engines means more screenshots and a longer run. Start with the engines you ship for. To split a long run across machines, see Parallel testing.

Match levels and thresholds

Applitools offers match levels such as Strict and Layout that change what kind of difference counts. Snapvisor does not. It has one comparison and a sensitivity, threshold, between 0 and 1, defaulting to 0.5. Higher means less sensitive.

Start from the default and adjust only if a specific screenshot is noisy:

await argosScreenshot(page, "chart", { threshold: 0.7 });

To keep an area that always changes out of the comparison, mask it instead of loosening the threshold. If you used a loose match level to cope with dynamic content, mask that content and try the default first. The threshold is stored with each screenshot and applied by the same engine that produces the diff you review, so what you set is what gates the build.

Other test runners

This guide covers the Eyes Playwright SDK. If you use Eyes with another runner, the move is the same shape: replace the check call with the matching Snapvisor SDK call, and replace the Applitools key with ARGOS_TOKEN. Snapvisor has SDKs for Cypress, Storybook and Puppeteer, and the CLI uploads any folder of images. See SDKs for the package list and setup.

The CI change

Eyes reads its key from APPLITOOLS_API_KEY. Snapvisor reads ARGOS_TOKEN.

Before:

- run: npm ci
- run: npx playwright test
  env:
    APPLITOOLS_API_KEY: ${{ secrets.APPLITOOLS_API_KEY }}

After:

- run: npm ci
- run: npx playwright test # captures via argosScreenshot, uploads via the reporter
  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 commit it. See Access tokens. On GitHub Actions you can drop the secret entirely with tokenless authentication. More workflows, including merge queues and fork pull requests, are in GitHub Actions recipes.

If you would rather not change how screenshots are produced, write them to a folder and upload it with the CLI:

export ARGOS_TOKEN="<your project token>"
npx @snapvisor/cli upload ./screenshots

Run both side by side

You do not have to switch in one pull request. Keep the Eyes calls and add the Snapvisor calls next to them in the same tests, with both keys set in the job:

- run: npx playwright test
  env:
    APPLITOOLS_API_KEY: ${{ secrets.APPLITOOLS_API_KEY }}
    ARGOS_TOKEN: ${{ secrets.ARGOS_TOKEN }}

A way to run the overlap:

  1. Add the Snapvisor calls on a branch, and merge them to your base branch so the first Snapvisor build becomes the baseline.
  2. Leave the Applitools check as your gate and the Snapvisor check optional while you compare results.
  3. When the Snapvisor builds match your expectations on a few pull requests, make the Snapvisor check required and remove Eyes.

Your first build becomes the baseline

The first Snapvisor build on your base branch has nothing to compare against, so it becomes the baseline and is approved automatically. On later builds, Snapvisor diffs each screenshot against the approved baseline for the base branch and posts a status check to the pull request. Approving a change in the review UI promotes it to the new baseline.

Because the first build is approved without review, run it on a base branch that is visually correct. See Baseline builds for how the reference build and base branch are resolved.

Make the Snapvisor check the gate

upload exits 0 once the build has been created, whether or not it contains changes. A non-zero exit means the upload itself failed (bad token, unresolvable commit, network, missing parallel arguments). 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.

If the check is optional, nothing blocks a merge. A green CI job after the Snapvisor upload means the screenshots arrived, not that they are unchanged. Require the check in branch protection — see GitHub or GitLab.

First-build checklist

After the first Snapvisor build on your base branch:

  1. Open the build and confirm it has a screenshot for each checkpoint you expected. Compare the count with your last Applitools batch.
  2. Look through the screenshots for fonts, images and animations that did not settle. Fix those first, before any threshold change.
  3. Run the same build twice on one commit and check that nothing shows as changed.
  4. Open a pull request with one small visual change. Confirm the Snapvisor status check appears, asks for review, and clears after you approve.
  5. Make the Snapvisor check required in branch protection.

Cleaning up

Once builds are landing in Snapvisor:

  1. Remove @applitools/eyes-playwright from devDependencies, and replace each eyes.check call and the eyes fixture.
  2. Delete your eyesConfig and any Applitools configuration files.
  3. Remove APPLITOOLS_API_KEY from your CI secrets.
  4. Take the Applitools status checks out of the required checks in branch protection so they stop blocking merges, and require the Snapvisor check instead.

Frequently asked questions

Can I import my Applitools baselines into Snapvisor?
No. There is no import path for another tool's baselines. Your first Snapvisor build on your base branch becomes the new baseline: it has nothing to compare against, so it is approved automatically. Plan the switch for a moment when your base branch is visually correct.
Is there a Snapvisor match level like Layout or Content?
No. Snapvisor has one comparison with a sensitivity setting, threshold. It does not offer separate layout-only or content-only modes. To keep a changing area out of the comparison, mask it. If you rely on a specific match level, test representative screenshots before you switch.
Does Snapvisor render my page on a grid of browsers the way the Ultrafast Grid does?
No. Snapvisor compares screenshots taken by the browser your own test runs in. To cover Chromium, Firefox and WebKit, run those as Playwright projects, and capture each viewport you care about with the viewports option.
Can I run Applitools and Snapvisor side by side while I switch?
Yes. The two use different packages, keys and CI settings, so you can add Snapvisor calls on a branch and compare the results before removing Eyes. Each tool keeps its own baselines, so expect differences between them rather than a one-to-one match.

On this page