Skip to main content

Visual Testing and Image Comparison

SHAFT Engine provides built-in visual regression testing through the matchesReferenceImage() assertion. On the first run, SHAFT captures and stores a baseline screenshot. On subsequent runs, it compares the current state against the baseline using the selected comparison engine.

info

Visual baseline images are stored in src/test/resources/DynamicObjectRepository/ by default. Commit these files to source control so all team members and CI/CD pipelines share the same baseline.


Comparison Engines

SHAFT supports five visual validation engines through the VisualValidationEngine enum:

EngineDescriptionBest For
EXACT_EYESPixel-perfect comparisonStatic assets, logos, icons
STRICT_EYESHigh-sensitivity comparison with minor toleranceUI components
CONTENT_EYESCompares content while ignoring minor rendering differencesText-heavy pages
LAYOUT_EYESCompares layout structure, ignores content changesPage layout regression
OPENCVUses OpenCV for flexible image matchingComplex scenarios, partial matching

matchesReferenceImage()

Default Engine

VisualTesting.java
// Assert element matches a reference image (stores baseline on first run)
driver.element().assertThat(By.id("logo"))
.matchesReferenceImage();

Specific Engine

VisualTesting.java
import com.shaft.enums.internal.VisualValidationEngine;

// Visual regression with a specific engine
driver.element().assertThat(By.id("chart"))
.matchesReferenceImage(VisualValidationEngine.STRICT_EYES);

// Layout comparison — ignores content, checks structure
driver.element().assertThat(By.id("productCard"))
.matchesReferenceImage(VisualValidationEngine.LAYOUT_EYES);

Complete Example

VisualRegressionTest.java
import com.shaft.driver.SHAFT;
import com.shaft.enums.internal.VisualValidationEngine;
import org.openqa.selenium.By;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;

public class VisualRegressionTest {
private SHAFT.GUI.WebDriver driver;

@BeforeMethod
public void setup() {
driver = new SHAFT.GUI.WebDriver();
}

@Test
public void assertLogoMatchesBaseline() {
driver.browser().navigateToURL("https://example.com");
driver.element().assertThat(By.id("logo"))
.matchesReferenceImage();
}

@Test
public void assertChartMatchesBaseline() {
driver.browser().navigateToURL("https://example.com/reports");
driver.element().assertThat(By.id("salesChart"))
.matchesReferenceImage(VisualValidationEngine.STRICT_EYES);
}

@Test
public void assertPageLayoutMatchesBaseline() {
driver.browser().navigateToURL("https://example.com/home");
driver.element().assertThat(By.tagName("body"))
.matchesReferenceImage(VisualValidationEngine.LAYOUT_EYES);
}

@AfterMethod
public void teardown() {
driver.quit();
}
}

Updating Baselines

When an intentional UI change is made, delete the relevant baseline image from src/test/resources/DynamicObjectRepository/ and run the test once to regenerate it.

tip

Run visual tests in a consistent environment (same OS, browser version, screen resolution) to prevent false positives caused by rendering differences across platforms.

warning

Avoid running visual tests in headless mode if your baselines were captured in headed mode — subtle rendering differences between the two modes will cause false failures.