How to Integrate Selenium, Maven, and Jenkins
Add Selenium to a Maven project, run browser tests in a Jenkins Pipeline, and publish reports—even when tests fail.
To integrate Selenium, Maven, and Jenkins, add Selenium’s Java binding to pom.xml, make the required Java, Maven, and browser setup available on a Jenkins agent, then run the Maven lifecycle from a Pipeline. Publish the generated Surefire or Failsafe XML reports so Jenkins can display test results. This guide shows a compact JUnit 5 setup and Pipeline; adjust versions, tools, agent labels, and browser configuration to match your environment.
1. Add Selenium to a Maven project
Use the Selenium Java dependency in pom.xml. Keep its version in a property so it is straightforward to update, and check the Selenium downloads and installation documentation against the Java and browser setup you actually use. This guide does not prescribe a universal version combination.
<properties>
<maven.compiler.release>17</maven.compiler.release>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<selenium.version>REPLACE_WITH_VERIFIED_VERSION</selenium.version>
<junit.version>REPLACE_WITH_VERIFIED_VERSION</junit.version>
</properties>
<dependencies>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>${selenium.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>REPLACE_WITH_VERIFIED_VERSION</version>
</plugin>
</plugins>
</build>
Replace each placeholder with a version verified for your project. Maven Surefire runs tests in the test phase and writes reports. Keep test classes in src/test/java and use names Surefire recognizes, such as *Test, or configure the plugin if your naming differs. See the Selenium Java installation guidance and Maven Surefire documentation.
A minimal Selenium test
This JUnit 5 example assumes Chrome is available to the test process and that the Selenium/browser setup for the selected versions can start it. It opens a page and checks its title. Use a stable page under your control for a real test suite.
package example;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import static org.junit.jupiter.api.Assertions.assertTrue;
class HomePageTest {
@Test
void pageHasExpectedTitle() {
WebDriver driver = new ChromeDriver();
try {
driver.get("https://example.com");
assertTrue(driver.getTitle().contains("Example Domain"));
} finally {
driver.quit();
}
}
}
Always quit the driver in a finally block or an equivalent teardown hook. Otherwise, a failed assertion can leave browser processes behind and make later builds less reliable. For a suite, create and close one driver per test or per explicitly managed test context according to your isolation needs.
2. Prepare the Jenkins agent
The agent running the Pipeline needs the project’s Java runtime and Maven. Browser tests also need the browser environment and any driver or remote browser service configuration required by your Selenium version. Pin and verify the Java, Selenium, Maven, browser, and driver combination for the actual agent; there is no single compatibility matrix established here for every deployment.
- Install the Pipeline Maven Integration plugin and the Jenkins JUnit plugin if you plan to publish JUnit-format reports with the
junitPipeline step. - In Jenkins tool configuration, define Maven and JDK installations if you want Jenkins to select managed tools. Use the configured names in the Pipeline.
- Make sure the chosen agent label points to an agent with the needed browser environment and access to any external browser service used by the tests.
- Configure private repository access through Jenkins’ approved credential and Maven settings mechanisms. Do not put repository credentials in
pom.xmlor commit secrets in the Jenkinsfile.
The Pipeline Maven Integration plugin documentation describes withMaven, tool selection, settings configuration, and discovery of supported Maven artifacts and test reports. Its documented Maven build detection requirement is Maven 3.2 or later; confirm current plugin compatibility and requirements in Jenkins Update Center before installing or upgrading.
3. Run Maven and publish test results from a Pipeline
Commit a Jenkinsfile at the repository root. This Declarative Pipeline checks out the source, runs mvn clean verify inside withMaven, and publishes Surefire XML reports in an always post condition, including when tests fail.
pipeline {
agent { label 'browser-agent' }
tools {
jdk 'configured-jdk'
maven 'configured-maven'
}
stages {
stage('Checkout') {
steps {
checkout scm
}
}
stage('Build and test') {
steps {
withMaven(maven: 'configured-maven', jdk: 'configured-jdk') {
sh 'mvn -B clean verify'
}
}
}
}
post {
always {
junit testResults: 'target/surefire-reports/TEST-*.xml',
allowEmptyResults: true
archiveArtifacts artifacts: 'target/surefire-reports/**',
allowEmptyArchive: true
}
}
}
Replace browser-agent, configured-jdk, and configured-maven with names configured in your Jenkins instance. The sample uses a Unix-like agent’s sh step. On a Windows agent, use an appropriate batch step and shell syntax. The explicit JUnit publisher requires the Jenkins JUnit plugin. The Pipeline Maven plugin can also discover and publish supported Surefire and Failsafe reports; avoid accidentally publishing the same reports twice if you enable both mechanisms.
allowEmptyResults: true keeps a missing report from masking the build outcome, but it can also conceal a report-generation problem. Check the build log and ensure reports exist when a test run is expected. Remove that setting if a missing report should fail the Pipeline. The artifact archive is optional and preserves the XML files for diagnosis.
Choose the Maven lifecycle for your browser suite
| Suite placement | Typical Maven reporting | When to use it |
|---|---|---|
| Test phase | Surefire; reports commonly under target/surefire-reports |
Use when the browser tests are part of the normal Maven test suite. |
| Integration-test lifecycle | Failsafe; reports commonly under target/failsafe-reports |
Use when the project treats browser tests as integration tests and configures them for the integration-test/verify lifecycle. |
Choose deliberately rather than assuming every Selenium suite belongs in one phase. The Pipeline Maven plugin documentation supports Surefire and Failsafe report handling. If publishing Failsafe reports explicitly, use the actual report path and a matching publisher configuration available in your Jenkins setup; verify the generated XML files after the Maven run.
4. Run the build locally before wiring Jenkins
- From the project root, run
mvn -B clean verify. - Confirm the tests start the intended browser and close it when complete.
- Inspect
target/surefire-reportsfor XML results, or the configured Failsafe report directory for integration tests. - Push the
pom.xmlandJenkinsfile, then run the Pipeline against the intended agent. - Open the Jenkins test report and compare the result count with the generated Maven reports.
If Maven reports a failed test, the build should normally be marked failed while the post { always { ... } } block still publishes available results. A failed build with visible test details is more useful than a green build that silently skipped the suite.
5. Or skip the browser setup
If your goal is to capture a page image or PDF rather than exercise browser interactions, a screenshot API can remove the need to provision and maintain a browser for that capture. ScreenshotNeo is a website screenshot API and MCP server by Yorker Media. One GET request returns a PNG, JPEG, WebP, or PDF; see the ScreenshotNeo site and API documentation.
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,
)
r.raise_for_status()
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(`ScreenshotNeo request failed: ${res.status}`);
const bytes = new Uint8Array(await res.arrayBuffer());
await Bun.write('shot.webp', bytes);
The Node example uses Bun’s file-writing API. In Node.js, save the response bytes with fs/promises, for example by importing writeFile from node:fs/promises and calling await writeFile('shot.webp', Buffer.from(await res.arrayBuffer())). Protect your access key as a secret and do not expose it in public client-side code.
- Cookie banners and consent dialogs, newsletter popups, and chat widgets are removed before the shot; each cleanup step can be turned off.
- Bot checks and CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed. Response headers report the page verdict and billing status.
- An MCP server provides
take_screenshot,get_page_info, andcapture_pdftools for AI agents and MCP clients. - Free includes 1,000 screenshots per month with no card. Paid plans start at $5 for 3,000 screenshots; every feature is on every plan.
Create a free ScreenshotNeo account for 1,000 screenshots a month with no card.
6. Relevant capture options for a screenshot workflow
When a page capture is part of a test or CI artifact workflow, select the parameters that match the artifact and page behavior. ScreenshotNeo supports full-page capture with lazy images loaded, CSS-selector element capture, dark mode, device presets and arbitrary viewports, retina scale, custom CSS and JavaScript, clicks before capture, selector hiding, waits for a selector/delay/network idle, request and resource blocking, custom headers/cookies/user agent/Authorization, timezone and geolocation, transparent background, image resizing, configurable-TTL caching, signed public image links, asynchronous jobs with signed webhooks, batches of up to 100 URLs, usage API, and OpenAPI specification. Parameters used by other screenshot APIs also work to make migration easier. Consult the docs for exact parameter names and response behavior.
These captures complement browser tests but do not replace Selenium when the test must click through an application, assert interactive behavior, or validate a user journey. Keep assertions in the test suite and use screenshots as artifacts or for page-state review.
7. Troubleshooting
| Symptom | Likely cause | What to check or change |
|---|---|---|
| Jenkins shows no test results | Maven did not generate XML, the report path is wrong, or the JUnit publisher is unavailable. | Inspect the console log and report directories after Maven. Confirm Surefire/Failsafe configuration, Jenkins JUnit plugin installation, and the testResults glob. |
| Build uses an unexpected Java or Maven version | The configured tool name is missing or the Pipeline selects a different installation than expected. | Check Jenkins global tool configuration and the names in both tools and withMaven. Print java -version and mvn -version in a diagnostic build. |
| Tests pass locally but fail on the agent | The agent environment differs: Java/Maven, browser availability, environment variables, permissions, or remote browser settings. | Compare tool versions and browser setup between local and agent runs. Confirm the selected agent label and external browser service settings. |
| Browser fails to start in headless CI | The agent lacks the browser or required runtime configuration, or its browser and driver setup does not match the project. | Verify browser availability and the version pairing for the actual environment. Check startup logs and agent permissions; use the project’s supported headless or remote browser configuration. |
| Pipeline stops before reports publish | Report publication is in a later stage rather than an unconditional post action, or an earlier failure prevents it. | Keep publication in post { always { ... } }. Ensure the report step handles the no-report case intentionally. |
| Reports appear twice | Automatic Pipeline Maven report discovery and explicit junit publishing are both configured for the same reports. |
Choose one publishing path or configure paths so each report is published once. |
| Legacy Maven job behaves differently from Pipeline | Legacy job configuration and Pipeline integrations can discover or publish reports differently. | Review the Jenkins Maven Integration guidance; Jenkins recommends moving toward Pipeline or freestyle job types and the supported integrations for them. |
8. Performance, reliability, and cost
- Keep suites focused. Run fast unit tests on every change and place slower browser integration coverage in a lifecycle and stage that suits the project. The exact split depends on the suite and environment.
- Reduce avoidable setup. Reuse managed JDK and Maven installations consistently. Keep browser provisioning and any remote service configuration stable across agents.
- Make failures diagnosable. Preserve test XML and useful browser logs or screenshots as build artifacts when appropriate. Publish reports even after test failure.
- Control concurrency. Ensure parallel builds do not contend for shared browser profiles, ports, or external browser capacity. Isolate per-run state where your setup requires it.
- Budget infrastructure, not only the test command. The Selenium/Maven/Jenkins workflow uses open-source project configuration, but Jenkins agents, browser execution, and any separately managed grid have operational costs that vary by deployment. The dossier establishes no universal benchmark or cost estimate.
- For screenshot-only jobs, compare API usage with browser maintenance. ScreenshotNeo plans are Free for 1,000 shots/month, Starter $5 for 3,000, Growth $15 for 15,000, Pro $39 for 60,000, Scale $99 for 250,000, and Business $249 for 1,000,000; yearly billing gives two months free. Only clean shots are billed. Check the site for plan details.
FAQ
Should Selenium browser tests use Surefire or Failsafe?
Use the lifecycle your project has chosen for browser coverage: Surefire for tests in the Maven test phase, or Failsafe for suites configured as integration tests. Configure Jenkins to publish the matching reports.
Does the Jenkins JUnit plugin run the tests?
No. Maven and the configured test framework execute the tests. The JUnit plugin publishes compatible XML results in Jenkins.
Can Jenkins run this Pipeline on Windows?
Yes. The sample uses sh for Unix-like agents; replace it with the appropriate Windows batch step and command syntax for your agent.
Does a screenshot API replace Selenium?
No. Use Selenium to test browser interactions and application behavior. Use an API capture for screenshots or PDFs when you do not need to drive an interactive browser session.


