How to use Applitools Eyes for website visual testing
Add Applitools Eyes visual checkpoints to Playwright, establish baselines, and review diffs safely. Includes setup, configuration, troubleshooting, and a ScreenshotNeo screenshot API alternative.
Applitools Eyes adds visual regression checks to browser tests: your test drives the application to a meaningful state, captures a checkpoint, and Eyes compares it with a stored baseline. You review the differences in Eyes Test Manager and accept an intentional UI change or reject a regression. The steps below use Playwright with TypeScript; the same workflow applies to other supported frameworks, but their SDK APIs and setup differ.
Choose the Eyes SDK that matches the browser automation and language your team already uses. Applitools lists integrations for Playwright, Selenium, Cypress, WebdriverIO, TestCafe, Puppeteer, and other frameworks. See the Eyes SDK selector and the Playwright integration guide for current setup details.
1. Set up Applitools Eyes with Playwright
You need an existing Playwright project and an Applitools account with an API key. Keep the key out of source control and provide it to the test process as APPLITOOLS_API_KEY. SDK setup can change, so follow the current official Playwright integration instructions when installing or upgrading.
# Add the Eyes Playwright SDK to an existing Playwright project
npm install --save-dev @applitools/eyes-playwright
# macOS or Linux: provide the key to the test process
export APPLITOOLS_API_KEY="YOUR_APPLITOOLS_API_KEY"
# Run the project's Playwright tests
npx playwright test
For Windows PowerShell, set the environment variable for the current session with $env:APPLITOOLS_API_KEY="YOUR_APPLITOOLS_API_KEY". For persistent or CI configuration, use your CI provider’s secret store. Never commit an API key in a test file or configuration file.
2. Add a checkpoint to an existing test
Use the Eyes-provided Playwright fixture by importing test from @applitools/eyes-playwright/fixture. Navigate and interact with the page as your functional test normally would, then call eyes.check() after the interface reaches the state you want to protect.
// tests/home.visual.spec.ts
import { test } from '@applitools/eyes-playwright/fixture';
test('homepage visual check', async ({ page, eyes }) => {
await page.goto('https://example.com');
// Capture the full page and compare it with the saved baseline.
await eyes.check('Homepage', {
fully: true,
matchLevel: 'Strict',
});
});
Give every checkpoint a stable, descriptive name. Names such as Homepage, Checkout — payment step, or Account — signed in help reviewers find the relevant state. The fixture manages the Eyes lifecycle for the test; if you use a different SDK integration, follow its lifecycle and runner instructions rather than copying this fixture pattern.
Capture just one element
A focused checkpoint can make component or navigation regressions easier to diagnose than a full-page image. Pass a Playwright locator as the region:
test('navigation visual check', async ({ page, eyes }) => {
await page.goto('https://example.com');
const navigation = page.locator('nav');
await eyes.check('Primary navigation', {
region: navigation,
matchLevel: 'Layout',
});
});
Use an element checkpoint when the element is the behavior or design contract under test. Keep at least some full-page checks when page-level layout, spacing, or interactions between components matter.
3. Establish and manage baselines
The first run has no prior baseline. Eyes marks the checkpoint as new and saves its captured image as the reference for later runs. Subsequent runs compare their checkpoint images against that reference and report differences. This is the core baseline workflow described in the Applitools visual testing overview.
- Run the test against a known-good application state.
- Open the results in Eyes Test Manager and inspect each new checkpoint.
- For a new test, confirm the image is the intended reference before allowing future runs to rely on it.
- On later runs, inspect the changed area and surrounding layout. Accept a difference only when it reflects an intentional UI change; reject it when it represents a defect.
- Save accepted baseline updates so later runs compare against the reviewed design.
A baseline is an expected result, not proof that the current UI is correct. If a broken rendering is accepted without review, later tests can treat that defect as normal. Avoid blanket acceptance of every changed checkpoint, especially after large refactors or dependency updates.
4. Choose capture scope and comparison settings
Start with the smallest set of settings that expresses what the test should protect. The documented Playwright integration supports full-page capture, region capture, match levels, ignored regions, floating regions, and displacement handling. Check the current API documentation for supported option names and SDK behavior.
| Setting or choice | Use it when | Watch out for |
|---|---|---|
fully: true |
The page can scroll and content below the initial viewport matters. | Long pages can take longer to capture and produce more changes to review. |
region |
You need to check a specific element or area, such as a menu or card. | A narrow region will not catch defects elsewhere on the page. |
Strict match level |
Content, styling, and position should remain visually consistent. | Real content changes can produce diffs; inspect whether they are expected. |
Ignore Colors match level |
Color differences are irrelevant to the assertion, while content or structure still matters. | Color regressions will not be caught in the comparison. |
Layout match level |
Structure and relative positioning matter more than exact text or styling. | It can overlook defects in content or visual styling that the test should protect. |
| Ignored regions | A specific changing area, such as a timestamp, cannot be stabilized and is not part of the assertion. | Ignored pixels cannot reveal a defect. Keep the region as small as possible. |
| Floating regions | An element may move while its own appearance should still be checked. | Use only for elements that are expected to move; otherwise movement can be a meaningful regression. |
| Displacement handling | Small shifts should not count as a failure under the intended comparison. | Position changes often matter. Confirm that suppressing them matches the user-visible contract. |
Match levels change what the comparison treats as significant; they do not make unstable test data deterministic. Prefer to stabilize data and page state first. If an area must vary, use a narrowly scoped region control and retain checks around it.
Set shared Playwright configuration
The Eyes Playwright integration documents shared settings through eyesConfig. For example, assign a recognizable application name and choose when a visual difference should fail the test. Confirm the configuration shape against the installed SDK version.
// playwright.config.ts
import { defineConfig } from '@playwright/test';
import type { EyesFixture } from '@applitools/eyes-playwright/fixture';
export default defineConfig<EyesFixture>({
use: {
eyesConfig: {
appName: 'Storefront',
failTestsOnDiff: 'afterEach',
},
},
});
The documented failTestsOnDiff choices include afterEach, afterAll, and false. Pick behavior that fits your runner and review process: failing earlier can make a changed test visible immediately, while collecting results can help teams review a batch together.
5. Make visual tests stable in local runs and CI
Visual comparison depends on capturing the same meaningful state each run. Before the checkpoint:
- Wait for the page’s required content or a specific locator, not an arbitrary short sleep.
- Use deterministic test data and a known account state.
- Control animations, rotating content, clocks, and random values when they are not part of the behavior being tested.
- Use consistent viewport and browser settings for a given baseline. If you deliberately add browser or device coverage, treat each intended rendering target as part of the test plan.
- Capture after fonts and important images have loaded when their final appearance matters.
- Keep checkpoints at meaningful states, such as after opening a menu or completing a form step, rather than after every action.
Eyes integrates with the test frameworks listed in its SDK selector. Choose browser and device coverage based on the applications your users run and the configuration available to your team. The Selenium Java quickstart’s JDK, Maven, Chrome, and ChromeDriver requirements apply to that example only; they are not universal prerequisites for every Eyes SDK.
6. Review visual diffs without hiding regressions
When a checkpoint changes, compare the baseline and current image and ask:
- Did the application change intentionally, or did the test reach a different state?
- Does the changed region affect readability, alignment, interaction, or the product’s visual design?
- Is the difference confined to genuinely dynamic content, or does it extend into stable parts of the UI?
- Would a narrower ignored region, a more suitable match level, or deterministic test data address the cause?
- Should the baseline be accepted, or should the change be fixed and the test rerun?
Accept an intentional redesign only after reviewing the result. Reject a regression and report it to the team. Avoid loosening comparison settings merely to turn a failing run green; that can erase the signal the visual test was added to provide.
7. Troubleshooting common problems
| Symptom | Likely cause | What to do |
|---|---|---|
| API key or authentication error | APPLITOOLS_API_KEY is missing from the process running the test, misspelled, or invalid. |
Set the secret in the same shell or CI job that runs Playwright. Confirm it is available without printing its value in logs. |
| Import error for the fixture | The Eyes package is absent, the dependency version is inconsistent, or the test imports Playwright’s default fixture. | Install the Eyes Playwright SDK in the project and import test from @applitools/eyes-playwright/fixture. Check the current integration guide for version-specific setup. |
| Every first checkpoint appears as new | No baseline exists yet, or the run is using a different test identity or application configuration. | Review the new result as a candidate baseline. Check checkpoint names and shared configuration before accepting it. |
| Unexpected diffs on every run | The app has dynamic content, animation, timing variation, changed test data, or inconsistent rendering conditions. | Wait for a stable state, make test data deterministic, and isolate only the truly variable area with a supported region option. |
| Full-page screenshot is incomplete | The page has not finished rendering or lazy-loaded content has not appeared before capture. | Wait for the content that matters to render and scroll or otherwise trigger lazy content using the test’s normal interaction flow before checking. Confirm full-page capture is enabled. |
| Diffs fail the test too early or too late | The selected failTestsOnDiff policy does not match the team’s review workflow. |
Configure the documented failure timing deliberately and verify the result in the installed SDK. |
| Local run works but CI fails | The CI job may lack the key, use different browser settings, or capture a different page state. | Check secret injection, runner configuration, test data, and checkpoint timing. Compare the captured result and environment settings. |
| Large numbers of diffs after a redesign | A broad intentional UI change affects many checkpoints, or tests are capturing unstable states. | Review the changed checkpoints in context, verify the new design, and update only the baselines that are intentionally different. |
8. Performance, reliability, and cost considerations
Each checkpoint adds capture and comparison work to the test run, and full-page or broader browser/device coverage can increase the amount of visual work. Keep checkpoints at states that protect a user-visible contract, and use targeted regions where they answer a specific question. Exact runtime and capacity depend on the test suite and account configuration; the research does not establish a universal benchmark.
For reliability, make the browser state repeatable and treat baseline changes as reviewed code-quality decisions. Store API keys as secrets, group related checks consistently, and make sure the CI job’s test result links reviewers to the associated visual results. Teams with network, security, or deployment constraints should validate whether cloud, dedicated-cloud, or on-premises configurations meet their requirements with current Applitools documentation and their administrator.
Applitools’ pricing page, retrieved for this guide’s research, listed Starter at $667 per month paid annually, with 100,000 component checkpoints or 1,000 page checkpoints. Pricing and allowances can change; check the current Applitools pricing page and confirm which checkpoint type and plan fit your use before budgeting.
Or skip the browser setup
If you need a clean screenshot of a live page rather than a baseline comparison inside your test suite, ScreenshotNeo is a website screenshot API and MCP server. A GET request returns an image or PDF. See the ScreenshotNeo API documentation for options and response details.
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}`);
const image = Buffer.from(await res.arrayBuffer());
await import('node:fs/promises').then(fs => fs.writeFile('shot.webp', image));
ScreenshotNeo removes cookie banners, newsletter popups, and chat widgets before the shot; bot checks, blank pages, and failed loads are never billed. Its MCP server lets AI agents take screenshots. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000. Sign up for ScreenshotNeo’s free plan.
FAQ
Does Applitools Eyes replace Playwright assertions?
No. Keep functional assertions for behavior and data conditions. Eyes adds visual checks for how the interface appears at selected states.
Should every page have a visual checkpoint?
No. Prioritize high-value flows, shared components, and states where a visual regression would matter. Too many low-value checks create review work without necessarily improving coverage.
Can I use Eyes with a framework other than Playwright?
Yes. Applitools lists multiple web and component SDK integrations. Use the SDK that matches your framework, and follow its own setup and checkpoint API.
Can a visual test tell whether a change is a bug?
It reports a difference from the stored reference. A reviewer must decide whether the change is intentional or a regression.


