diff --git a/CHANGELOG.md b/CHANGELOG.md
index b3b8fe3..a522c67 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,7 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/).
---
-### v3.5.0 — unreleased
+### 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)
diff --git a/README.md b/README.md
index f828193..0a5781f 100644
--- a/README.md
+++ b/README.md
@@ -28,7 +28,7 @@ Three files. Copy them as-is and `mvn test` goes green against a real Chrome.
io.github.seleniumboot
selenium-boot
- 3.4.0
+ 3.5.0
@@ -205,7 +205,7 @@ Add to your `pom.xml`:
io.github.seleniumboot
selenium-boot
- 3.4.0
+ 3.5.0
```
@@ -787,7 +787,7 @@ ci:
## Project Status
-**Current release: v3.4.0** — new header-keyed table extraction (`Locator.rows()`), bootstrap failures now log their full root-cause chain, and Selenium Java is bumped to 4.49.0.
+**Current release: v3.5.0** — zero-config first run (`selenium-boot.yml` is now optional), terminal `Locator` actions that wait and re-resolve stale elements, and JUnit 6 support.
See the full version history in **[CHANGELOG.md](CHANGELOG.md)**.
diff --git a/docs-site/docs/changelog.md b/docs-site/docs/changelog.md
index 5a0c162..1d18aaf 100644
--- a/docs-site/docs/changelog.md
+++ b/docs-site/docs/changelog.md
@@ -11,6 +11,15 @@ All notable changes to Selenium Boot are documented here.
---
+## [3.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)
+
+---
+
## [3.4.0] — 2026-09-19
### Added
diff --git a/docs-site/docs/getting-started.md b/docs-site/docs/getting-started.md
index c5ee385..3121f23 100644
--- a/docs-site/docs/getting-started.md
+++ b/docs-site/docs/getting-started.md
@@ -35,7 +35,7 @@ No WebDriver binaries required — Selenium Manager handles browser driver downl
io.github.seleniumboot
selenium-boot
- 3.4.0
+ 3.5.0
```
@@ -44,7 +44,7 @@ No WebDriver binaries required — Selenium Manager handles browser driver downl
```groovy title="build.gradle"
dependencies {
- testImplementation 'io.github.seleniumboot:selenium-boot:3.4.0'
+ testImplementation 'io.github.seleniumboot:selenium-boot:3.5.0'
}
test {
@@ -58,7 +58,7 @@ test {
```kotlin title="build.gradle.kts"
dependencies {
- testImplementation("io.github.seleniumboot:selenium-boot:3.4.0")
+ testImplementation("io.github.seleniumboot:selenium-boot:3.5.0")
}
tasks.test {
diff --git a/docs-site/docs/junit5.md b/docs-site/docs/junit5.md
index dbc7364..2fde4f1 100644
--- a/docs-site/docs/junit5.md
+++ b/docs-site/docs/junit5.md
@@ -17,7 +17,7 @@ Selenium Boot supports both **TestNG** (built-in) and **JUnit 5** (opt-in). The
io.github.seleniumboot
selenium-boot
- 3.4.0
+ 3.5.0
diff --git a/docs-site/docs/migration/from-selenium-testng.md b/docs-site/docs/migration/from-selenium-testng.md
index 972f483..d1db95e 100644
--- a/docs-site/docs/migration/from-selenium-testng.md
+++ b/docs-site/docs/migration/from-selenium-testng.md
@@ -26,7 +26,7 @@ Remove your Selenium, WebDriverManager, and reporting dependencies and add one:
io.github.seleniumboot
selenium-boot
- 3.4.0
+ 3.5.0
```
diff --git a/docs-site/src/pages/index.js b/docs-site/src/pages/index.js
index 3826ff8..03b3204 100644
--- a/docs-site/src/pages/index.js
+++ b/docs-site/src/pages/index.js
@@ -241,7 +241,7 @@ export default function Home() {
code={`
io.github.seleniumboot
selenium-boot
- 3.4.0
+ 3.5.0
`}
/>
diff --git a/pom.xml b/pom.xml
index ea56af0..019dd03 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
io.github.seleniumboot
selenium-boot
- 3.4.0
+ 3.5.0
jar
Selenium Boot