Skip to main content

Selenium Boot

An opinionated, Spring Boot–inspired Java test automation framework.

Maven Central License


What is Selenium Boot?

Selenium Boot eliminates the boilerplate that every Java Selenium project repeats — WebDriver setup and teardown, wait helpers, retry logic, screenshot capture, and report generation — so your test code contains only test intent.

It is inspired by Spring Boot's philosophy: sensible defaults, convention over configuration, and zero required setup for common cases.

public class LoginTest extends BaseTest {

@Test(description = "Valid user can log in")
public void loginTest() {
open();
new LoginPage(getDriver()).login("admin", "secret");
Assert.assertTrue(new DashboardPage(getDriver()).isLoaded());
}
}

No WebDriver setup. No @AfterMethod teardown. No wait helpers. No retry configuration. Just the test.


Design philosophy

People often ask whether Selenium Boot is meant to be an opinionated framework, an extensible toolkit, or a thin productivity layer over Selenium. It's the Spring Boot of Java test automation — and the answer is layered, not equal parts of all three:

  1. Opinionated core (primary). Convention over configuration, zero boilerplate by default. Add one dependency, extend BaseTest / BasePage, and the framework has already made the sensible decisions for you. selenium-boot.yml is optional — SeleniumBootDefaults covers you if you never write it.
  2. Never hides Selenium (the constraint). Unlike heavier abstractions, Selenium Boot never takes the raw WebDriver away from you. When the conventions don't fit, drop straight down to WebDriver / By / WebElement. Opinionated without being a cage.
  3. Extensible toolkit (the escape hatch). An SPI/registry plugin system (DriverProviderRegistry, PluginRegistry, ReportAdapterRegistry) makes it modular for the power users who need it — serving the opinionated core, not replacing it. Most users never touch it.

Already invested in Selenium?

You don't have to abandon Selenium to get the ergonomics people love in Playwright. Selenium Boot brings those ideas into the Selenium ecosystem — so you keep your stack, your grid, and your team's skills:

Playwright ideaIn Selenium Boot
Accessibility-first locatorsgetByRole, getByLabel, getByText, getByPlaceholder, getByTestId — target the accessibility tree, survive CSS/DOM refactors
Auto-waitingWaitEngine-backed actions — Thread.sleep() disappears
Web-first assertionsassertThat(...) that auto-retries until true
Convention over configurationZero-boilerplate defaults, optional selenium-boot.yml

…all without hiding raw Selenium, and while keeping your existing Selenium / Java / TestNG stack, team skills, and Selenium Grid.

Why not just build your own framework?

Almost every Java team already has one: a home-grown BaseTest, a DriverFactory, a pile of wait utilities, and a reporting hack — rewritten from scratch at each new project or company. It's unpaid infrastructure you own, debug, and maintain forever, and it's rarely tested or parallel-safe.

Selenium Boot is that framework — already built, maintained, tested, thread-safe, and documented. You keep the part that's actually yours (the test intent) and delete the plumbing:

Roll your ownSelenium Boot
Write & maintain driver lifecycle, waits, retriesProvided, thread-safe, zero config
Build a reporting layer from scratchHTML report + JUnit XML included
Bespoke CI wiring per projectAuto-detects GitHub Actions / Jenkins / CircleCI
Onboarding = "read our internal wiki"Onboarding = public docs + one dependency
You fix the bugsThe framework ships the fixes

Selenium Boot is the Spring Boot of Selenium — zero setup, smarter defaults, Playwright-inspired APIs, and enterprise features, without hiding Selenium.


AI-powered test authoring

seleniumboot-mcp lets Claude or GitHub Copilot control a real browser, record your session, and generate Selenium Boot test code — TestNG, JUnit 5, Page Object, Gherkin, C# NUnit — in one prompt.

pip install seleniumboot-mcp

84 tools · self-healing locators · mobile emulation · codegen for Java / Python / C# / Playwright

PyPI · GitHub


What you get out of the box

Outcomes first — the API that delivers each one is on the right so you can jump straight to its docs.

What you getHow
Never write driver setup or teardown againOne driver per thread, created before each test, quit after
Switch environments without touching codeYAML config — browser, parallel, timeouts, retry in one file
Never write Thread.sleep() againAuto-waiting WaitEngine with 10+ built-in conditions
Flaky tests stop failing your buildGlobal, per-method @Retryable, or per-Cucumber-scenario @retryable tag
See exactly why a test failedScreenshot auto-captured on failure, base64-embedded in report
Read the test like a specStepLogger named steps with optional per-step screenshots
Hand stakeholders a report they'll readTabbed HTML dashboard — overview, test cases, failures, flakiness radar
Plug into any CI without extra toolingJUnit XML parsed natively by Jenkins, GitHub Actions, GitLab CI
CI that configures itselfHeadless forced, threads auto-tuned, no config changes needed
Extend it without forking itSPI-based plugins — custom drivers, hooks, report adapters
Bring your own test runnerFull JUnit 5 parity via @ExtendWith(SeleniumBootExtension.class) or BaseJUnit5Test
Write specs your product team can readBDD / Cucumber — BaseCucumberSteps, CucumberHooks, per-scenario steps in report
Test UI and API in the same suiteBaseApiTest, fluent ApiClient, JSONPath, schema validation, hybrid UI+API
Pin down the exact element, fluently$("selector").filter().nth().withText() — Playwright-style chainable locators
Tests survive CSS and DOM refactorsAccessibility-first locators — getByRole(Role.BUTTON).withName("Submit"), getByText, getByLabel, getByPlaceholder, getByTestId
Assertions that don't flake on timingWeb-first assertThat(By.id("x")).isVisible() — auto-retrying until timeout
Test admin-and-user flows in one testwithSession("admin", () -> { ... }) — two browsers in one test
Verify what actually landed in the DBdb().assertRowExists(), db().query().assertValue() — plain JDBC, no ORM
Assert on the email your app sentmailbox().waitForEmail(to("user@test.com")) — Mailhog, Mailtrap, Outlook, IMAP
Skip the browser for non-UI tests@NoBrowser — DB assertions, API checks, file operations, no WebDriver
Run on real cloud browsers unchangedexecution.mode: browserstack / saucelabs — session URL in HTML report
Understand failures without diggingAI failure analysis — Claude explains why a test failed and suggests a fix
Locators that repair themselvesSelf-healing fallback strategies when a locator fails
Know which tests will flake nextFlakiness prediction — risk scores from run history, radar chart in report
Drive tests from data you already haveExternal test data — @TestData("csv:..."), @TestData(value="excel:...", sheet="Login"), @TestData("db:SELECT...")
Test time-dependent behaviour deterministicallyClock mocking — clock().set("2030-01-01T00:00:00Z"), JS Date override, auto-reset

Philosophy

  1. Zero boilerplate — if the user writes more than 1 line to enable something, it should be a default
  2. Convention over configuration — smart defaults, YAML opt-in for advanced behaviour
  3. No required external services — works offline, no cloud APIs in core
  4. Opt-in complexity — advanced features behind config flags, off by default
  5. Single dependency — add selenium-boot and nothing else is required
  6. Test code stays clean — internals handle lifecycle; test methods contain only intent

Next steps