ScreenshotNeo

BlogHow-to

How to Use Selenide for Screenshot Testing

Selenide captures failure screenshots automatically. Learn named, element, JUnit, TestNG, CI, MHTML, troubleshooting, and ScreenshotNeo alternatives.

By the ScreenshotNeo team1 October 20269 min read

Short answer: Selenide takes a screenshot automatically when a Selenide check fails. In the current configuration API, screenshot capture is enabled by default, and artifacts normally go to build/reports/tests. You can also capture a named screenshot at any point, capture a single element, register JUnit or TestNG lifecycle hooks, and save HTML or Chromium MHTML page sources alongside the image.

This guide shows the complete workflow for Java projects: setup, automatic failure evidence, explicit captures, element screenshots, framework integrations, CI artifacts, MHTML, troubleshooting, and operational guidance. The behavior described here is based on the Selenide screenshots guide, the current Configuration API, the Selenide API, and the Screenshots API.

1. Add Selenide to a Java test project

Use the Selenide version already selected by your project and pair it with your test framework. The example below uses JUnit 5 and Maven coordinates; adjust the version and test framework to match your build.

<dependency>
  <groupId>com.codeborne</groupId>
  <artifactId>selenide</artifactId>
  <version>YOUR_PROJECT_VERSION</version>
  <scope>test</scope>
</dependency>

<dependency>
  <groupId>org.junit.jupiter</groupId>
  <artifactId> junit-jupiter</artifactId>
  <version>YOUR_JUNIT_VERSION</version>
  <scope>test</scope>
</dependency>

Selenide’s normal workflow is to open a page, act on elements, and check conditions. A failed condition automatically produces diagnostic artifacts according to the screenshot configuration.

2. Rely on automatic screenshots for failed checks

import org.junit.jupiter.api.Test;

import static com.codeborne.selenide.Condition.visible;
import static com.codeborne.selenide.Selenide.$;
import static com.codeborne.selenide.Selenide.open;

class LoginTest {
  @Test
  void showsTheLoginForm() {
    open("https://example.test/login");
    $("form#login").shouldBe(visible);
  }
}

If the check fails, Selenide captures a screenshot automatically. The official guide describes this as the default failure behavior, and the current configuration API documents screenshots as enabled by default. A failure capture is useful because it records the rendered state at the moment the assertion could not be satisfied.

Choose a predictable reports directory

The default reports folder is build/reports/tests for Gradle projects. Set a project-specific path with a system property:

mvn test -Dselenide.reportsFolder=test-result/reports

Or configure it in Java before the test runs:

import com.codeborne.selenide.Configuration;

Configuration.reportsFolder = "test-result/reports";
Configuration.screenshots = true;

System properties and Java configuration are both documented by the Configuration API. Keep the directory stable so local tooling and CI artifact upload steps can find it.

3. Capture a named screenshot at a deliberate checkpoint

Use Selenide.screenshot("name") when the screenshot is part of the test narrative rather than only a failure diagnostic.

import org.junit.jupiter.api.Test;

import static com.codeborne.selenide.Selenide.*;

class CheckoutTest {
  @Test
  void capturesTheReviewStep() {
    open("https://example.test/checkout");
    $("button[data-test='continue']").click();
    Selenide.screenshot("checkout-review");
  }
}

The named method creates checkout-review.png. Depending on configuration, it can also save .html or Chromium .mhtml. A named PNG is created even when Configuration.screenshots is false, because explicit capture is separate from automatic failure capture. The API can also return a capture in a requested form such as bytes, Base64, or a temporary file; consume or copy temporary files immediately if they must survive the test process.

4. Capture only an element

Element screenshots are useful for component-level evidence: a date picker, checkout summary, chart, or error panel. The Screenshots API includes file and image methods and iframe-aware variants.

import java.io.File;
import org.junit.jupiter.api.Test;

import static com.codeborne.selenide.Selenide.*;

class ComponentTest {
  @Test
  void capturesTheErrorPanel() {
    open("https://example.test/form");
    $("button[type='submit']").click();

    File image = $("[data-test='error-panel']").screenshot();
    // Copy image to durable test storage here if the CI job needs it later.
    System.out.println(image.getAbsolutePath());
  }
}

The returned file may be temporary and is not guaranteed to persist after tests complete. Copy it to your reports directory or upload it during the test while the file is available.

5. Capture successful tests and non-Selenide assertion failures

Automatic screenshots focus on failed Selenide checks. If you need a screenshot after every test, after successful tests, or when a general JUnit or TestNG assertion fails outside Selenide’s own checks, use the framework integration documented in the official screenshots guide.

JUnit 5

import com.codeborne.selenide.junit5.ScreenShooter;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.api.Test;

import static com.codeborne.selenide.Selenide.open;

@ExtendWith(ScreenShooter.class)
class JunitScreenshotTest {
  @Test
  void capturesUsingTheExtension() {
    open("https://example.test");
  }
}

The guide also shows a configurable registration using new ScreenShooterExtension(true).to("target/screenshots"). Confirm the exact class and registration syntax against the Selenide and JUnit versions in your project before copying it into a build.

JUnit 4 and TestNG

Selenide documents a JUnit 4 ScreenShooter rule and a TestNG ScreenShooter listener. These hooks are appropriate when the capture trigger belongs to the test framework lifecycle rather than to an individual Selenide condition. Register the integration using the syntax required by your selected framework version.

6. Save HTML or Chromium MHTML with the screenshot

A screenshot records pixels. Page source records markup separately. For difficult rendering or resource problems, enable page-source capture:

import com.codeborne.selenide.Configuration;

Configuration.savePageSource = true;
Configuration.savePageSourceWithResources = true;

Equivalent command-line settings are:

mvn test \
  -Dselenide.savePageSource=true \
  -Dselenide.savePageSourceWithResources=true

savePageSourceWithResources enables MHTML capture in Chromium through the DevTools Protocol’s Page.captureSnapshot. Selenide 7.18.0 release notes explain that if the browser is not Chromium, CDP is unavailable, or capture fails, Selenide falls back to ordinary HTML. Treat MHTML as a Chromium-specific enhancement, not a portable artifact format.

7. Make CI artifacts easy to find

  1. Set selenide.reportsFolder to a directory your CI system collects.
  2. Keep automatic screenshots enabled for failed checks.
  3. Add the directory to your CI test-artifact configuration.
  4. Use Configuration.reportsUrl when your test reports need links prefixed with a CI report URL.
import com.codeborne.selenide.Configuration;

Configuration.reportsFolder = "target/selenide-reports";
Configuration.reportsUrl = "https://ci.example.test/job/123/artifacts";

Selenide stores the files; your CI platform still needs a separate artifact-upload step. The Selenide documentation does not claim to upload artifacts for you.

8. Select the right capture route

Route Use it when Key detail
Automatic failure capture You need diagnostics for failed Selenide checks Enabled by default in the current API; controlled by Configuration.screenshots
JUnit/TestNG integration You need captures for successful tests or general assertion failures Hooks into the framework lifecycle
Selenide.screenshot("name") You need an intentional checkpoint Creates a named PNG independently of automatic capture settings
Element screenshot You need component-level evidence Returned files can be temporary; copy them promptly
Chromium MHTML You need markup with embedded resources Requires savePageSourceWithResources; non-Chromium fallback is HTML

9. Troubleshooting Selenide screenshots

No screenshot appears after a failure

Cause: automatic capture was disabled, the failure happened outside a Selenide check, or the report directory is different from the one you inspected.

Fix: confirm Configuration.screenshots = true, inspect the configured reportsFolder, and add the JUnit or TestNG integration for framework-level failures.

The screenshot is in an unexpected directory

Cause: Selenide uses its configured reports folder, which defaults to build/reports/tests for Gradle projects.

Fix: set -Dselenide.reportsFolder=... or Configuration.reportsFolder, then update the CI artifact path to match.

A named screenshot is missing

Cause: the test may terminate before the call, the process may not have permission to write the directory, or the file may be created under the configured reports folder rather than the working directory.

Fix: place Selenide.screenshot after the state you want to record, print the configured path during diagnosis, and verify filesystem permissions.

An element screenshot disappears after the test

Cause: the element screenshot API can return a temporary file.

Fix: copy the file into durable test storage immediately or consume its image representation before the test process exits.

MHTML is not produced

Cause: MHTML resource capture depends on Chromium and CDP. Other browsers, unavailable CDP, or capture errors use HTML fallback.

Fix: run the test in Chromium when MHTML is required, enable savePageSourceWithResources, and check the HTML fallback when the environment cannot provide CDP.

The screenshot shows the wrong state

Cause: the capture occurred before the UI finished updating, before an animation completed, or before the intended navigation.

Fix: wait for a meaningful condition such as visibility or text, then call the named or element screenshot. Prefer state-based waits over arbitrary sleeps.

CI has screenshots locally but not in the job artifacts

Cause: Selenide writes files but does not configure your CI artifact uploader.

Fix: publish the exact reportsFolder directory in the CI configuration and verify that the job runs from the expected working directory.

10. Performance, reliability, and cost considerations

  • Capture only useful checkpoints. Automatic failure screenshots are usually enough for diagnosis. Framework hooks that capture every successful test increase file count and storage.
  • Prefer element captures for focused evidence. They reduce review noise when the question concerns one component, while full-page captures preserve broader context.
  • Keep reports folders isolated per job. Parallel CI jobs should not overwrite identically named artifacts.
  • Use deterministic names. Include test or scenario identity when calling Selenide.screenshot, especially in parameterized tests.
  • Separate image and source retention. HTML and MHTML can be much larger than PNG files. Enable resource-rich capture only when it helps diagnose a real rendering or dependency issue.
  • Do not treat a screenshot as visual regression testing. The reviewed Selenide material documents capture and artifact creation; it does not establish built-in pixel-baseline comparison or a current visual-regression plugin recommendation.
  • Keep browser and Selenide versions aligned. Framework integrations and CDP-dependent behavior should be checked against the versions used by your project.

Or skip the browser setup

If you need screenshots of URLs rather than an in-process browser test, ScreenshotNeo provides a single HTTP endpoint and an MCP server for AI agents. It removes cookie and consent banners, newsletter popups, and chat widgets before capture. Bot checks, blank pages, timeouts, failed loads, and cache hits are not billed, and the response identifies the result with X-Page-Verdict and X-Billed headers.

One request returns PNG, JPEG, WebP, or PDF. The full option set includes full-page capture with lazy images loaded, CSS-selector element capture, dark mode, device presets and custom viewports, retina scale, PDF paper and margin controls, custom CSS and JavaScript, clicks, selector waits, delays, network-idle waits, request blocking, headers, cookies, user agents, authorization, timezone, geolocation, transparent backgrounds, resizing, TTL caching, signed links, asynchronous jobs with signed webhooks, bulk capture for up to 100 URLs per call, and a usage API. Parameter names used by other screenshot APIs also work to ease migration. See the ScreenshotNeo documentation.

cURL

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

Python

import requests

r = requests.get(
    "https://api.screenshotneo.com/v1/shot",
    params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
    timeout=90,
)
r.raise_for_status()
open("shot.webp", "wb").write(r.content)

Node.js

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 failed: ${res.status}`);
const fs = await import('node:fs/promises');
await fs.writeFile('shot.webp', Buffer.from(await res.arrayBuffer()));

ScreenshotNeo also includes take_screenshot, get_page_info, and capture_pdf MCP tools for Claude, Cursor, and other MCP clients. The Free plan includes 1,000 screenshots each month with no card; paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account.

FAQ

Does Selenide take screenshots automatically?

Yes. Selenide’s screenshot guide says it captures screenshots on test failure, and the current configuration API enables screenshots by default.

Can I disable automatic screenshots but keep named captures?

Yes. Set Configuration.screenshots = false for automatic failure behavior; an explicit Selenide.screenshot("name") still creates its named PNG.

Where are Selenide screenshots stored?

The documented default reports folder is build/reports/tests for Gradle projects. Configure reportsFolder when your build needs another location.

Does a screenshot prove that the page matches a baseline?

No. A screenshot is an artifact. Pixel comparison is a separate visual-regression workflow.

When should I use MHTML?

Use it when you need page markup with embedded resources for Chromium-based diagnosis. Selenide falls back to plain HTML when Chromium or CDP capture is unavailable.

Sources