Skip to main content

This guide covers additional BaseCase helpers that close the parity gap with Python SeleniumBase. These helpers handle page artifacts, window introspection, on-page messaging, console logs, traffic generation, charts, and deferred assertions.

Info

What you will learn

  • How to save screenshots and page source.
  • How to inspect and manipulate the browser window.
  • How to post messages and read console logs.
  • How to use deferred assertions for soft failures.

Page artifacts#

Both methods return a PathBuf pointing to the saved file in the logs directory (latest_logs/).

Warning

The name must be a plain file name: "../home.png" or "/tmp/home.png" is refused with an InvalidConfig error instead of writing outside the logs directory. A file of the same name is replaced.

For an exact path of your own, use save_screenshot_to_path. Files the framework names itself (save_screenshot_to_logs) never replace an earlier one.

Reading text from the screen (OCR)#

Feature: ocr

With the ocr feature, seleniumbase_rs::ocr::Ocr reads the text a page shows from its screenshot, including text drawn on a canvas or inside an image, which the DOM does not hold as text. It runs ocrs, pure Rust, so nothing has to be installed.

The text comes back one line per line of text, top to bottom.

Info

The first Ocr::load downloads the two models (about 12 MB) into the cache folder (below) and checks them against pinned SHA-256 hashes; later runs use the saved copies. On a machine without network access, set SB_OCR_MODELS to a folder that holds text-detection.rten and text-recognition.rten. Build with --features ocr; tests/ocr_chrome.rs reads a heading from a real Chrome.

The cache folder, by system:

Visual regression testing (pixels)#

Feature: visual

check_window is the port of Python’s: it compares the page’s layout, the tags of the HTML and their attributes, and keeps the screenshot only for a person to look at. A new colour, font, image or position that leaves the HTML alone passes it. With the visual feature, assert_visual_match compares the pixels instead:

The first run saves the screenshot as visual_baseline/<test>/home.png, where <test> is the test’s whole path: the test binary (the crate, or the file in tests/), the module path and the function, joined with ., such as cart.checkout.renders, so tests of the same name in other modules or files keep separate baselines. (check_window names its folder after the function alone, as Python does.) Later runs compare with it and fail with AssertionFailed when the similarity is below 0.999; the failure leaves two more files next to the baseline:

visual_baseline
<test>the test's whole path, such as cart.checkout.renders
home.pngthe baseline, saved by the first run
home.actual.pngthe new screenshot, left by a failing run
home.diff.pngthe new screenshot in grey with what changed painted red

A screenshot of another size fails without a comparison: set a fixed window size for visual tests. Run once with RunSettings::with_visual_baseline_reset(true) to accept intended changes, as for check_window.

For another folder or threshold, or with the pure CDP engine, use seleniumbase_rs::visual::VisualBaseline directly. check_page takes a BaseCase or an sb_cdp::Page, and check takes PNG bytes:

The score is the mean structural similarity (SSIM over 8 × 8 pixel windows) of the red, green and blue channels, the lowest of the three: 1.0 for identical images. Because it is a mean over the whole screenshot, a small change moves it little: in headless Chrome at 800 × 600 a rewritten 48 px heading scored 0.980 and failed, while one changed word of 16 px text scored 0.99926 and passed. To catch changes that small, compare a screenshot of the element, or raise the threshold. Rendering differs between machines and Chrome versions, so keep baselines per platform. The rustdoc of seleniumbase_rs::visual explains the algorithm and the threshold in full; tests/visual_chrome.rs runs both engines against a real Chrome.

Window introspection#

On-page messaging#

These helpers inject a visible banner into the page, useful for demos or MasterQA reports. The banner replaces the one already showing and goes away after the run’s message duration (post_message_for takes its own); in a headless browser that is at most 0.75 s, as in Python. Each call returns 0.15 s after the banner has gone, like Python’s pause=True.

Console logs#

Referral / traffic helpers#

These are real click-throughs, as Python’s are: the start page gets a link to the destination in place of its body, the link is clicked, and the destination receives a Referer header naming the start page. (Chrome’s default referrer policy sends the whole address to a page of the same origin and the origin alone to a page of another origin.) Pass an empty string as the start page to begin on the page the browser is on. A page that is not a valid URL, or a chain of fewer than two pages, is refused before anything is clicked.

Note

Earlier versions of this crate returned the URL with a ?ref= parameter added instead, which sends no Referer at all.

Multi-series charts#

Deferred assertions#

Deferred assertions check the page at once, collect the failures with the URL of the page they saw, and only fail the test when process_deferred_asserts is called:

Use them when you want to validate many independent conditions and report all failures at once.

Running the example#

The example demonstrates many of these helpers in sequence, and checks the effect of each one, so a run that finishes has shown that the helper did what its name says. It needs Chrome and a matching chromedriver, but not the network: it opens a page it serves from 127.0.0.1 (the examples/local_site module that the browser examples share). The screenshot, page source and chart land in latest_logs/.