Skip to main content

A plugin never sees sb_cdp::Browser, Page or BaseCase. The browser and each tab reach it as two small traits, BrowserHandle and PageHandle, which both engines of seleniumbase-rs implement, so one plugin works with either. Both are in seleniumbase_rs_plugin, defined in crates/seleniumbase-rs-plugin/src/lib.rs, and both are async through async_trait.

Who implements them#

ImplementationWherePublic
The pure CDP engine’s browser and tabssrc/sb_cdp/plugin_hooks.rs (BrowserLink, TabLink)no, the hooks receive them
seleniumbase_rs::sb_cdp::Pagesrc/sb_cdp/plugin_hooks.rsyes: impl PageHandle for Page, feature plugins
The WebDriver engine’s browser and windowsrc/browser/plugin_hooks.rs (DriverBrowser, DriverPage)no, the hooks receive them
RecordingBrowser, RecordingPageseleniumbase-rs-plugin-testingyes, see Testing

Every engine’s handle errors are PluginError::Other; the set wraps them as PluginError::Hook with the plugin and the hook.

BrowserHandle#

trait seleniumbase_rs_plugin::BrowserHandle

The running browser, as a plugin sees it in on_browser.

BrowserHandle::engine#

fn
returnEngine#

Engine::Cdp on the pure CDP engine, Engine::WebDriver on the WebDriver engine.

BrowserHandle::family#

fn
returnBrowserFamily#

The browser’s family. Always Chromium on the pure CDP engine; on the WebDriver engine, the family of the configured browser.

BrowserHandle::send#

fn async
method&strrequired#

A browser-level Chrome DevTools Protocol method, such as SystemInfo.getInfo.

paramsserde_json::Valuerequired#

Its parameters, usually json!(...); json!({}) for none.

returnResult<Value>#

The command’s result, as JSON.

Sends a browser-level command and returns its result. Browsers without the protocol return an error.

EngineWhat happens
Pure CDPSent on the browser’s own connection, with no tab session
WebDriver, ChromiumSent through chromedriver’s DevTools channel (goog/cdp/execute)
WebDriver, Firefox or SafariRefused: NAME has no Chrome DevTools Protocol channel through WebDriver, ...

On every engine the host refuses Fetch.* and Network.setRequestInterception first; see the request guard.

PageHandle#

trait seleniumbase_rs_plugin::PageHandle

A tab, as a plugin sees it in on_page_created, and as the set adds a plugin’s packages to it. On the WebDriver engine it is the window the session is on.

PageHandle::engine#

fn
returnEngine#

The engine that runs the tab. A page has no family(): read the family in on_browser, or from LaunchContext, if the plugin needs it.

PageHandle::send#

fn async
method&strrequired#

A Chrome DevTools Protocol method for this tab, such as Network.enable.

paramsserde_json::Valuerequired#

Its parameters.

returnResult<Value>#

The command’s result, as JSON.

Sends a command to this tab and returns its result. Browsers without the protocol return an error.

EngineWhat happens
Pure CDPSent on the tab’s own protocol session
WebDriver, ChromiumSent through goog/cdp/execute, which reaches the window the session is on
WebDriver, Firefox or SafariRefused, as for BrowserHandle::send

Before sending, every engine applies two rules:

  • Fetch.* and Network.setRequestInterception are refused, because the host owns request interception.
  • Network.setBlockedURLs is merged: its urls are added to the tab’s blocklist (the library’s ad-block list, the tracker hosts of a fingerprint and every pattern a plugin sent), and the whole union is sent, each pattern once, in the order it first arrived. urls must be a list of strings; a command with urlPatterns is refused, because it cannot be merged. A plugin cannot take a pattern back.

PageHandle::add_init_script#

fn async
source&strrequired#

JavaScript to run in every document this tab loads from now on.

returnResult<()>#

An error when the script cannot be added, or when it throws in the current document (the script threw: ...).

Runs source in every document this tab loads from now on, before the page’s own scripts.

EngineWhat happens
Pure CDP, and WebDriver with ChromiumPage.addScriptToEvaluateOnNewDocument, then Runtime.evaluate of the same source in the document already loaded
WebDriver, Firefox or SafariA WebDriver script now, and again after each navigation of the session, so it runs after the page’s own scripts. It runs as a function body: its top-level declarations stay local, so assign to window to share a value

PageHandle::evaluate#

fn async
expression&strrequired#

A JavaScript expression.

returnResult<Value>#

Its value, as JSON. An exception is an error, the script threw: ....

Evaluates expression in the current document and returns its value.

EngineWhat happens
Pure CDPRuntime.evaluate with returnByValue and awaitPromise, so a promise is waited for
WebDriver, every browserA WebDriver script that returns the expression (a trailing ; is dropped), in the frame the session is on; a promise is waited for

sb_cdp::Page as a PageHandle#

impl Feature: plugins impl PageHandle for seleniumbase_rs::sb_cdp::Page

A tab of the pure CDP engine is a PageHandle too, so a program can hand one of its own tabs to code written against the plugin API. It behaves as the tabs the hooks receive, guard included. Page also has inherent methods named evaluate and add_init_script, which differ (the inherent add_init_script returns an identifier and does not run the script in the current document), so call the trait’s with PageHandle::evaluate(&page, ...).