Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 34 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Selenium Boot

**A Zero-Boilerplate, Production-Ready Framework for Java QA Automation**
**The Spring Boot of Selenium — Playwright-inspired APIs, zero setup, and enterprise features, without hiding Selenium**

[![Maven Central](https://img.shields.io/maven-central/v/io.github.seleniumboot/selenium-boot)](https://central.sonatype.com/artifact/io.github.seleniumboot/selenium-boot)
[![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](LICENSE)
Expand All @@ -24,28 +24,43 @@ Selenium Boot is a zero-boilerplate, production-ready automation framework for J

It eliminates repetitive boilerplate by providing sensible defaults, a standardized project structure, and a convention-over-configuration approach — while keeping Selenium fully visible and accessible.

### Design Philosophy

Selenium Boot is **the Spring Boot of Java test automation** — and that positioning is deliberately layered:

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 — driver lifecycle, waits, retries, reporting, CI wiring. `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?** Selenium Boot gives you the productivity features people love in Playwright — **accessibility-first locators** (`getByRole` / `getByLabel` / `getByText`), **auto-waiting** so `Thread.sleep()` disappears, and **web-first assertions** — while keeping your existing Selenium / Java / TestNG stack, team skills, and Selenium Grid. You get the modern ergonomics without leaving the ecosystem you've already built on, and without ever hiding raw Selenium.

**Why not just build your own framework?** Most teams already have a home-grown `BaseTest` + `DriverFactory` + wait-utils they've rewritten a dozen times. Selenium Boot *is* that framework — maintained, tested, parallel-safe, and documented — so the driver lifecycle, retries, reporting, and CI wiring stop being unpaid infrastructure you own forever. You keep your test code; you delete the plumbing.

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

---

## What You Get Out of the Box

- Automatic WebDriver lifecycle management (no setup/teardown boilerplate)
- YAML-based configuration with environment profile switching
- Parallel execution with thread-safe driver isolation
- Smart explicit waits via `WaitEngine` — no more `Thread.sleep()`
- Automatic retry for flaky tests via `@Retryable`
- Screenshot capture on failure, embedded in report
- Advanced HTML report — pass rate gauge, donut chart, slowest tests, step timeline, dark mode
- `BasePage` — wait-backed `click`, `type`, `getText`, `isDisplayed`, iFrame helpers, file upload
- `SmartLocator` — tries multiple `By` strategies in order, returns first visible element
- **Accessibility-first locators** — `getByRole`, `getByText`, `getByLabel`, `getByPlaceholder`, `getByTestId`, `getByAltText`, `getByTitle`; target the accessibility tree the user perceives, so tests survive CSS/DOM refactors (Playwright-style, auto-waiting)
- `@PreCondition` — session-aware pre-conditions with automatic cookie + localStorage caching
- `ConsoleErrorCollector` — capture JS console errors (Chrome via logs, Firefox via shim)
- `DownloadManager` — poll download directory, handle partial files
- `StepLogger` — named test steps with timestamps and per-step screenshots
- **API testing** — `BaseApiTest` for pure API tests; fluent `ApiClient` with auth, schema validation, JSONPath; hybrid UI + API tests in the same suite
- **Accessibility assertions** — `accessibility().withTags("wcag2a","wcag21aa").withLevel(Impact.SERIOUS).run()` — axe-core bundled in JAR, no extra dependency; scoped scans, exclude selectors, fluent `Impact` level filter
- Plugin system — custom browser providers, report adapters, lifecycle hooks via Java SPI
- CI-ready — auto-detects GitHub Actions, Jenkins, CircleCI; forces headless, emits JUnit XML
Outcomes first — the API that delivers each one is named so you can find it in the docs.

- **Never write driver setup or teardown again** — automatic WebDriver lifecycle, thread-safe per test
- **Never write `Thread.sleep()` again** — auto-waiting `WaitEngine` with 10+ built-in conditions
- **Tests survive CSS and DOM refactors** — accessibility-first locators (`getByRole`, `getByText`, `getByLabel`, `getByPlaceholder`, `getByTestId`, `getByAltText`, `getByTitle`) plus a `SmartLocator` fallback that tries multiple strategies
- **Flaky tests stop failing your build** — automatic retry via `@Retryable`
- **Run your whole suite in parallel, safely** — thread-isolated drivers, `parallel` in one YAML line
- **Switch environments without touching code** — YAML config with environment profile switching
- **See exactly why a test failed** — screenshot auto-captured on failure and embedded in the report
- **Hand stakeholders a report they'll actually read** — HTML dashboard with pass-rate gauge, donut chart, slowest tests, step timeline, dark mode
- **Write pages, not plumbing** — `BasePage` with wait-backed `click`, `type`, `getText`, `isDisplayed`, iFrame helpers, file upload
- **Log in once, reuse the session** — `@PreCondition` with automatic cookie + localStorage caching
- **Catch JavaScript errors your users would hit** — `ConsoleErrorCollector` (Chrome via logs, Firefox via shim)
- **File download testing that just works** — `DownloadManager` polls the download dir and handles partial files
- **Read the test like a spec** — `StepLogger` named steps with timestamps and per-step screenshots
- **Test UI and API in the same suite** — `BaseApiTest` + fluent `ApiClient` with auth, schema validation, JSONPath; hybrid UI + API tests
- **Accessibility testing in one line** — `accessibility().withTags("wcag2a","wcag21aa").run()`; axe-core bundled in the JAR, no extra dependency
- **Extend it without forking it** — Java SPI plugins for custom browser providers, report adapters, lifecycle hooks
- **CI that configures itself** — auto-detects GitHub Actions, Jenkins, CircleCI; forces headless, emits JUnit XML

---

Expand Down
95 changes: 68 additions & 27 deletions docs-site/docs/intro.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,45 @@ No `WebDriver` setup. No `@AfterMethod` teardown. No wait helpers. No retry conf

---

## 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 idea | In Selenium Boot |
|---|---|
| Accessibility-first locators | `getByRole`, `getByLabel`, `getByText`, `getByPlaceholder`, `getByTestId` — target the accessibility tree, survive CSS/DOM refactors |
| Auto-waiting | `WaitEngine`-backed actions — `Thread.sleep()` disappears |
| Web-first assertions | `assertThat(...)` that auto-retries until true |
| Convention over configuration | Zero-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 own | Selenium Boot |
|---|---|
| Write & maintain driver lifecycle, waits, retries | Provided, thread-safe, zero config |
| Build a reporting layer from scratch | HTML report + JUnit XML included |
| Bespoke CI wiring per project | Auto-detects GitHub Actions / Jenkins / CircleCI |
| Onboarding = "read our internal wiki" | Onboarding = public docs + one dependency |
| You fix the bugs | The 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.

---

:::tip 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.
Expand All @@ -54,34 +93,36 @@ pip install seleniumboot-mcp

## What you get out of the box

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

| What you get | How |
|---|---|
| **Driver lifecycle** | One driver per thread, created before each test, quit after |
| **YAML configuration** | Browser, parallel, timeouts, retry — all in one file |
| **Smart waits** | `WaitEngine` with 10+ built-in conditions |
| **Retry** | Global, per-method `@Retryable`, or per-Cucumber-scenario `@retryable` tag |
| **Screenshots** | Auto-captured on failure, base64-embedded in report |
| **Step logging** | Named steps with optional per-step screenshots |
| **HTML report** | Tabbed dashboard — overview, test cases, failures, flakiness radar |
| **JUnit XML** | Parsed natively by Jenkins, GitHub Actions, GitLab CI |
| **CI auto-detection** | Headless forced, threads auto-tuned, no config changes needed |
| **Extensibility** | SPI-based plugins, custom drivers, hooks, report adapters |
| **JUnit 5** | Full feature parity via `@ExtendWith(SeleniumBootExtension.class)` or `BaseJUnit5Test` |
| **BDD / Cucumber** | `BaseCucumberSteps`, `CucumberHooks`, per-scenario steps in HTML report |
| **API testing** | `BaseApiTest`, fluent `ApiClient`, JSONPath, schema validation, hybrid UI+API |
| **Fluent locators** | `$("selector").filter().nth().withText()` — Playwright-style chainable locators |
| **Accessibility-first locators** | `getByRole(Role.BUTTON).withName("Submit")`, `getByText`, `getByLabel`, `getByPlaceholder`, `getByTestId` — target the accessibility tree, survive CSS/DOM refactors |
| **Web-first assertions** | `assertThat(By.id("x")).isVisible()` — auto-retrying until timeout |
| **Multi-session testing** | `withSession("admin", () -> { ... })` — two browsers in one test |
| **Database assertions** | `db().assertRowExists()`, `db().query().assertValue()` — plain JDBC, no ORM |
| **Email verification** | `mailbox().waitForEmail(to("user@test.com"))` — Mailhog, Mailtrap, Outlook, IMAP |
| **`@NoBrowser`** | Skip WebDriver for non-UI tests — DB assertions, API checks, file operations |
| **BrowserStack / Sauce Labs** | `execution.mode: browserstack` or `saucelabs` — cloud browsers with session URL in HTML report |
| **AI failure analysis** | Claude explains why a test failed and suggests a fix |
| **Self-healing locators** | Automatic fallback strategies when a locator fails |
| **Flakiness prediction** | Risk scores from run history, radar chart in report |
| **External test data** | `@TestData("csv:...")`, `@TestData(value="excel:...", sheet="Login")`, `@TestData("db:SELECT...")` |
| **Clock mocking** | `clock().set("2030-01-01T00:00:00Z")` — JS `Date` override, auto-reset after each test |
| **Never write driver setup or teardown again** | One driver per thread, created before each test, quit after |
| **Switch environments without touching code** | YAML config — browser, parallel, timeouts, retry in one file |
| **Never write `Thread.sleep()` again** | Auto-waiting `WaitEngine` with 10+ built-in conditions |
| **Flaky tests stop failing your build** | Global, per-method `@Retryable`, or per-Cucumber-scenario `@retryable` tag |
| **See exactly why a test failed** | Screenshot auto-captured on failure, base64-embedded in report |
| **Read the test like a spec** | `StepLogger` named steps with optional per-step screenshots |
| **Hand stakeholders a report they'll read** | Tabbed HTML dashboard — overview, test cases, failures, flakiness radar |
| **Plug into any CI without extra tooling** | JUnit XML parsed natively by Jenkins, GitHub Actions, GitLab CI |
| **CI that configures itself** | Headless forced, threads auto-tuned, no config changes needed |
| **Extend it without forking it** | SPI-based plugins — custom drivers, hooks, report adapters |
| **Bring your own test runner** | Full JUnit 5 parity via `@ExtendWith(SeleniumBootExtension.class)` or `BaseJUnit5Test` |
| **Write specs your product team can read** | BDD / Cucumber — `BaseCucumberSteps`, `CucumberHooks`, per-scenario steps in report |
| **Test UI and API in the same suite** | `BaseApiTest`, 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 refactors** | Accessibility-first locators — `getByRole(Role.BUTTON).withName("Submit")`, `getByText`, `getByLabel`, `getByPlaceholder`, `getByTestId` |
| **Assertions that don't flake on timing** | Web-first `assertThat(By.id("x")).isVisible()` — auto-retrying until timeout |
| **Test admin-and-user flows in one test** | `withSession("admin", () -> { ... })` — two browsers in one test |
| **Verify what actually landed in the DB** | `db().assertRowExists()`, `db().query().assertValue()` — plain JDBC, no ORM |
| **Assert on the email your app sent** | `mailbox().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 unchanged** | `execution.mode: browserstack` / `saucelabs` — session URL in HTML report |
| **Understand failures without digging** | AI failure analysis — Claude explains why a test failed and suggests a fix |
| **Locators that repair themselves** | Self-healing fallback strategies when a locator fails |
| **Know which tests will flake next** | Flakiness prediction — risk scores from run history, radar chart in report |
| **Drive tests from data you already have** | External test data — `@TestData("csv:...")`, `@TestData(value="excel:...", sheet="Login")`, `@TestData("db:SELECT...")` |
| **Test time-dependent behaviour deterministically** | Clock mocking — `clock().set("2030-01-01T00:00:00Z")`, JS `Date` override, auto-reset |

---

Expand Down
2 changes: 1 addition & 1 deletion docs-site/docusaurus.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const { themes } = require('prism-react-renderer');
/** @type {import('@docusaurus/types').Config} */
const config = {
title: 'Selenium Boot',
tagline: 'Zero-boilerplate Java test automation — inspired by Spring Boot',
tagline: 'The Spring Boot of Selenium — Playwright-inspired APIs, zero setup, without hiding Selenium',
favicon: 'img/logo.svg',

url: 'https://seleniumboot.github.io',
Expand Down
Loading
Loading