Skip to main content
Java · Selenium · TestNG · JUnit 5

Test automation
without the noise

The Spring Boot of Selenium — Playwright-inspired APIs, zero setup, without hiding Selenium

pom.xml
<dependency>
  <groupId>io.github.seleniumboot</groupId>
  <artifactId>selenium-boot</artifactId>
  <version>3.1.1</version>
</dependency>
LoginTest.java
public class LoginTest extends BaseTest {

  @Test(description = "Valid user can log in")
  public void loginTest() {
    StepLogger.step("Open login page");
    open();

    StepLogger.step("Enter credentials", true);
    new LoginPage(getDriver())
        .login("admin", "secret");

    StepLogger.step("Assert dashboard");
    Assert.assertTrue(
        new DashboardPage(getDriver()).isLoaded()
    );
  }
}
1Dependency to add
20+Built-in features
4CI platforms auto-detected
0Boilerplate required

Same test.
None of the plumbing.

Selenium Boot lets your team focus on testing, not framework engineering. The waits, the driver setup, the boilerplate — handled.

Plain Selenium
LoginTest.java
WebDriverWait wait = new WebDriverWait(
    driver, Duration.ofSeconds(10));

wait.until(ExpectedConditions
    .elementToBeClickable(By.id("login")))
    .click();

wait.until(ExpectedConditions.textToBe(
    By.cssSelector("h1"), "Welcome"));
Selenium Boot
LoginTest.java
$("#login").click();   // auto-waits

assertThat($("h1")).hasText("Welcome");

Everything you need,
nothing you don't

One dependency. Zero required config. Full-stack automation power, ready the moment you extend BaseTest.

Zero Boilerplate

Extend BaseTest, write @Test methods, and go. Driver lifecycle, waits, retries, reports, and screenshots are all handled — no setup code required.

class LoginTest
    extends BaseTest {

  @Test void login() {
    open();                 // driver ready
    getByRole(BUTTON)       // auto-waits
      .withName("Sign in")
      .click();
  }
}
🎯

Tests Survive CSS Refactors

Accessibility-first getByRole / getByText / getByLabel target the accessibility tree — Playwright-style, auto-waiting, and resilient to CSS or DOM refactors.

🩺

Locators That Repair Themselves

When a locator breaks, self-healing falls back through id, name, text, and data-testid automatically — and flags every heal in the report.

📊

A Report Stakeholders Actually Read

A tabbed HTML dashboard with a pass-rate gauge, retry badges, expandable errors, a Flakiness Radar, trace links, search, and dark mode.

🧠

Know Why a Test Failed

On every failure, AI failure analysis has Claude read the error, steps, and URL, then embeds a plain-English root cause and suggested fix in the report.

🤖

Generate Tests From a Prompt

AI test authoring via seleniumboot-mcp lets Claude or Copilot drive a real browser and generate ready-to-run Selenium Boot tests from a single prompt.

The complete toolkit

Twelve more capabilities, all built in — no plugins, no extra setup.

📄

Switch Environments Without Code Changes

One selenium-boot.yml controls browsers, threads, timeouts, retry, and CI gates.

🔁

Flaky Tests Stop Failing Your Build

Auto-retry flaky tests and rank them HIGH / WATCH / STABLE in the report.

📋

Write Pages, Not Plumbing

BasePage wraps clicks, waits, dropdowns, iframes, Shadow DOM, and uploads.

🔗

Pin Down Any Element

Fluent, Playwright-style chainable locators with auto-retrying assertThat().

🌐

Test Without a Real Backend

Mock API responses over CDP; read and write storage, cookies, and geo.

📸

Catch Visual Regressions

Pixel-diff screenshots and one-line device emulation for 6 mobile profiles.

🪜

Read the Test Like a Spec

Step logging — named steps with screenshots and a self-contained failure trace.

🔐

Log In Once, Reuse the Session

@PreCondition runs login once, caches the session, and restores it for every test.

📧

Assert on the Email Your App Sent

Email verification waits for real emails via Mailhog, Mailtrap, Graph API, or IMAP.

🕐

Test Time Without Waiting for It

Clock mocking freezes the browser clock to test expiry, trials, and countdowns.

☁️

Run on Real Cloud Browsers

BrowserStack or Sauce Labs by changing one config line.

🔌

Extend It Without Forking It

Register custom drivers, report adapters, and hooks via Java SPI / ServiceLoader.

Up and running
in 3 minutes

Add the dependency, create a YAML config, extend BaseTest — your first test runs with full reporting, retry, and smart waits already configured.

Read the guide
selenium-boot.yml
browser:
  name: chrome
  headless: false

execution:
  baseUrl: https://your-app.com

retry:
  enabled: true
  maxAttempts: 2

email:
  provider: mailhog

clock:
  injectHeader: false

Questions, answered

The things teams ask before adopting Selenium Boot.

No. Selenium Manager (built into Selenium 4) resolves and downloads the right driver automatically. You just need Chrome or Firefox installed.

All three. TestNG is the default, JUnit 5 has full parity via BaseJUnit5Test or @ExtendWith(SeleniumBootExtension.class), and Cucumber is supported through BaseCucumberSteps + CucumberHooks.

No — it is optional. SeleniumBootDefaults supplies sensible defaults for everything, so the framework runs with zero config. Add selenium-boot.yml only when you want to override a default.

Always. getDriver() gives you the live WebDriver, and every fluent locator exposes toBy() to hand back a standard Selenium By. Selenium Boot wraps Selenium — it never hides it.

Selenium Boot keeps you on the Selenium ecosystem (Grid, cloud vendors, the whole Java tooling world) while giving you the ergonomics people love about Playwright — fluent and accessibility-first locators, auto-waiting assertions, tracing, and codegen.

Yes. The driver is held in a ThreadLocal, so parallel TestNG/JUnit runs are isolated by default. Set parallel and threadCount in selenium-boot.yml and go.

It is free and open source under Apache 2.0, published to Maven Central. Add one dependency and you are done.

Ready to delete your boilerplate?

One dependency. One YAML file. Tests that read like intent.