ScreenshotNeo

BlogHow-to

How to Add Visual Testing to Selenium Tests

Add visual checkpoints to Selenium, compare screenshots with approved baselines, and review changes without confusing rendering noise for regressions.

By the ScreenshotNeo team4 October 20268 min read

To add visual testing to Selenium, drive the browser to a meaningful, repeatable UI state, capture a named screenshot, and compare it with an approved baseline. A visual difference is a review signal: inspect it, fix unintended changes, and approve the new baseline only when the change is intentional. Keep existing functional assertions; visual checks cover how selected screens look, not whether every behavior works.

What visual testing adds to Selenium

Functional assertions can verify that a button works or that a message appears. A visual checkpoint checks the rendered screen against an accepted image, helping reveal unexpected layout, typography, color, or other visible changes. Applitools describes visual testing as regression testing for screens that have changed unexpectedly, and Percy documents capturing screenshots, comparing them to baselines, and highlighting differences. See Applitools’ visual testing overview and Percy’s overview.

A screenshot alone does not tell you whether a difference is a defect. The team must review the comparison in context and decide whether to fix the UI or accept an intentional design change.

Choose checkpoints that represent useful states

Start with a small number of screens where a visual regression would matter. Good candidates include:

  • A primary page after its important content has loaded.
  • A form in a representative validation or error state.
  • A meaningful success or confirmation state.
  • A key responsive layout at a viewport your users rely on.

Capture after Selenium has navigated and interacted to reach the intended state. Name each snapshot so a reviewer can identify the page and state without guessing. Avoid capturing every interaction indiscriminately: more checkpoints create more images to review and maintain.

Stabilize the page before capturing

Visual comparisons are most useful when the same test state produces a comparable screen. Before the capture:

  1. Wait for the specific content or element the checkpoint depends on, rather than relying only on a fixed sleep.
  2. Use predictable test data and a known starting state.
  3. Choose a consistent viewport and browser configuration for the baseline and later runs.
  4. Reduce avoidable variability, such as animations, rotating content, live timestamps, or other dynamic regions. Use controls provided by your visual testing tool where available; there is no universal Selenium setting that stabilizes every application.
  5. Capture only after the test has reached the state represented by the snapshot name.

These practices reduce noise, but they do not eliminate legitimate platform rendering differences. Fonts, form controls, and scrollbars can vary by operating system. Percy documents these differences in its browser and device guidance.

Approach 1: use a hosted visual testing service

A hosted service can manage snapshot comparison, build organization, and review and approval workflows. Percy documents Selenium integrations and baseline review. The general flow is: configure the service for the project, add a named screenshot call after Selenium reaches a checkpoint, run the test through the service’s documented build workflow, and review the resulting comparison.

Java with BrowserStack Percy

The Java integration uses the Percy SDK to capture a named state from the Selenium driver. Configure the project and dependency using the current Java setup guide; dependency versions and setup details can change, so use that guide rather than copying a frozen version.

// After configuring the Percy Java SDK for your project:
WebDriver driver = new ChromeDriver();
try {
    driver.get("https://example.com");
    new WebDriverWait(driver, Duration.ofSeconds(10))
        .until(ExpectedConditions.visibilityOfElementLocated(
            By.cssSelector("main")));

    // Assert the functional state as usual.
    assertTrue(driver.findElement(By.cssSelector("h1")).isDisplayed());

    // Capture a named visual checkpoint.
    PercySDK.screenshot(driver, "Home page - loaded");
} finally {
    driver.quit();
}

The example shows where the checkpoint belongs in a test; it is not a complete project setup. Follow the official guide for the current Maven configuration, imports, and build invocation.

Python with BrowserStack Percy

The documented Python workflow installs the Percy CLI and percy-selenium, then calls percy_snapshot on the browser after reaching the desired state. Follow the current Python integration guide for install commands and build invocation.

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
from percy import percy_snapshot

browser = webdriver.Chrome()
try:
    browser.get("https://example.com")
    WebDriverWait(browser, 10).until(
        EC.visibility_of_element_located((By.CSS_SELECTOR, "main"))
    )

    assert browser.find_element(By.CSS_SELECTOR, "h1").is_displayed()
    percy_snapshot(browser, "Home page - loaded")
finally:
    browser.quit()

Package APIs and compatibility can change. Confirm the current import, installation instructions, and CLI workflow in the official guide before wiring this into CI.

Build and review baselines deliberately

  1. Run the visual test to create the first snapshot set. This establishes images for review; without an approved baseline, a later run cannot be judged as a change from an accepted screen.
  2. Inspect initial snapshots for correctness: confirm the intended route, state, viewport, and test data are represented.
  3. Approve the initial baseline only after reviewing it as the expected UI.
  4. On later runs, inspect each meaningful difference. Accept a new baseline when the product change is intentional.
  5. If the change is a regression, leave the old baseline in place, fix the UI, and rerun the test.

Do not approve an entire build without reviewing its changes. See Percy’s build review documentation for its review workflow.

Approach 2: manage screenshot comparison yourself

You can use Selenium to save screenshots at named checkpoints, but a self-managed system also needs a place to store baselines, an image comparison method, a way to present differences, and an approval process that preserves the old baseline until changes are reviewed. Your team owns that tooling and its ongoing maintenance. The sources cited here do not establish a complete, current self-hosted diff stack, so choose and validate those pieces for your own environment rather than treating a screenshot file as a complete review workflow.

Expand browser and viewport coverage gradually

Start with one browser and a small stable set of checkpoints. After the workflow is producing useful comparisons, add browsers and widths based on your users and product requirements. Additional environments can reveal browser-specific rendering differences and create additional snapshots to review. Percy notes that fonts, form controls, and scrollbars may differ across operating systems; its documentation also explains that browser snapshots count toward screenshot usage. Check the current supported browser documentation and service usage terms when planning coverage.

Hosted service or self-managed comparison?

Consideration Hosted service such as Percy Self-managed screenshots
Capture Call the service SDK at named Selenium checkpoints. Save screenshots from Selenium at chosen checkpoints.
Baselines and review Service provides documented baseline comparison and review workflows. Your team chooses storage, comparison, diff presentation, and approval.
Browser coverage Use configured service support; account for platform rendering differences and usage. Depends on your browser execution and comparison infrastructure.
Ongoing work Maintain SDK and service configuration. Maintain image storage, noise controls, reporting, and review tooling.

This is a workflow comparison, not a claim that one approach is universally better. Check current provider documentation for supported integrations and plan details.

Performance, reliability, and cost considerations

  • Runtime: Each checkpoint adds capture and comparison work to the pipeline. Keep the initial suite focused on valuable states, then expand based on the regressions you need to catch.
  • Reliability: A stable test state, explicit waits, consistent viewport, and controlled data make comparisons easier to interpret. Investigate repeated noisy differences before adding more checkpoints.
  • Platform coverage: More browsers and operating systems can surface rendering differences, but they also increase the number of outputs to review.
  • Service cost: Usage and pricing vary by provider and can change. This research does not establish current prices or quotas; consult the provider’s live plan information before estimating cost. Percy documents that browser snapshots count toward usage.
  • Self-managed cost: There may be no hosted visual service charge, but your team must operate and maintain the comparison and review workflow.

Troubleshooting common problems

Symptom Likely cause What to do
The same test produces different images on each run. The page is captured before it settles, or contains changing data, animation, or other dynamic content. Wait for the relevant element, make test data repeatable, and control dynamic regions with supported tool options where available.
A large diff appears after a small UI change. The viewport, browser, operating system, font availability, or page state differs from the baseline run. Compare the execution configuration and test state first; keep baseline and comparison environments consistent.
The snapshot shows a loading state or missing content. The test captured before the relevant content appeared, or the page failed to load as expected. Add a wait for the specific content and retain functional assertions that verify the page reached the intended state.
The SDK call or package import fails. The project setup, dependency, import, or SDK version does not match the current integration instructions. Use the current official language guide, verify the dependency and configuration, and check Selenium compatibility.
A baseline update hides an unintended change. Changes were approved without reviewing the visual diff. Review each meaningful change; keep the old baseline when investigating a suspected regression.
Cross-browser diffs are noisy. Browsers or operating systems render fonts, controls, or scrollbars differently. Begin with one browser, then add environments deliberately and review platform-specific differences as separate expected outputs when appropriate.

Or skip the browser setup

If you need a clean screenshot of a URL without configuring a browser capture stack, ScreenshotNeo is a website screenshot API and MCP server for developers. It is not a Selenium visual baseline system: use Selenium visual checkpoints when you need to compare application states across test runs. For a standalone page capture, one GET request returns an image or PDF. See the ScreenshotNeo API documentation.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://example.com -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://example.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://example.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

ScreenshotNeo accepts cookie or consent banners and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each cleanup step can be turned off. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing, and response headers report the page verdict and billing status. Its MCP server provides take_screenshot, get_page_info, and capture_pdf for Claude, Cursor, and other MCP clients. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000 shots. Every feature is on every plan. Sign up for 1,000 free screenshots a month, with no card required.

FAQ

Does visual testing replace Selenium assertions?

No. Keep assertions for behavior and use visual checkpoints to review rendered appearance at selected states.

Should every Selenium test take a screenshot?

No. Start with a few high-value, repeatable states and add checkpoints where the visual result matters.

Can a visual diff tell me whether a change is a bug?

No. A diff identifies a change for review. Determine whether it is intentional before accepting a new baseline.

How should I begin cross-browser visual coverage?

Stabilize the workflow on one browser first, then add browsers and viewport sizes that match your users and product needs.