Skip to content

Latest commit

 

History

History
397 lines (250 loc) · 48.1 KB

CHANGELOG.md

File metadata and controls

397 lines (250 loc) · 48.1 KB

Changelog

All notable changes to Selenium Boot are documented in this file.

The format is loosely based on Keep a Changelog, and this project adheres to Semantic Versioning.


v3.11.0 — 2026-11-10

  • Headed local browsers start maximized by default — Chrome gets --start-maximized and Firefox calls maximize() after launch, so a watched test is no longer left in a small window. Headless runs and containers (fixed 1920x1080) are unchanged, and your own --start-maximized, --window-size, --kiosk or Firefox --width/--height arguments still win. (#245)

  • HTML report: sortable columns in Test Cases table — clicking headers for Test, Status, Logic (ms), and Total (ms) sorts rows within each test class group ascending or descending with visual sort indicators, while preserving detail row attachments and cooperating with active status, tag, and search filters. (#217, #242)

  • HTML report: Expand all / Collapse all — one control on the Test Cases tab opens or closes every class group. (#218, #240)

  • HTML report: screenshot lightbox navigation — previous/next buttons move between a test's screenshots without closing the lightbox. (#219, #241)

  • HTML report: flaky trend chart hidden when empty — the chart no longer renders as an empty frame when no run had flaky tests. (#243)

  • Docs: quickstart fixed — example.com no longer has an "Example Domain" heading, so the quickstart test now asserts the "Learn more" link. (#244)

v3.10.0 — 2026-11-04

  • HTML report: print stylesheet for "Save as PDF" — printing the report now produces a clean document: UI chrome is hidden, all sections print instead of only the active tab, collapsed groups and failed-test details (error and full stack trace) are expanded, the light palette is used even in dark mode, and your on-screen filters are restored afterwards. (#221, #236)

  • HTML report: execution timeline — the dashboard now shows a Gantt-style timeline of when each test started and ended, built from the new per-test startedAtMs export. (#201)

  • HTML report: results by tag — a tag breakdown from TestNG groups, Cucumber tags and JUnit 5 tags, with click-to-filter in the Test Cases tab. (#167, #189)

  • HTML report: refreshed theme and restructured markup — the report's CSS, JavaScript and HTML partials are now separate files and the theme is aligned across tabs. (#192, #193, #194)

  • Tracing: failure traces recorded by default in CI — when tracing.enabled is not set, failed-test traces are recorded in CI and stay off locally. An explicit true/false still wins. (#198)

  • Selenium Java 4.51.0 → 4.52.0 — internal upgrade. 4.52.0 no longer ships the CDP devtools.v153 module, so NetworkMock, DeviceEmulator and the network trackers now use devtools.v154. No API change. (#238)

  • HTML report: status and tag filter persistence — the active status filter (All, Passed, Failed, Skipped, Flaky) and tag filter in the Test Cases tab are now persisted across page reloads and reopens using localStorage (sb-status-filter and sb-tag-filter). Storage reads and writes are safely guarded against restricted environments (private browsing, disabled storage, quota limits); if a previously stored tag is not present in the current report, it is gracefully ignored without restricting rows, and restoring filters preserves the default Dashboard tab view. (#215)

  • HTML report: "Copy failure details" button — failed tests with an error now have a button in the expanded detail row (and on the Failures tab) that copies the test id, error message and stack trace to the clipboard, with brief "Copied" feedback. Falls back to execCommand('copy') when navigator.clipboard is unavailable (e.g. some file:// setups). (#216)

  • Fix: @PreCondition session restore on a fresh browser — the cached cookies and localStorage were silently dropped when the next test started on about:blank, so only the first test per thread was logged in. Restore now navigates to the origin the session was captured on first.

  • LambdaTest cloud provider — execution.mode: lambdatest now creates W3C LT:Options sessions, supports environment-based credentials and capability overrides, and links each cloud session from the HTML report. (#197)

  • Cloud execution mode validation — execution.mode now accepts the existing browserstack and saucelabs providers, alongside local, remote, and the new lambdatest provider.

  • Trace shows browser console errors — when browser.captureConsoleErrors: true, the JS errors collected for a test now appear in its trace file under "Console Errors", next to the steps and failure details, so a shared trace includes what the browser logged. No change when the option is off. (#130)

  • Network mocking on Firefox via WebDriver BiDi — networkMock().stub(...) now uses WebDriver BiDi network interception under the hood when supported by the driver (including Firefox and BiDi-enabled drivers), falling back to Chrome DevTools Protocol (CDP) for Chromium-based drivers. The existing stubbing API (returnJson, returnBody, returnStatus, delay, clear) works identically across Chrome and Firefox. (#196)

  • Trace shows the locators each step used — every terminal Locator action (click, type, getText, …) is now recorded with its time offset and listed in the trace file under "Locators Used", grouped beneath the step it ran in. A lookup that timed out is marked "not found". Collected automatically, no config. (#130)

  • Trace: console errors and failed requests under the step they happened in — console errors (Chrome) now carry their timestamp and are listed beneath the step they occurred in. New opt-in tracing.captureNetwork: true records requests that returned 4xx/5xx or failed outright (CDP on Chrome/Edge, WebDriver BiDi on Firefox) and lists them the same way, so a trace shows the 500 behind a failed step. Off by default; successful requests are never recorded and at most 200 are kept per test. (#130)


v3.9.0 — 2026-10-21

  • GitHub Actions job summary: link to the run's artifacts — the failed-tests summary now adds a line linking to the workflow run page (built from GITHUB_SERVER_URL, GITHUB_REPOSITORY and GITHUB_RUN_ID, no config) where uploaded target/traces/ artifacts live, so a reviewer can get from a red PR to the trace in one click. Omitted when those variables are missing. (#130)

  • Locator keyboard and pointer actions: press(Keys...), focus(), doubleClick(), rightClick() — send keys without clearing the value, focus without clicking, or perform native double/context clicks directly on a locator. Each action re-resolves on every poll and retries stale or not-yet-present elements until timeouts.explicit elapses. (#134, #188)

  • HTML report: flaky-test trend line — the dashboard gains a third "Flaky Test Trend" line chart (flaky tests per run) next to the pass-rate and duration charts. (#185)

  • Fix: Cucumber quarantine check no longer silently skipped — checkCucumberQuarantine threw when the framework context was not yet initialised and the error was swallowed, so quarantined scenarios ran instead of being skipped. It now guards on initialisation. (#186)

  • Fix: Gemini default model — ai.provider: gemini now defaults to the gemini-flash-latest alias; the previously pinned gemini-2.5-flash returned 404 for new API keys. (#171)

  • Dependency updates — selenium-java 4.51.0, cucumber-testng 8.0.4, cucumber-junit-platform-engine, jackson-databind, mockito-core 5.24.0, jakarta.mail 2.0.2.

  • Results by Tag (TestNG groups, Cucumber tags, JUnit 5 @Tag) — capture test tags across TestNG groups, Cucumber scenario tags, and JUnit 5 @Tag, export them in selenium-boot-metrics.json, and render a "Results by Tag" card (passed/failed/skipped/pass rate per tag), tag chips on test table rows, and interactive click-to-filter in the HTML report. Absent when no tests have tags. (#167)

  • HTML report: tab and failure fixes — the report always opens on the Dashboard (it no longer restores the last-open tab), failure details start collapsed, and the Failures tab no longer goes empty after you expand or collapse a class in Test Cases (both tabs shared one group id).

  • Failure Intelligence: high-level triage and suggested actions — each failure is classified as Product bug, Test bug, Environment, Flaky or Unknown (flaky keeps its cause, e.g. Flaky (Locator not found)), with a rule-based suggested action. Shown in the HTML report, as failureType / suggestedAction in the metrics JSON, and in the JUnit XML; opt-in AI analysis uses it as a baseline. No API key needed. (#138)

  • AI provider is configurable — ai.provider selects the backend for failure analysis and the run summary: anthropic (default, unchanged), gemini, or openai (any OpenAI-compatible /chat/completions endpoint — OpenAI, Azure, Groq, local Ollama via ai.baseUrl). ai.model now defaults per provider. Existing configs keep working with no change.

  • AI run summary (opt-in) — ai.runSummary: true adds one short paragraph to the HTML dashboard summarising the run's failures: which same-cause groups account for most of them, which look like product bugs versus test or environment problems, and what to check first. One API call per run, independent of ai.failureAnalysis; only grouped error messages and test names are sent (see the data note in the HTML report docs). Absent when disabled, when nothing failed, or on any error; the suite result is never affected. The text is exported as aiRunSummary in the metrics JSON.

  • HTML report: pass-rate and duration trend charts — the dashboard now shows two line charts under the donut and percentile row, built from the last 20 runs in the metrics history (the same flakiness.historyDir / -Dseleniumboot.history.dir location the Flakiness Radar reads). They appear once there are at least two runs of history and stay hidden otherwise. (#160)

  • Cucumber on the JUnit Platform: quarantine and suite-lifecycle parity — quarantined scenarios run under cucumber-junit-platform-engine are now reported as aborted instead of failed (TestAbortedException; TestNG still gets SkipException). SeleniumBootLauncherListener now also clears the API health cache, loads pre-conditions and starts test-management reporting at test-plan start, matching the TestNG path, and the suite-start work is idempotent. docs-site/docs/cucumber.md documents the JUnit Platform runner as the recommended option. (#155, #158)

  • BaseCucumberTest deprecated — @Deprecated(since = "3.9.0"), because AbstractTestNGCucumberTests is deprecated for removal upstream in Cucumber 8.x. Nothing changes at runtime and existing TestNG Cucumber suites keep working; subclasses now get a deprecation warning. Plan to remove it in 4.0.0, once Cucumber drops its TestNG runner, in favour of cucumber-junit-platform-engine (added as an optional dependency). CucumberStepLogger also moves off the deprecated getStepText(). (#155, #157)

  • JUnit Platform: suite-start hooks now fire — ExecutionHook.onSuiteStart() was never called on the JUnit 5 path (only TestNG), so hooks that open a run or start a clock silently did nothing. SeleniumBootLauncherListener now bootstraps the framework and fires onSuiteStart() once per test plan.

  • Failed tests with trace links in GitHub Actions job summary — when running inside GitHub Actions and tracing.enabled: true is on, failed tests are automatically summarized in a Markdown table (test name, error message, and path to the HTML trace file) appended to $GITHUB_STEP_SUMMARY. Triage failures and locate trace paths directly from the Actions job summary without downloading artifact bundles; no-op outside Actions or when all tests pass. (#137)

  • Bounded failure detail record — every failed test now exports one optional-field failureDetail object with the failing locator, top application frame, last successful step, page URL/title, heal events, console errors, retry/history status, and representative same-cause context. The HTML failure panel and opt-in AI prompt reuse this record; raw errors and stack traces remain available. Text/list/URL limits and the exact AI data disclosure are documented. (#142)

  • Richer auto-retrying locator assertions — LocatorAssert adds isFocused() and isEmpty(), plus Pattern overloads for hasText, containsText, and hasValue. Regex failures report the locator and last observed value, and stale elements are re-resolved until timeouts.explicit. (#136)

  • Locator: waitFor(State), allTextContents(), and element screenshot() — waitFor(State) (and waitFor()) waits for an element to reach a target lifecycle state (VISIBLE, HIDDEN, ATTACHED, DETACHED), retrying up to timeouts.explicit. allTextContents() returns the text content of all matched elements in a single pass without waiting if empty, re-resolving if an element goes stale during read. screenshot() returns the element's PNG bytes, and screenshot(Path) writes them to a file path; both terminal actions re-resolve on every poll to survive stale elements. (#135)

  • flakiness.historyDir / -Dseleniumboot.history.dir — metrics history can now live outside target/. Builds that clean target/ or discard the CI workspace between runs had no history, so the Flakiness Radar and the newly/consistently-failing and intermittent statuses stayed empty. Point it at a directory your CI restores and saves (a cache or artifact store); the system property wins over the config. Default unchanged: <reports dir>/metrics-history. (#141)

  • Retry- and history-aware test status — each test now gets a status from this run's retries and the earlier runs in target/metrics-history/: Passed on retry, Newly failing (passed in every earlier run in the window), Consistently failing (failed in the two or more earlier runs) or Intermittent (mixed earlier results). A "Test status" card sits next to the Flakiness Radar, the status shows in the failure detail, and newly failing tests are listed first in the Failures tab. The metrics JSON gains testStatus. Radar thresholds and failOnHighFlakiness are unchanged. (#141)

  • Failure grouping — the report's Failures tab now opens with a "N tests, same cause" panel: failed tests are grouped by a signature of category, exception type, normalised message (ids, numbers and quoted values stripped) and top application stack frame. The flat per-class list is unchanged below it. With ai.failureAnalysis on, one Claude call is made per group; the other tests in the group reuse its analysis. The metrics JSON gains failureSignature. (#140)

  • Failure classification — every failed test is tagged with a category (LOCATOR_NOT_FOUND, ELEMENT_NOT_INTERACTABLE, STALE_ELEMENT, TIMEOUT, ASSERTION_MISMATCH, NAVIGATION_ERROR, BROWSER_CRASH, or UNKNOWN) and the evidence for it, from the exception class chain and message alone. No AI, no API key, no network. Shown as a badge in the HTML report's failure panel, as failureCategory / failureEvidence in the metrics JSON, and as the type of <failure> in the JUnit XML. The raw error and stack trace are unchanged. (#139)


v3.8.0 — 2026-10-11

  • Locator.first() and Locator.last() — narrow matches to the first or last matching element (e.g. getByRole(Role.LISTITEM).first()). Both resolve at action time, re-evaluating candidate elements on every poll and retrying stale/not-yet-present elements up to timeouts.explicit. (#132)

  • Locator form actions: clear(), check(), uncheck(), isChecked(), selectOption(text), selectOptionByValue(value), inputValue() — form controls can now be manipulated and inspected directly on Locator without falling back to BasePage helpers or raw WebElements. check() and uncheck() are idempotent (no click if already in the target state), isChecked() queries checked state without waiting, and terminal actions (clear, check, uncheck, selectOption, selectOptionByValue, inputValue) auto-wait, re-resolving from scratch on every poll to survive stale or late-appearing elements. (#133)

  • HTML report: the "Avg Time (ms)" stat tile is now "Suite Time" — the wall-clock suite duration in hh:mm:ss, matching the sidebar.

  • HTML report: suite duration in hh:mm:ss, wall-clock. The report previously showed the sum of every test's time in milliseconds, which overstates a parallel run. It now shows how long the suite actually ran (01:42:07; hours aren't capped). The metrics JSON gains suiteDurationMs; totalTimeMs (summed test time) is unchanged.

  • HTML report: results first. The dashboard now opens with a one-line run summary and the stat cards; the full run configuration moved into a collapsed "Run configuration" block at the bottom, with empty rows (Grid URL, unset CI fields) dropped. A "View failures" shortcut appears when any test failed.


v3.7.0 — 2026-10-04

  • Locator.dragTo(Locator) — drags one element onto another, including HTML5 drag-and-drop pages that ignore the native gesture. See Drag and drop. (#101)
  • debug.slowMoMs / debug.highlight — dev-only live-triage aids: pause after each Locator action and outline the element about to be acted on. Off by default, no cost when off; not for CI. See Debug. (#52)
  • withNewWindow(opener, body) / withNewTab(...) on BasePage — run the click that opens a new window, switch to it, run your checks, close it and return to the original window, even if the checks throw. No window opening within timeouts.explicit throws TimeoutException. See Handle new windows and tabs. (#49)
  • browser.version — optional exact browser version for local Chrome/Firefox runs, resolved by Selenium Manager. Omit it to use the installed browser. (#51)

v3.6.0 — 2026-09-27

  • WaitEngine.waitForNetworkIdle() / waitForResponse(urlPattern) — waits until no network request has been in flight for a quiet period (default 500ms, or a custom Duration), or until a response whose URL matches a glob pattern (same syntax as NetworkMock.stub) is observed, returning its HTTP status code. Both are bounded by the configured explicit timeout. Works on Chrome/Edge (via CDP) and any BiDi-capable browser such as Firefox; throws UnsupportedOperationException on others. Firefox sessions now request a BiDi connection by default (webSocketUrl capability) so this works with no extra configuration — an explicit value in the user's own browser.capabilities still wins.
  • open() names execution.baseUrl when the site can't be reached — a DNS or connection failure now reads Could not reach <url> (ERR_NAME_NOT_RESOLVED) — check execution.baseUrl in selenium-boot.yml … (the driver's error stays as the cause) instead of a bare net::ERR_NAME_NOT_RESOLVED. Applies to BaseTest, BaseJUnit5Test, BaseCucumberSteps and BaseConditions. Also fixes BaseJUnit5Test.open() with no execution.baseUrl failing with a bare driver error instead of naming the missing key. (#84)
  • Gradle projects now get their reports under build/ (#81) — the base directory is decided from build.gradle / build.gradle.kts (a pom.xml wins if both exist) instead of "does target/ exist", which other components had already created. Flakiness report, healed locators, traces, recordings, Allure results, screenshots and JUnit XML all follow it; -Dseleniumboot.reports.dir still overrides.
  • Docs: the Gradle systemProperties System.properties snippet is replaced (#82) — copying every JVM property broke test runs when the test JVM differs from Gradle's. It now forwards only browser and env.

v3.5.0 — 2026-09-24

  • Zero-config first run: selenium-boot.yml is now optional — with no default selenium-boot.yml in the working directory or on the classpath, the framework runs on built-in defaults (browser.name: chrome, execution.mode: local, timeouts.explicit: 10, timeouts.pageLoad: 30) and prints one [Selenium Boot] No selenium-boot.yml found — running with built-in defaults ... notice line. Fields a file omits (and an empty file) fall back to the same defaults; browser.name is only defaulted when browser.matrix is not set, and SeleniumBootDefaults overrides still take precedence over the built-ins. Nothing that was an error before stops being one: a requested profile (-Dselenium.boot.profile) or explicit path (-Dselenium.boot.config) whose file is missing still throws, so a typo never silently runs on defaults, and present-but-invalid values (an unknown execution.mode, a negative timeout) still fail validation. Adds ConfigurationLoader.load(File, ClassLoader) (working directory and classpath supplied, for tests). (#66)
  • Terminal Locator actions wait for the element and re-resolve it on every poll — click(), type(), append(), getText(), getAttribute(), hover(), scrollIntoView(), jsClick() and element() used to look the element up once and act on that cached reference, so a page that re-rendered it in between surfaced as a StaleElementReferenceException, and a locator that matched nothing yet threw immediately. They now resolve the locator from scratch on each poll, retrying on a stale or not-yet-present element until timeouts.explicit elapses. Behavior change: a locator that matches nothing is now retried for up to timeouts.explicit instead of failing at once. If it never matches, the call still ends in a LocatorException (cause: TimeoutException), so existing catches keep working; an element that exists but never becomes visible/clickable still times out with a TimeoutException, as before. isVisible(), isHidden(), isEnabled() and count() still never wait, and rows() inherits the wait for its table through element(). (#67, #68)
  • JUnit Jupiter API bumped 5.10.2 → 6.1.3 (junit-jupiter-api, optional dependency of the JUnit 5 bridge). junit-platform-launcher is now bumped to match (6.1.3, was 1.10.2), closing the pairing gap left by #64. Verified both directions against the consumer integration suite (11/11 real-browser JUnit 5 tests): a consumer still on JUnit 5.10.2 + launcher 1.10.2 keeps working unchanged, and a consumer on JUnit 6 (jupiter 6.1.3 + launcher 6.1.3) now works too. (#64)
  • Clearer error when execution.baseUrl is unset — open() and open(String) now throw execution.baseUrl is not set — add it to selenium-boot.yml, or navigate with getDriver().get(url) instead of baseURL is null or empty. Message only; still an IllegalStateException. The getting-started guide now says Step 3 needs the Step 2 file, since zero-config has no default baseUrl. (#77)

v3.4.0 — 2026-09-19

  • Locator.rows() — resolves a locator to a <table> and returns its data rows as header-keyed maps (List<Map<String, String>>), one map per row, keyed by column header. Headers are taken from the first <thead> row with <th> cells, falling back to the first <tr> anywhere with <th> cells, then the first <tr>'s <td> cells; whichever row supplies headers is never returned as data. Short rows are padded with "", extra cells are dropped, and <th>-only rows (group headings) are skipped. Contributed by @timothytkim. (#54)
  • Bootstrap failures now expose their root cause — when framework initialization throws, SuiteExecutionListener now logs the full cause chain (Caused by: ..., walked to the root) to System.err before rethrowing, so the actual failure reason is visible in normal Maven/TestNG/Surefire output instead of being buried one level down in the wrapping IllegalStateException. (Fixes #45)
  • Selenium Java bumped 4.40.0 → 4.49.0 (9 releases). This is a behavior-preserving internal upgrade: NetworkMock and DeviceEmulator are repointed from the now-removed CDP devtools.v144 module to devtools.v153 (the newer of the two bundled with 4.49.0), and two new trailing Optional.empty() arguments were added to Emulation.setDeviceMetricsOverride() calls to match v153's changed signature, preserving the existing defaults. Verified with the full 508-test suite.
  • Docs — the README and getting-started quickstarts now show the locator API ($(...)) instead of getDriver() for the first example, and the getting-started example is runnable as written. (#40, #44)

v3.3.0 — 2026-08-15

  • execution.parallel now validates against TestNG's own parallel modes, not a hand-written allowlist that had drifted from them — tests and instances are legitimate TestNG modes that flow straight through to XmlSuite.setParallel() and work exactly like methods/classes downstream, but Selenium Boot's bootstrap validator rejected them anyway, and did so with a "Parallel execution configuration missing" message — telling users their config was absent when it was present but simply not on the list. Validation now delegates to TestNG's XmlSuite.ParallelMode enum directly, so anything TestNG accepts, Selenium Boot accepts, and an unrecognised value's error message names both the rejected value and the full valid set instead of going stale again. (Fixes #35)

v3.2.0 — 2026-07-18

  • Three new WaitEngine conditions, consistent with the existing waitFor* naming:
    • waitForAttribute(By, attribute, value) — waits for an exact attribute match (use the existing waitForAttributeContains for a substring match)
    • waitForUrlMatches(String regex) — waits for the current URL to match a regular expression (use the existing waitForUrlContains for a substring match)
    • waitForTextMatches(By, String regex) — waits for an element's visible text to match a regular expression
    • Purely additive to the @SeleniumBootApi surface — no breaking changes. (Closes #12)

v3.1.1 — 2026-06-26

  • Per-engine report output directory — the metrics JSON, HTML report, and metrics history now honor the seleniumboot.reports.dir system property (the same switch already used for the JUnit XML report), defaulting to target as before. This fixes the HTML report being overwritten when two test engines run in one build — e.g. a TestNG suite (Surefire) and JUnit 5 tests (Failsafe): point each engine's run at its own directory (-Dseleniumboot.reports.dir=target/junit5) and each produces a self-contained report instead of the last one clobbering the first.
  • New com.seleniumboot.reporting.ReportPaths helper centralizes report path resolution.

v3.1.0 — 2026-06-25

  • Accessibility-first locators — new Playwright-style semantic locators on BaseTest and BasePage: getByRole, getByText, getByLabel, getByPlaceholder, getByTestId, getByAltText, getByTitle. They target the accessibility tree the user perceives instead of brittle CSS/DOM structure, so tests survive redesigns
  • getByRole(Role) — 38 WAI-ARIA roles, each matching both implicit HTML elements (<button>, <a href>, <h1>…) and explicit role="…" attributes; refine with .withName("Submit") (accessible-name match) and .withLevel(1) (heading level)
  • Case-insensitive substring by default, exact opt-in via .exact() — mirrors Playwright ergonomics; all locators flow through the existing auto-wait Locator chain (no Thread.sleep, no explicit waits)
  • toBy() escape hatch — every semantic locator can return its synthesized Selenium By for drop-down to raw Selenium or SmartLocator
  • Configurable test-id attribute — locators.testIdAttribute in selenium-boot.yml (default data-testid)
  • Accessible-name computation follows ARIA precedence (aria-label → aria-labelledby → associated <label> → text → value/alt/title)

v3.0.0 — 2026-06-21

  • TestRail + Xray Integration — annotate any test method with @TestRailCase("C1234") or @XrayTest("PROJ-123") (both support arrays for multiple IDs); results are pushed automatically after each test completes — no extra code in @Test methods; TestRail results are pushed per-test immediately; Xray results are batch-imported at suite end for efficiency
  • TestRail — creates a named run automatically (testmanagement.testrail.autoCreateRun: true); configurable projectId, suiteId, runName; maps PASSED→1, FAILED→5, SKIPPED→Retest(4); failure message is sent as the TestRail result comment
  • Xray Cloud — authenticates via OAuth2 client credentials (clientId + clientSecret); uses https://xray.cloud.getxpecto.com/api/v2 endpoints; supports testPlanKey linking
  • Xray Server/DC — HTTP Basic auth (jiraUrl + username + password); posts to /rest/raven/1.0/import/execution; both modes use the same @XrayTest annotation
  • Zero extra dependencies — clients use java.net.http.HttpClient (Java 17 built-in); no OkHttp, Apache HttpClient, or Jackson required for this feature
  • Works with TestNG and JUnit 5 — SuiteExecutionListener + TestExecutionListener handle TestNG; SeleniumBootExtension + SeleniumBootLauncherListener handle JUnit 5

v2.6.0 — 2026-06-20

  • Gradle Build Support — testImplementation 'io.github.seleniumboot:selenium-boot:2.6.0' in build.gradle; test { useTestNG() } is all that's needed; full docs with Groovy + Kotlin DSL samples, parallel config, JUnit 5 setup, and optional-dep table; JUnitXmlReporter auto-detects Maven vs Gradle by directory layout and writes to build/test-results/test/ (Gradle) or target/surefire-reports/ (Maven); override with -Dseleniumboot.reports.dir=; FrameworkVersion now reads Implementation-Version from MANIFEST.MF (set by maven-jar-plugin and Gradle jar task) so FrameworkVersion.get() returns the correct version in both build tools

v2.5.0 — 2026-06-20

  • Accessibility Assertions (axe-core) — accessibility().withTags("wcag2a","wcag21aa").withLevel(Impact.SERIOUS).excluding("#cookie-banner").run() runs an axe-core WCAG scan on the active page; axe-core 4.10.2 bundled in the JAR — no CDN, no extra Maven dependency; withContext("#main-form") scopes the scan to a subtree; collect() returns raw AccessibilityResult for custom inspection; detailed AssertionError message shows rule ID, severity, fix guidance, element selector, and docs URL for every failing node; available in BaseTest and BaseJUnit5Test

v2.4.0 — 2026-05-19

  • Performance Assertions — assertPerformance().lcp().isBelow(2500).fcp().isBelow(1800).ttfb().isBelow(600).cls().isBelow(0.1) — Core Web Vitals via browser-native window.performance API, no extra tool needed; LCP/CLS Chrome/Edge only, others all browsers; unavailable metrics silently skipped; performance.captureOnEveryTest: true shows ⚡ metrics strip in HTML report

v2.3.0 — 2026-05-17

  • Test Quarantine — selenium-quarantine.yml committed to the repo lists tests to skip; survives fresh CI clones; plain string or structured-with-reason format; class-only entry skips all methods in the class; Cucumber support via @quarantine tag; quarantine.enabled: false disables without editing the file

v2.2.0 — 2026-05-12

  • External @TestData sources — @TestData("csv:testdata/logins.csv") (built-in parser), @TestData(value="excel:testdata/users.xlsx", sheet="Login") (Apache POI optional dep), @TestData("db:SELECT username, password FROM test_users LIMIT 1") (JDBC via database config); row attribute selects zero-based data row (header excluded); type coercion: integers, doubles, booleans
  • TestClock — clock().set("2030-01-01T00:00:00Z") injects a JS Date override into the browser; clock().advance(Duration.ofDays(30)) fast-forwards from current mock; clock().reset() restores real time; auto-reset after every test (no cleanup needed); available via clock() in BaseTest and BaseJUnit5Test

v2.1.0 — 2026-05-04

  • BrowserStack integration — execution.mode: browserstack + browserstack.username/accessKey/os/osVersion/browser/browserVersion; W3C bstack:options capabilities; mobile device support via device + realMobile; session dashboard URL auto-injected into HTML report as "☁ View Session" link
  • Sauce Labs integration — execution.mode: saucelabs + saucelabs.username/accessKey/region/platformName/browser/browserVersion; three regions: us-west-1, eu-central, apac-southeast; W3C sauce:options capabilities; session dashboard URL in HTML report
  • Existing mode: remote (self-hosted Selenium Grid) unchanged — all three remote modes coexist

v2.0.0 — 2026-05-04

  • Email Verification — mailbox().waitForEmail(to("user@example.com")) polls until an email arrives; email.assertSubject(), email.assertBodyContains(), email.extractLink(linkText) for anchor extraction; mailbox().clear() purges the inbox; email.autoClear: true clears automatically before each test
  • Four backends: Mailhog (local/Docker), Mailtrap (hosted sandbox), Outlook/Office 365 (Microsoft Graph API — app-only OAuth2, no user login), IMAP (Gmail, Yahoo, any standards-compliant server via optional jakarta.mail dep)
  • Outlook config: tenantId, clientId, clientSecret, mailbox — OAuth2 token auto-refreshed and cached

v1.13.0 — 2026-05-03

  • @NoBrowser — annotate a test class or method to skip WebDriver creation entirely; no Chrome/Firefox window opened, no screenshot/recording/trace; all other framework services (report, steps, metrics, retry, hooks) still active; ideal for database assertions, API-only tests that extend BaseTest, and any test that does not touch the browser

v1.12.0 — 2026-05-03

  • Multi-Session Testing — withSession("alice", () -> { ... }) runs a lambda with a named browser session active; session("name") returns the raw WebDriver; all named sessions are automatically closed at test end; nested withSession() calls supported via stack-based driver restoration; available in BaseTest and BaseJUnit5Test
  • Database Assertions — db().assertRowExists(table, conditions), db().assertNoRow(), db().assertRowCount(), db().query(sql, params).assertValue(column, expected), db().scalar(sql, params); plain JDBC, no ORM dependency; named datasources via db("reporting"); connections pooled per thread and closed automatically at test end
  • New sessions.maxPerTest and database.* config blocks in selenium-boot.yml

v1.11.0 — 2026-05-03

  • @Retryable for JUnit 5 — InvocationInterceptor in SeleniumBootExtension retries failed test methods with full driver recreation between attempts; @Retryable(maxAttempts = N) on method or class overrides global config
  • @Retryable for Cucumber — entire scenario reruns from step 1 with a fresh driver via RetryAnnotationTransformer; retry detected in CucumberHooks and shown as retry badge in HTML report
  • @Retryable — new maxAttempts attribute + class-level target; fully backward-compatible

v1.10.0 — 2026-05-02

  • JUnit 5 Support — SeleniumBootExtension (@ExtendWith) handles driver lifecycle, screenshot on failure, AI analysis, trace, and recording; WebDriver injectable as test method parameter; BaseJUnit5Test base class with getDriver(), getWait(), open(), $(), assertThat(), step(); @EnableSeleniumBoot composed annotation; SeleniumBootLauncherListener generates HTML report when the JUnit Platform test plan finishes (registered via ServiceLoader — no config needed); parallel execution via junit-platform.properties

v1.9.0 — 2026-05-02

  • BDD / Cucumber Integration — BaseCucumberTest runner base + BaseCucumberSteps step definition base (getDriver(), open(), $(), assertThat()); CucumberHooks manages driver lifecycle, metrics, and screenshots per scenario automatically; CucumberStepLogger plugin streams Gherkin step names into the HTML report step timeline; cucumber-java and cucumber-testng declared as optional — consumers add their own version; cucumber.properties support for IDE single-scenario runs; Scenario Outlines produce individual report entries per example row

v1.8.0 — 2026-04-16

  • Self-Healing Locators — locators.selfHealing: true; when waitForVisible/waitForClickable times out, framework automatically tries fallback strategies: extract id from CSS #foo or XPath @id, name from CSS [name] or XPath @name, text from XPath text(), class from CSS .btn, data-testid; healed tests get ⚠ healed badge in HTML report; target/healed-locators.json lists every healed locator after suite
  • AI-Assisted Failure Analysis — ai.failureAnalysis: true + ai.apiKey: ${CLAUDE_API_KEY}; on test failure calls claude-haiku-4-5-20251001 with error message, stack trace, step log, URL, and page title; plain-English root-cause + fix suggestion embedded in HTML report below the stack trace; bounded by ai.timeoutSeconds (default 20s); fully non-blocking — never affects suite result
  • Flakiness Prediction — reads last flakiness.historyRuns (default 20) JSON files from target/metrics-history/; computes per-test failure rate; classifies as STABLE (<10%), WATCH (10–33%), HIGH (≥33%); Flakiness Radar card in HTML report; target/flakiness-report.json; flakiness.failOnHighFlakiness: true to gate builds

v1.7.0 — 2026-04-16

  • Trace Viewer — tracing.enabled: true generates a self-contained dark-themed target/traces/{Class}/{method}-trace.html per failed test; embeds step timeline with screenshots, final-state screenshot, error message + stack trace; zero CDN dependencies; captureOnPass: true option to trace passing tests too; "View Trace" link appears in the HTML report's failure detail panel

v1.6.0 — 2026-04-16

  • Visual regression testing — VisualAssert.assertScreenshot() pixel-by-pixel comparison; auto-creates baseline on first run; diff image saved to target/visual-diffs/; configurable tolerance via VisualTolerance.of(n); -DupdateBaselines=true to regenerate
  • Mobile device emulation — DeviceEmulator.emulate("iPhone 14") / emulateDevice() in BasePage/BaseTest; CDP-based on Chrome/Edge (viewport, scale factor, UA); window-resize fallback on Firefox; 6 built-in profiles (iPhone 14, iPhone SE, Pixel 7, Galaxy S23, iPad, iPad Pro 12) via DeviceProfiles registry
  • Clipboard helpers — ClipboardHelper.write/read/clear() backed by a reliable JS global store
  • GeoLocation mock — CDP-based on Chrome/Edge, JS navigator.geolocation override on Firefox
  • Network interception — NetworkMock.stub(pattern) stubs API responses via CDP Fetch domain; glob patterns, custom status, delay, auto-cleanup after each test
  • Browser storage helpers — StorageHelper.localStorage(), sessionStorage(), cookies() for reading/writing browser storage in tests
  • Fluent Locator API — $(css) / $(By) chainable locator: filter(), withText(), within(), nth(), auto-wait terminals
  • Web-First Assertions — assertThat(By/Locator) with auto-retry: isVisible, isHidden, hasText, containsText, hasAttribute, hasClass, count

v1.3.0 — 2026-04-07

  • Shadow DOM helpers — ShadowDom utility + 7 BasePage methods (shadowFind, shadowFindAll, shadowClick, shadowType, shadowGetText, shadowPierce, shadowExists)
  • Alert handling fix — unhandledPromptBehavior: ignore on all driver providers; BasePage.getAndAcceptAlert() convenience method
  • Component-aware waits — WaitEngine.waitForAngular() (Angular 2+/AngularJS 1.x) and WaitEngine.waitForReactHydration() (React 18/17/16, Next.js)
  • Enhanced HTML report — pass rate gauge, donut chart, retry badges, expandable error/stack trace rows, filter bar, search, dark mode, slowest-5 section
  • JUnit XML error details — <failure message> now contains the actual assertion message and full stack trace
  • Allure adapter — opt-in Allure 2 JSON result files in target/allure-results/ (reporting.allureEnabled: true)
  • Slack / Teams notifications — webhook-based post-suite summary with pass/fail counts and failed test list
  • @DependsOnApi — skip test immediately (before browser open) if a dependent HTTP endpoint is unreachable; repeatable; cached per suite

v1.1.1 — 2026-03-28

  • Schema validation — ApiResponse.assertSchema("schemas/user.json") validates response body against a JSON Schema file; requires com.networknt:json-schema-validator:1.4.3 on classpath
  • @UseAuth annotation — apply named auth strategy from config to any test method or class
  • ApiAuth.oauth2() — OAuth2 client credentials flow with automatic token caching and expiry refresh
  • ApiClient.setGlobalAuth() / clearGlobalAuth() — set auth once per suite, applied automatically to all requests

v1.1.0 — 2026-03-25

  • BaseApiTest — pure API test base class; no browser started; full framework lifecycle (reporting, @TestData, retry, CI gates)
  • ApiClient — fluent HTTP client backed by Java's built-in HttpClient; GET, POST, PUT, PATCH, DELETE; auto step-logging
  • ApiResponse — rich response wrapper; JSONPath extraction ($.user.id), asObject(Class), fluent assertions (assertStatus, assertJson, assertBodyContains)
  • ApiAuth — bearerToken(token), basicAuth(user, pass) auth strategies
  • ScenarioContext — thread-local in-test store; ctx().set/get; auto-cleared after each test
  • SuiteContext — global thread-safe store for cross-test state; suiteCtx().set/get
  • apiClient(), ctx(), suiteCtx() added to BaseTest for hybrid UI+API tests

v0.10.0 — 2026-03-22

  • @TestData — annotation-driven test data injection; loads JSON/YAML from src/test/resources/testdata/; env-specific override (admin.staging.json overrides admin.json when -Denv=staging); getTestData() in BaseTest
  • Browser matrix — browser.matrix: [chrome, firefox] in YAML runs every test on every browser in one mvn test; Browser column in HTML report; per-browser JUnit XML for Jenkins matrix view
  • SessionCache — SessionCache.store("name") / SessionCache.restore("name"); global cross-thread session reuse; reduces repeated login overhead in large parallel suites
  • SoftAssert — softAssert().that(condition, "message") collects failures without throwing; framework flushes at test end; single screenshot captured; all failures appear as individual step entries in the report

v0.9.6 — 2026-03-21

  • DownloadManager browser auto-configuration — Chrome and Firefox automatically configure download directory from browser.downloadDir config; no save dialog shown; partial downloads (.crdownload, .part) filtered out
  • Remote mode guard — download prefs skipped when execution.mode: remote (Grid sessions download to node filesystem, not local)
  • File upload helper — BasePage.upload(By, String) resolves paths via absolute → classpath → project-root; CI-safe

v0.9.5 — 2026-03-21

  • ConsoleErrorCollector auto-integration — when browser.captureConsoleErrors: true, the JS shim is auto-injected on every open() call and errors are auto-collected at test end as WARN step entries in the report
  • failOnConsoleErrors enforcement — when browser.failOnConsoleErrors: true, a passing test with JS errors is marked FAILED with a clear error listing the detected errors
  • StepStatus.WARN — new step status for JS error entries (does not affect test outcome)

v0.9.4 — 2026-03-20

  • iFrame helpers expanded — withinFrameName(String, Runnable) added; withinFrame, withinFrameIndex, withinFrameName now support nested frames (inner calls restore to parentFrame(), outermost restores to defaultContent())

v0.9.3 — 2026-03-20

  • Bug fix — alert methods (acceptAlert, dismissAlert, getAlertText, typeInAlert) in BasePage now use this.driver directly instead of WaitEngine/DriverManager, matching the driver reference used by the page object
  • Bug fix — @PreCondition failure error message now shows the real exception instead of "null" (unwraps InvocationTargetException)

v0.9.2 — 2026-03-20

  • Bug fix — precondition failure now throws SkipException (not RuntimeException); prevents retry from firing and a second browser from opening on @PreCondition setup failures
  • Bug fix — maxAttempts: 0 in YAML now respected; changed int field default to nullable Integer so intentional 0 is never silently overridden by programmatic defaults

v0.9.1 — 2026-03-19

  • Alert wait fix — acceptAlert, dismissAlert, getAlertText, typeInAlert now use WaitEngine.waitForAlert() — no more NoAlertPresentException on slow pages
  • WaitEngine.waitForAlert() — new explicit wait for browser alert presence
  • BasePage.smartFind() — convenience wrapper; use inside page objects without passing the driver

v0.9.0 — 2026-03-18

  • BasePage expanded — dropdowns (selectByText, selectByValue, selectByIndex, getSelectedOption), alerts (acceptAlert, dismissAlert, getAlertText, typeInAlert), mouse actions (hover, doubleClick, rightClick), scroll (scrollTo, scrollToTop, scrollToBottom), JS fallbacks (jsClick, jsType)

v0.8.0 — 2026-03-17

  • BasePage — page object base class: click, type, getText, isDisplayed, withinFrame, withinFrameIndex, upload
  • SmartLocator — tries multiple By strategies in order, returns first visible element
  • DownloadManager — waitForFile, waitForAnyFile, clearDownloads with partial-download detection
  • ConsoleErrorCollector — JS console error capture (Chrome via WebDriver logs, Firefox via injected shim)
  • @PreCondition — session-aware pre-conditions with cookie + localStorage caching per thread
  • @ConditionProvider + BaseConditions — define named condition providers, registered via SPI
  • @SeleniumBootApi — annotation marking stable public API with since version
  • FrameworkVersion + minFrameworkVersion() — runtime version checks, plugin compatibility enforcement
  • Config additions — browser.downloadDir, browser.captureConsoleErrors, browser.failOnConsoleErrors

v0.7.0 — 2026-03-16

  • StepLogger — named test steps with timestamps and optional per-step screenshots
  • Step timeline — step-by-step execution timeline in the HTML report Failures tab
  • Tabbed HTML report — Dashboard, Test Cases, and Failures tabs with collapsible rows
  • Browser lifecycle — browser.lifecycle: per-test | per-suite configuration

v0.6.0 — 2025-12-01

  • Advanced HTML report — pass rate gauge, donut chart, slowest tests card, retry badges
  • Self-contained report — screenshots base64-encoded, single file, no external dependencies

v0.5.0 — 2025-10-15

  • Retry support — retry.enabled + retry.maxAttempts in selenium-boot.yml
  • @Retryable — per-method retry override
  • Retry metrics — retry counts tracked in ExecutionMetrics and exported to JSON

v0.4.0 — 2025-08-20

  • CI auto-detection — GitHub Actions, Jenkins, CircleCI, GitLab CI; forces headless, tunes thread count
  • Container detection — Docker and Kubernetes; auto-applies Chrome container flags
  • JUnit XML reporter — target/surefire-reports/TEST-SeleniumBoot.xml
  • Build quality gates — BuildThresholdEnforcer enforces pass-rate and flaky-test thresholds
  • CI templates — GitHub Actions workflow and Jenkinsfile included

v0.3.0 — 2025-06-10

  • Plugin system — SeleniumBootPlugin + PluginRegistry with SPI discovery
  • Custom driver providers — NamedDriverProvider + DriverProviderRegistry
  • Custom report adapters — ReportAdapter + ReportAdapterRegistry
  • Lifecycle hooks — ExecutionHook + HookRegistry
  • SeleniumBootDefaults — programmatic config defaults for shared test-base JARs

v0.2.0 — 2025-04-05

  • WaitEngine — fluent explicit wait API
  • Thread-safe config — SeleniumBootContext with AtomicReference
  • Session semaphore — maxActiveSessions cap with fair wait
  • Global retry — retry.enabled: true retries all tests without @Retryable

v0.1.0 — 2025-02-01

  • Initial release — Chrome/Firefox, TestNG integration, selenium-boot.yml, basic HTML report, screenshot on failure