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.
| Method | Does |
|---|---|
new, strict | An empty set; a strict one refuses undeclared plugins |
with, with_shared | Add a plugin with the default grants |
with_trusted | Add a plugin with the default grants and named Critical ones |
with_grants, with_grants_shared | Add a plugin with exactly these grants |
is_empty, names | Read the set |
for_launch | The set for one browser, with fresh per-launch instances |
check, check_with | Check every plugin before anything starts |
audit | Every declared capability with its risk and grant |
before_launch, on_browser, on_page_created, on_close | Run a hook of every plugin, in order |
PluginSet::new#
fnAn empty set, the same as PluginSet::default(). It runs plugins that declare
no metadata.
PluginSet::strict#
fnAn 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#
fnThe plugin to add. It is moved into an Arc.
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 plugin | Gets |
|---|---|
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#
fnA plugin shared with other sets, such as one a Registry built.
As with, with the same default grants.
PluginSet::with_trusted#
fnThe plugin to add.
Capabilities to grant besides the default grants. They may be Critical.
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#
fnThe plugin to add.
Exactly the capabilities to grant, as the command line will from a lockfile. See CapabilitySet.
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#
fnA shared plugin.
Exactly the capabilities to grant.
As with. Every other way of adding a plugin ends here.
PluginSet::is_empty#
fnWhether the set has no plugins. Both engines skip every plugin step for an empty set.
PluginSet::for_launch#
fnThe 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#
fnPluginSet::check#
fnThe browser about to start. See LaunchContext.
As check_with.
check_with(context, &HostInfo::cdp()): the check on a host that supports
every capability.
PluginSet::check_with#
fnThe browser about to start.
Ok(()), or the first error found. Nothing has started either way.
The checks, in this order:
- The run order resolves: every
requiresanddependenciesname is in the set (MissingDependency), no plugin conflicts with another that is present (Conflict), and the edges have no cycle (Cycle). - Then, for each plugin in run order:
- a strict set refuses it when it declares no metadata (
Undeclared); - 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`; - 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 inoptionalare never checked.
- a strict set refuses it when it declares no metadata (
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#
fnOne 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 asyncThe settings the host filled in. Each plugin sees the changes of the ones before it.
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:
| Change | Needs | Refused with |
|---|---|---|
An entry removed from args, disable_features, enable_features, host_resolver_rules or extensions | never allowed | list settings only grow; it removed an entry |
New args | launch.args | it changed a setting without the capability |
A new arg in REFUSED_SWITCHES, or a --disable-features=/--enable-features= arg naming a refused feature | raw:switches | the switch `--NAME` is refused for every plugin, or the feature `NAME` may not be changed by a plugin |
New disable_features or enable_features | launch.args; a refused feature needs raw:switches too | that feature may not be changed by a plugin |
host_resolver_rules, webrtc_policy or disable_quic changed | launch.network | it changed a setting without the capability |
A key removed from prefs | never allowed | it removed a preference another plugin set |
prefs changed | launch.prefs | it changed a setting without the capability |
extensions changed | launch.extensions | as above |
headless changed | launch.headless | as above |
proxy changed | launch.proxy | as above |
| The profile changed | never allowed | the profile is read-only for plugins |
A sealed proxy, webrtc_policy or headless set to another value | never allowed | PluginError::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 asyncThe running browser.
The first hook error, as PluginError::Hook.
Tells every plugin, in run order, that the browser runs.
PluginSet::on_page_created#
fn asyncThe new tab.
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 asyncEvery 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.
The plugin’s name.
Its category; None for a plugin that declares no metadata.
The capability, from the plugin’s capabilities or optional.
capability.risk(): Low, Medium, High or Critical.
Whether the plugin’s grants cover it.
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:
- The phase of each plugin:
Lastfor a plugin withRequirements::RUN_LAST; otherwise its metadata’sphase; otherwise its category’s default phase; otherwiseNormal. Phases run in the orderPrepare,Normal,Enforce,Observe,Last(Phase). - The edges: each name in
requiresordependenciesruns before the plugin (and must be present); each present plugin named inafterruns before it; each present plugin named inbeforeruns after it. Anafterorbeforenaming an absent plugin is ignored. Edges win over phases: aPrepareplugin that runsafteraNormalone comes after it. - 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.