This guide walks you through your first browser automation test with
seleniumbase-rs. By the end you will have a working Rust project that opens a
browser, interacts with a page, asserts on the result, and cleans up.
What you will learn
- How to create a new Rust project and add
seleniumbase-rsas a dependency. - How to configure a
BrowserConfig. - How to create a
BaseCase, navigate, interact, assert, and quit. - How to run the test and interpret common startup errors.
- How to configure a session in code and through
SB_*environment variables. - A complete example that needs no network, and the same flow on the driverless CDP engine.
Prerequisites#
- Rust toolchain 1.99 or newer (the crate’s
rust-version). - A Chromium-based browser such as Google Chrome, Chromium, or Microsoft Edge.
- A network connection for the first build (dependencies may need to be fetched).
The crate can connect to an existing WebDriverThe Selenium protocol: a test sends commands to a driver such as chromedriver, which drives the browser. endpoint or auto-start
chromedriver for you. With the default WebDriver URL it first looks for a
driver already listening on http://localhost:4444; if there is none, it starts
downloaded_drivers/chromedriver on a free port, downloading the latest stable
chromedriver into that folder first when it is missing (it does not look on your
PATH). cargo run --bin sbrs -- install fetches the driver ahead of time.
Create a new project#
Create the project#
Add the dependencies#
Open Cargo.toml and add the dependencies:
The tokio runtime is required because BaseCase methods are async.
Write your first test#
Write the program#
Replace the contents of src/main.rs with the following program:
Run it#
You should see the browser open, fill the login form, submit, verify the welcome message, and close.
How it works#
BrowserConfig::default()returns a default configuration pointing athttp://localhost:4444with headlessThe browser runs without a visible window. mode enabled.with_mode(DriverMode::Uc)enables Undetected Chromedriver mode, which applies anti-detection evasions.with_headless(false)runs the browser with a visible window so you can watch the test. In CI you usually wanttrue.BaseCase::new(config).await?creates the browser session. If no WebDriver server is running, the crate attempts to start one.sb.open(url).await?navigates to the requested page.sb.type_text(selector, text).await?finds the element, clears it, and types.sb.click(selector).await?clicks the element.sb.assert_text_visible(text, selector).await?waits up to the default timeout (sb.set_timeout(secs)) for the text to be visible and fails if it never is, as Python’sassert_textdoes. For a different wait, callsb.wait_for_text(text, selector, timeout_secs).await?.sb.quit().await?closes the browser and ends the session.
Configuration#
BrowserConfig is a plain struct with with_* builder methods. These are the
settings most programs touch (all are in seleniumbase_rs::BrowserConfig):
| Setting | Builder | Default |
|---|---|---|
| Browser | with_browser(Browser::Edge) | Browser::Chrome (also Chromium, Firefox, Brave, Opera, Safari, ChromeForTesting, …) |
| Headless | with_headless(bool) | true |
| Engine mode | with_mode(DriverMode) | DriverMode::WebDriver (Cdp and Uc add DevTools helpers and anti-detection) |
| WebDriver endpoint | with_webdriver_url(url) | http://localhost:4444 |
| Browser binary | with_browser_binary_path(path) | none (from_env reads SB_CHROME_BIN) |
| Proxy | with_proxy(spec) or with_proxy_pac_url(url) | none |
| User agent, locale | with_user_agent(ua), with_locale("de-DE") | none |
| Profile and extensions | with_user_data_dir(dir), with_extension_dir(dir) | none |
| Start page | with_start_page(url) | none |
| Ad blocking | with_ad_block(bool) | false |
| Reuse browsers between tests | with_reuse_session(bool) | false |
| Extra Chromium arguments | with_extra_args([..]), push_extra_arg(arg) | none |
| Fingerprint | with_fingerprint(Fingerprint) | none; see Fingerprint & Stealth Profiles |
Two constructors build the starting point. BrowserConfig::default() uses the
defaults above and reads no environment variable. BrowserConfig::from_env()
returns a Result and reads the SB_* variables, which suits a deployed test
run because the same binary then needs no code change per environment:
Tracing filter (used by init_tracing_from_runtime); unset, it is RUST_LOG, then info.
Per-request client timeout for a remote grid, in seconds. Unset by default.
A value that does not parse (a non-number, or a SB_LOG_FORMAT other than
pretty or json) makes from_env return SeleniumBaseError::InvalidConfig;
from_env_lenient keeps the good values and lists the bad ones.
A complete example that needs no network#
This program is the whole project: Cargo.toml from above and this
src/main.rs. It loads a page from a string, types, clicks, asserts, saves a
screenshot, and closes the browser even if an assertion fails
(run_browser_test always calls quit).
cargo run starts (or downloads, then starts) chromedriver, opens a headless
Chrome, and exits with status 0 when every step passes. On a failed assertion
the error is printed and the exit status is non-zero.
The same page without a driver#
The pure CDP engine (seleniumbase_rs::sb_cdp) talks to Chrome directly, so
there is no chromedriver to download or start. It uses the same tokio
dependency:
Page also implements the capability traits (BrowserApi, ElementApi,
AssertionApi, ScreenshotApi), so a helper written over those traits runs on
both engines; see Capability traits.
The full engine is in Pure CDP.
Writing a #[tokio::test] instead of main#
For real test suites, use the test harness:
Run the test:
run_browser_test guarantees that quit is called even when assertions fail.
Common startup errors#
`WebDriver` connection error
Cause. No driver running, and auto-start does not apply: it needs auto_start_driver (on by default) and the default WebDriver URL http://localhost:4444.
Solution. Remove the custom URL, or start chromedriver yourself and pass its URL.
`chromedriver` not found
Cause. The driver executable is missing.
Solution. Install it with sbrs install or download it from the Chrome for Testing dashboard.
Chrome not found
Cause. The browser binary path is wrong.
Solution. Use BrowserConfig::with_browser_binary_path, or build the config with BrowserConfig::from_env() and set SB_CHROME_BIN (BrowserConfig::default() reads no variables).
Headless detected
Cause. Site blocks headless Chrome (headless sessions already use --headless=new).
Solution. Use with_headless(false).
Next steps#
CSS, XPath, link text and shadow DOM: how a selector string is read.
Wait for the page, then check it, without sleeps.
Run Chrome so sites see a person’s browser.
Slow a run down to watch it, and the other run-wide switches.
Every BaseCase method, the capability traits and the crate root.
One-off commands with sbrs, no project needed.
Run without a window in CI, and take screenshots, PDFs and downloads there.