Browser tests fail most often because they interact with elements before the
page is ready. seleniumbase-rs provides implicit waiting in many action
methods, plus explicit waits and assertions that retry until a condition is met
or a timeout expires.
This page explains the waiting model, the available assertion helpers, soft assertions, and common mistakes to avoid.
Smart waiting in actions#
BaseCase actions wait for their element before acting, pollingChecking again at short intervals until the condition holds or the timeout passes. until it is
ready or the timeout passes (10 seconds by default; see
Default timeout):
| Action | Waits for the element to be |
|---|---|
click, double_click, context_click | visible and enabled |
type_text, send_keys, clear, hover, drag_and_drop | visible |
get_text, get_attribute, submit, set_value, select_option_by_* | present |
What an action does while it waits.
If the element never gets there, the action fails with
SeleniumBaseError::WaitTimeout, which names the selector and the state it was
waiting for. You do not need a manual wait before every action, but explicit
waits are still useful for precise timing or for waiting on dynamic state.
The wait is a poll, not a WebDriver implicit wait, so checks such as
is_element_present still answer at once instead of waiting out the timeout
when the element is absent.
Explicit waits#
Use explicit waits when the default implicit wait is not enough or when you want to wait for a specific condition other than visibility.
Timeouts are in seconds and are passed as u64 values. Some methods also have
a _default variant that uses the configured implicit timeout.
Text and title waits#
Wait for text or page title conditions:
Assertions#
Assertions return Result<(), SeleniumBaseError> and stop the test on failure.
The text assertions take the text first and the selector second, as in Python,
and wait for it for up to the default timeout (see below) before they fail.
Soft assertions#
Soft assertions collect failures and report them at the end of the test instead of stopping immediately. This is useful for validation-heavy tests where you want to see all failures at once.
If any deferred assertion failed, process_deferred_asserts returns an error
containing all of the failures.
Default timeout#
You can change how long actions and some other methods wait:
set_timeout returns the previous value so you can restore it later.
set_default_timeout(seconds) changes the same default (1 to 60 seconds) and
reset_default_timeout() puts it back.
Time limit for the whole test#
Once the test has run longer than the limit, counted from creating the
BaseCase, its next open, readiness wait or element action fails with a
time-limit error, and waits are cut to the time left.
A test that does none of those is not interrupted; wrap the test in
tokio::time::timeout for a hard stop.
Anti-patterns#
- Do not use
tokio::time::sleepto wait for pages. It makes tests slow and does not eliminate timing races. Use explicit waits instead. - Do not assert on exact styling. Assert on content, attributes, and state.
- Do not silently swallow assertion failures. Let errors propagate with
?so the test runner reports them.
Wait and assertion checklist#
- Rely on the actions’ built-in waiting instead of adding sleeps.
- Explicit waits are used for dynamic state changes.
- Timeouts are chosen based on realistic page timing, not worst-case guesses.
- Soft assertions are followed by
process_deferred_asserts. - Tests do not contain fixed sleeps.