Applitools Selenium Integration: Add Visual Testing to Your Selenium Tests
Adding Applitools Eyes to existing Selenium tests is straightforward. The SDK wraps your WebDriver instance and adds visual checkpoint methods. Your existing test structure stays intact.
This guide covers Java, Python, and JavaScript integrations with practical examples.
Java Integration
Maven Dependency
<dependency>
<groupId>com.applitools</groupId>
<artifactId>eyes-selenium-java5</artifactId>
<version>5.66.0</version>
</dependency>Gradle
implementation 'com.applitools:eyes-selenium-java5:5.66.0'Basic Test Structure
import com.applitools.eyes.selenium.Eyes;
import com.applitools.eyes.selenium.Configuration;
import com.applitools.eyes.RectangleSize;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.annotations.*;
public class VisualLoginTest {
private WebDriver driver;
private Eyes eyes;
@BeforeClass
public void setUp() {
driver = new ChromeDriver();
eyes = new Eyes();
eyes.setApiKey(System.getenv("APPLITOOLS_API_KEY"));
}
@Test
public void testLoginPage() {
eyes.open(driver, "My App", "Login Test",
new RectangleSize(1280, 720));
driver.get("https://myapp.example.com/login");
eyes.checkWindow("Login page");
driver.findElement(By.id("email")).sendKeys("test@example.com");
driver.findElement(By.id("password")).sendKeys("password");
eyes.checkWindow("Login form filled");
driver.findElement(By.id("submit")).click();
eyes.checkWindow("After login");
eyes.close();
}
@AfterClass
public void tearDown() {
driver.quit();
eyes.abortIfNotClosed();
}
}Checking Specific Elements
import com.applitools.eyes.selenium.fluent.Target;
import org.openqa.selenium.By;
// Check a specific element by WebElement
WebElement header = driver.findElement(By.cssSelector(".page-header"));
eyes.check("Header", Target.region(header));
// Check by CSS selector directly
eyes.check("Navigation", Target.region(By.cssSelector("nav.main-nav")));
// Check with ignore regions
eyes.check("Dashboard",
Target.window()
.ignore(By.cssSelector(".live-feed"))
.ignore(By.cssSelector(".timestamp")));Python Integration
Installation
pip install eyes-seleniumTest with pytest
import os
import pytest
from selenium import webdriver
from applitools.selenium import Eyes, Target
@pytest.fixture
def eyes_driver():
driver = webdriver.Chrome()
eyes = Eyes()
eyes.api_key = os.environ['APPLITOOLS_API_KEY']
yield driver, eyes
driver.quit()
eyes.abort_if_not_closed()
def test_homepage_visual(eyes_driver):
driver, eyes = eyes_driver
eyes.open(driver, "My App", "Homepage", {"width": 1280, "height": 720})
driver.get("https://myapp.example.com")
eyes.check_window("Homepage")
# Navigate and check another page
driver.find_element("id", "nav-products").click()
eyes.check_window("Products page")
eyes.close()
def test_form_validation_visual(eyes_driver):
driver, eyes = eyes_driver
eyes.open(driver, "My App", "Form Validation", {"width": 1280, "height": 720})
driver.get("https://myapp.example.com/signup")
# Submit empty form to trigger validation
driver.find_element("id", "submit").click()
eyes.check_window("Validation errors shown")
eyes.close()Python Element Targeting
from applitools.selenium import Target
from selenium.webdriver.common.by import By
# Check full page
eyes.check("Full page", Target.window().fully())
# Check a region
nav = driver.find_element(By.css_selector, "nav")
eyes.check("Navigation", Target.region(nav))
# Ignore dynamic content
eyes.check("Dashboard",
Target.window()
.ignore(driver.find_element(By.css_selector, ".notifications"))
.layout(driver.find_element(By.css_selector, ".chart-area")))JavaScript Integration
Installation
npm install @applitools/eyes-seleniumTest with WebdriverIO
const { Eyes, Target, Configuration, BatchInfo } = require('@applitools/eyes-selenium');
const { Builder } = require('selenium-webdriver');
describe('Visual tests', () => {
let driver, eyes;
beforeAll(async () => {
driver = await new Builder().forBrowser('chrome').build();
eyes = new Eyes();
const config = new Configuration();
config.setApiKey(process.env.APPLITOOLS_API_KEY);
config.setBatch(new BatchInfo('My App Suite'));
eyes.setConfiguration(config);
});
it('Homepage visual check', async () => {
await eyes.open(driver, 'My App', 'Homepage', { width: 1280, height: 720 });
await driver.get('https://myapp.example.com');
await eyes.check('Homepage', Target.window().fully());
await eyes.close();
});
afterAll(async () => {
await driver.quit();
await eyes.abortIfNotClosed();
});
});Integrating Into Existing Tests
The most common pattern: add visual checkpoints at key moments in existing functional tests without changing test structure.
// Existing test: login flow
@Test
public void testUserCanLogin() {
driver.get(baseUrl + "/login");
// === ADD VISUAL CHECKPOINT ===
eyes.checkWindow("Login page before interaction");
// =============================
driver.findElement(By.id("email")).sendKeys(testUser.email);
driver.findElement(By.id("password")).sendKeys(testUser.password);
driver.findElement(By.id("submit")).click();
// Functional assertion (existing)
assertTrue(driver.getCurrentUrl().contains("/dashboard"));
// === ADD VISUAL CHECKPOINT ===
eyes.checkWindow("Dashboard after login");
// =============================
}This way, each functional test also generates visual baselines. Visual regressions surface alongside functional failures.
Configuration Patterns
Batch Configuration (for CI)
Group all tests in a run into one batch:
BatchInfo batch = new BatchInfo("CI Run - " + System.getenv("BUILD_NUMBER"));
batch.setId(System.getenv("BUILD_NUMBER")); // Stable ID for CI runs
eyes.setBatch(batch);Match Level
// Default: exact pixel comparison
eyes.setMatchLevel(MatchLevel.STRICT);
// Layout only — ignores colors, font details
eyes.setMatchLevel(MatchLevel.LAYOUT);
// Content — ignores all styling
eyes.setMatchLevel(MatchLevel.CONTENT);Viewport Size
Set consistent viewport to avoid baseline mismatches:
eyes.open(driver, "App", "Test", new RectangleSize(1280, 720));Or configure globally:
Configuration config = eyes.getConfiguration();
config.setViewportSize(new RectangleSize(1280, 720));
eyes.setConfiguration(config);CI Configuration
Set APPLITOOLS_API_KEY as a CI secret. Optionally set APPLITOOLS_BATCH_ID to group parallel runs:
- name: Run visual tests
env:
APPLITOOLS_API_KEY: ${{ secrets.APPLITOOLS_API_KEY }}
APPLITOOLS_BATCH_ID: ${{ github.run_id }}
run: mvn test -Dtest=VisualTestsRelated:
- Applitools Eyes guide — core concepts
- Applitools Ultrafast Grid — cross-browser parallel testing
- Visual AI testing strategies — when and how to use visual testing