Skip to main content

cargo test is the one test runner, and rstest supplies the fixtures. A test asks for sb: Sb (WebDriver, a BaseCase) or sb_cdp: SbCdp (pure CDP, a Page) and hands its body to run. The library then does what Python’s sb fixture does with the pytest options: it reads the run configuration, reruns a failed test, stops one that runs too long, leaves the evidence of a failure in latest_logs/, and closes the browser whatever happened.

Set up#

A test#

sb.run launches the browser, calls the closure with the open BaseCase, and closes the browser. It returns the test’s error, so ? and the assertions of BaseCase fail the test as usual; an assert! that panics fails it too, after the browser is closed. The closure is called again on a rerun, so it must not move out of what it captures.

For the pure CDP engine ask for sb_cdp: SbCdp and write sb_cdp.run(async |page| { ... }); the body gets the first Page. A Page has no test data of its own, so read it with sb_cdp.data().

Use #[case] for several inputs; each case is its own test with its own id and its own folder of evidence:

What the run configuration does#

The fixture reads Settings::load: the settings file (sbase_config.toml, or the file SB_SETTINGS_FILE names), with the SB_* variables on top. The test-related keys live in the [test] table and have a variable each.

Setting ([test])VariableWhat it does
reruns, reruns_delaySB_RERUNS, SB_RERUNS_DELAYRuns a failed test again, with a new browser, after the delay in seconds. A skipped test is never rerun. Each rerun prints RERUN <test id> (attempt 2 of 3) after: <error> to standard error.
time_limitSB_TIME_LIMITStops a test that runs longer, in seconds, and fails it with This test has exceeded the time limit of N seconds!. Time spent at a debug prompt does not count.
no_screenshotSB_NO_SCREENSHOTLeaves the screenshot out of the evidence.
save_screenshotSB_SAVE_SCREENSHOTSaves the screenshot and page source of a passing test too.
list_fail_pageSB_LIST_FAIL_PAGEPrints => Fail Page: <url> after a failure.
pdb, trace, final_debugSB_PDB, SB_TRACE, SB_FINAL_DEBUGThe debug prompts.
env, account, data, var1 to var3, variablesSB_ENV, SB_ACCOUNT, SB_DATA, SB_VAR1 to SB_VAR3, SB_VARIABLESThe test data below.

The browser settings (headless, browser, proxy, dark_mode, …) apply as they do everywhere else; see the settings page. To change one setting for one test, the Rust form of Python’s SB(...) arguments, use configure:

Test data#

--env, --account, --data, --var1 to --var3 and --variables of Python SeleniumBase are read from the BaseCase under the same names: sb.env() (test when none was given, otherwise one of the 24 environments, in lower case), sb.environment(), sb.account(), sb.data(), sb.var1(), sb.var2(), sb.var3() and sb.variables(), a JSON map. SB_VARIABLES takes a JSON object or the Python dictionary literal Python accepts.

Evidence of a failure#

A failed attempt leaves a folder named after the test, taken while the browser is still open:

The test id is the test binary, the module path and the function, joined with .; an rstest case adds its name. It is also sb.test_id(). The folder is written again by each attempt, so after a rerun it holds the last failure.

Debug prompts#

trace stops before the body, pdb after a failed last attempt (a post-mortem, the browser still open), and final_debug after every test, before the browser closes. Each prompt reads c to continue, s for a screenshot, src for the page source, u for the address, js <expression> and q to quit. Python’s stepping commands (n, s, r) have no equivalent.

Warning

A prompt needs a terminal: run cargo test -- --test-threads 1 --nocapture. Where nobody can answer (CI, a pipe, cargo nextest) the prompt is skipped with a warning in the log, so a flag left in a command never hangs a run. sb.breakpoint("message") pauses the same way anywhere in a body.

Seeing how every attempt ended#

Implement seleniumbase_rs::testing::Finalizer and register it with sb.finalizer(Arc::new(MyFinalizer)) to be told, once per attempt and with the page still open, how the attempt ended (Outcome::Passed, Failed or Skipped), how long it took and which attempt it was. The dashboard, the results database and the recorder plug in this way.

Note

run_browser_test and run_cdp_test stay the explicit forms that read no configuration; use them when a test must not depend on the environment.