A test plugin runs code around a test: when it starts, when it fails (with the browser still open, so it can take evidence), and when it finishes. The ones that ship with the crate save a screenshot and the page source on failure and write a report. They are the counterpart of Python SeleniumBase’s pytest plugins.
The hooks of a test plugin
What you will learn
- Attach the bundled plugins to a test run
- Use the same plugins with the Pure CDP engine
- Write your own plugin
- What happens when a plugin itself fails
Attaching plugins to a test#
Build a Plugins set and run the test through it. It works like
run_browser_test, and returns the same result:
Reuse one Plugins value for every test in a run. A ReportPlugin keeps the
results it has seen and rewrites its file after each test, so the report is
valid even if the run stops part-way.
The bundled plugins#
| Plugin | When | What it does |
|---|---|---|
ScreenshotOnFailurePlugin | a test fails | Saves a PNG named after the test and the time. |
PageSourceOnFailurePlugin | a test fails | Saves the page’s HTML the same way. |
ReportPlugin::json / ::html | a test finishes | Rewrites a JSON or HTML report of all tests so far. |
ResultStorePlugin (turso feature) | a test finishes | Records the test in a ResultStore, for trends and sbrs report. |
Details worth knowing:
- Files are never overwritten: a second failure of the same test in the same second gets a numbered name.
- A test name is turned into letters, digits,
-and_before it is used in a file name, so a test called../../etc/passwdcannot write outside the directory you chose. - If the browser cannot take the screenshot (it has crashed, say), no file is
written. An earlier version wrote a text note into a
.pngfile; a file that only pretends to be a screenshot is worse than none.
With the Pure CDP engine#
Evidence comes from anything that implements PageEvidence. It is implemented
for BaseCase and for sb_cdp::Page, so the same plugins work with either.
Plugins::run_cdp_test is the CDP twin of run_browser_test: it launches the
browser, runs the test on its first tab (an async closure over &Page), shows
the plugins the tab on failure and always closes the browser:
Outside those runners, call the hooks yourself:
Writing your own#
Implement TestPlugin. Every hook is optional and returns a Result:
When a plugin fails#
A plugin can never change how a test turns out. If a hook returns an error, it is logged as a warning (with the plugin, hook and test name as fields) and the remaining plugins still run. The test’s own result, combined with any error from closing the browser, is what you get back.
Uploading what a plugin saved#
S3LoggingPlugin, AzureLoggingPlugin and GcpLoggingPlugin are uploaders,
not hooks: call their upload_file after a test on the files the failure
plugins wrote. See Cloud Integrations.
Migrating from the old plugin API#
Earlier releases had a SeleniumBasePlugin trait with before_command and
after_command, a PluginManager, and a DbReportingPlugin. Nothing ever
called the manager, so none of their hooks ran. They are removed. Use
TestPlugin and Plugins; ReportPlugin replaces DbReportingPlugin (the
same JSON row format, one row per test instead of one per command), and
ResultStorePlugin covers the database case.
There is no per-command hook any more: the per-test hooks are the ones with a
natural place to run.
What has and has not been verified#
The plugins, the dispatch order, failure isolation, the file naming and the
reports are covered by tests that need no browser, and the screenshot and
page-source plugins are tested through the Pure CDP mock. Plugins::run_browser_test
(the BaseCase path) has not been run against a real WebDriver on the machine
this was written on.