Skip to main content

A PluginSet holds the plugins a program uses, with the capabilities each was granted. It checks them against the browser about to start, orders them, and calls their hooks; seleniumbase-rs calls the set, so a program usually only builds one and hands it to a launch builder (Host). It is seleniumbase_rs_plugin::PluginSet, defined in crates/seleniumbase-rs-plugin/src/lib.rs; the run order comes from order.rs.

PluginSet#

struct seleniumbase_rs_plugin::PluginSet

The plugins a program uses, in the order their hooks run. An error from before_launch, on_browser or on_page_created stops there and is returned: a plugin that did not run must not leave a browser without what it adds. Cloning a set clones Arcs: the plugins themselves are shared.

MethodDoes
new, strictAn empty set; a strict one refuses undeclared plugins
with, with_sharedAdd a plugin with the default grants
with_trustedAdd a plugin with the default grants and named Critical ones
with_grants, with_grants_sharedAdd a plugin with exactly these grants
is_empty, namesRead the set
for_launchThe set for one browser, with fresh per-launch instances
check, check_withCheck every plugin before anything starts
auditEvery declared capability with its risk and grant
before_launch, on_browser, on_page_created, on_closeRun a hook of every plugin, in order

PluginSet::new#

fn
returnPluginSet#

An empty set, the same as PluginSet::default(). It runs plugins that declare no metadata.

PluginSet::strict#

fn
returnPluginSet#

An empty strict set, which refuses plugins that declare no metadata.

A strict set accepts an undeclared plugin when you add it, and refuses it at the check with PluginError::Undeclared. The command line, the MCP server, Registry::plugin_set and plugin_host::build_with use strict sets.

PluginSet::with#

fn
pluginimpl Pluginrequired#

The plugin to add. It is moved into an Arc.

returnResult<PluginSet>#

The set with the plugin at the end of the insertion order, or PluginError::DuplicateName when a plugin with the same name is in it.

Grants the plugin what it declares, except Critical capabilities:

The pluginGets
Declares metadata (Metadata::new)capabilities and optional, without the Critical ones (raw:*, host.process, cdp:Target, cdp:Browser)
Declares nothing (Metadata::legacy)CapabilitySet::legacy(): launch.args, launch.prefs, launch.headless, launch.proxy, launch.extensions, page.script:*, page.evaluate and raw:cdp

A plugin that requires a Critical capability therefore fails the check (it is required but not granted) unless it is added with with_trusted or with_grants.

PluginSet::with_shared#

fn
pluginArc<dyn Plugin>required#

A plugin shared with other sets, such as one a Registry built.

returnResult<PluginSet>#

As with, with the same default grants.

PluginSet::with_trusted#

fn
pluginimpl Pluginrequired#

The plugin to add.

trusted&[Capability]required#

Capabilities to grant besides the default grants. They may be Critical.

returnResult<PluginSet>#

As with.

The way to run a plugin that requires raw:cdp, raw:switches, host.process, cdp:Target or cdp:Browser. A set built from names never grants those, so such a plugin is added in code.

PluginSet::with_grants#

fn
pluginimpl Pluginrequired#

The plugin to add.

grantsCapabilitySetrequired#

Exactly the capabilities to grant, as the command line will from a lockfile. See CapabilitySet.

returnResult<PluginSet>#

As with.

The default grants do not apply: a declared plugin gets only grants, and an undeclared one does not get the legacy set unless grants holds it.

PluginSet::with_grants_shared#

fn
pluginArc<dyn Plugin>required#

A shared plugin.

grantsCapabilitySetrequired#

Exactly the capabilities to grant.

returnResult<PluginSet>#

As with. Every other way of adding a plugin ends here.

PluginSet::is_empty#

fn
returnbool#

Whether the set has no plugins. Both engines skip every plugin step for an empty set.

PluginSet::for_launch#

fn
returnPluginSet#

The set for one browser: each plugin whose per_launch returns an instance with the same name is replaced by it. Grants and strictness are kept.

Both engines call it before every launch and every attach, and use the result for every later hook of that browser, so pooled browsers launched from one set do not share a plugin’s state.

PluginSet::names#

fn
returnVec<&str>#

The plugins’ names, in the order their hooks run (see Run order).

PluginSet::check#

fn
context&LaunchContextrequired#

The browser about to start. See LaunchContext.

returnResult<()>#

As check_with.

check_with(context, &HostInfo::cdp()): the check on a host that supports every capability.

PluginSet::check_with#

fn
context&LaunchContextrequired#

The browser about to start.

host&HostInforequired#

What the host supports: HostInfo::cdp(), HostInfo::webdriver(family) or HostInfo::embedded(). See HostInfo.

returnResult<()>#

Ok(()), or the first error found. Nothing has started either way.

The checks, in this order:

  1. The run order resolves: every requires and dependencies name is in the set (MissingDependency), no plugin conflicts with another that is present (Conflict), and the edges have no cycle (Cycle).
  2. Then, for each plugin in run order:
    1. a strict set refuses it when it declares no metadata (Undeclared);
    2. its requirements and packages (Requirement, with one of these reasons): it needs a browser with a window, not a headless one (HEADFUL), it only works with a browser the program starts, not one it attaches to (LAUNCH_ONLY), it needs a Chromium-based browser (CHROMIUM_ONLY), one of its packages says neither `only_on` nor `everywhere` ;
    3. each capability in its metadata’s capabilities: the host supports it (Unsupported), and the set granted it (Capability, it is required but not granted). Capabilities in optional are never checked.

The engines call it before before_launch and again after it; an attach is checked once. The WebDriver engine passes HostInfo::webdriver(family), except that a set holding an undeclared plugin is checked as for Chromium; see Limits.

PluginSet::audit#

fn
returnVec<AuditRow>#

One row for every capability each plugin requires or optionally uses, plugin by plugin in run order, each plugin’s capabilities sorted and without repeats.

granted says whether the plugin’s grants cover the capability, and enforcement is the capability’s enforcement for a native plugin. An undeclared plugin’s rows are the legacy set, with category: None.

PluginSet::before_launch#

fn async
launch&mut LaunchSettingsrequired#

The settings the host filled in. Each plugin sees the changes of the ones before it.

returnResult<()>#

The first hook error as PluginError::Hook, or the first rule broken as PluginError::Capability or PluginError::Sealed. Later plugins do not run.

Lets every plugin change the start-up settings, in run order, and checks each plugin’s change right after its hook:

ChangeNeedsRefused with
An entry removed from args, disable_features, enable_features, host_resolver_rules or extensionsnever allowedlist settings only grow; it removed an entry
New argslaunch.argsit changed a setting without the capability
A new arg in REFUSED_SWITCHES, or a --disable-features=/--enable-features= arg naming a refused featureraw:switchesthe switch `--NAME` is refused for every plugin, or the feature `NAME` may not be changed by a plugin
New disable_features or enable_featureslaunch.args; a refused feature needs raw:switches toothat feature may not be changed by a plugin
host_resolver_rules, webrtc_policy or disable_quic changedlaunch.networkit changed a setting without the capability
A key removed from prefsnever allowedit removed a preference another plugin set
prefs changedlaunch.prefsit changed a setting without the capability
extensions changedlaunch.extensionsas above
headless changedlaunch.headlessas above
proxy changedlaunch.proxyas above
The profile changednever allowedthe profile is read-only for plugins
A sealed proxy, webrtc_policy or headless set to another valuenever allowedPluginError::Sealed

A field is sealed by the first plugin that changes it while its metadata holds the matching seal (Seals::PROXY, Seals::WEBRTC, Seals::HEADLESS); a later plugin may set the same value again, not another one. See Seals.

PluginSet::on_browser#

fn async
browser&dyn BrowserHandlerequired#

The running browser.

returnResult<()>#

The first hook error, as PluginError::Hook.

Tells every plugin, in run order, that the browser runs.

PluginSet::on_page_created#

fn async
page&dyn PageHandlerequired#

The new tab.

returnResult<()>#

The first error, as PluginError::Hook with the hook packages or on_page_created.

Plugin by plugin, in run order: adds the plugin’s packages with page.add_init_script(&package.init_script()), then calls its on_page_created. A package that says neither only_on nor everywhere is skipped here; the check has already refused it.

PluginSet::on_close#

fn async
returnVec<PluginError>#

Every failure, each as PluginError::Hook with the hook on_close; empty when every plugin closed cleanly.

Tells every plugin, in run order, that the browser is about to close. Every plugin runs even when one fails; the caller logs the failures.

AuditRow#

struct non_exhaustive seleniumbase_rs_plugin::AuditRow

One row of PluginSet::audit.

pluginString#

The plugin’s name.

categoryOption<Category>#

Its category; None for a plugin that declares no metadata.

capabilityCapability#

The capability, from the plugin’s capabilities or optional.

riskRisk#

capability.risk(): Low, Medium, High or Critical.

grantedbool#

Whether the plugin’s grants cover it.

enforcementEnforcement#

capability.enforcement(false): whether the host enforces it for a native plugin, or the plugin only declares it.

Run order#

Every method that runs hooks, and names and audit, goes through the plugins in one order, resolved from:

  1. The phase of each plugin: Last for a plugin with Requirements::RUN_LAST; otherwise its metadata’s phase; otherwise its category’s default phase; otherwise Normal. Phases run in the order Prepare, Normal, Enforce, Observe, Last (Phase).
  2. The edges: each name in requires or dependencies runs before the plugin (and must be present); each present plugin named in after runs before it; each present plugin named in before runs after it. An after or before naming an absent plugin is ignored. Edges win over phases: a Prepare plugin that runs after a Normal one comes after it.
  3. The insertion order, among plugins that are ready at the same time and share a phase.

The resolver is Kahn’s algorithm, always taking the ready plugin with the lowest phase, then the lowest insertion index. So a set of plugins that declare nothing runs in the order they were added, with the RUN_LAST ones at the end. When the order cannot be resolved (a missing requires, a conflict or a cycle), names and the hook runners fall back to insertion order with the RUN_LAST plugins at the end; check reports the error.