Extending Browser
Python plugins
Add or replace keywords from Python, with access to the library's own API and to the Node side.
The Python plugin API adds keywords to Browser, or replaces existing ones, without forking the library. It is provided by PythonLibCore.
A Python-only plugin
Subclass LibraryComponent and decorate with @keyword:
Load it at import:
Two routes are shown above deliberately. self.library is the supported public
API and should be your default. Dropping to gRPC gets you at anything the Node
side can do, at the cost of coupling to internals that may change.
Several plugins can be loaded at once — plugins= takes one name, a
comma-separated list, or a real list. Arguments go after the class, separated by
semicolons: plugins=pkg.Plugin;arg1;kw=val.
Two rules that fail loudly, and one that does not:
- The class name must match the module or file name, or the import fails with
DataError. - A plugin that does not inherit
LibraryComponentfails withPluginError. - A plugin keyword whose method name matches a built-in silently replaces
it. Plugins load last — library keywords, then JavaScript extensions, then
plugins — so last wins, with no warning. The exception is the handful of
keywords declared with an explicit
@keyword(name=...), such asEvaluate JavaScript,Get BoundingBoxand the storage keywords: matching their method name creates a duplicate instead, and the suite fails with Keyword with same name defined multiple times. Give your method the same@keyword(name=...)to replace one of those. Every plugin keyword is taggedPlugin, which is how you spot one in Libdoc.
Selectors inside a plugin
The public keywords resolve the Set Selector Prefix value for you, so a
plugin that calls them needs to do nothing:
Resolve it yourself with self.resolve_selector(selector) only when you bypass
the public API — a direct gRPC call, or call_js_keyword.
For a keyword that should also honour presenter mode — highlighting the element
and pausing so a human can follow along — use presenter_mode, which resolves
the selector as well:
call_js_keyword reaches a keyword from any JavaScript module registered on the
Node side — one this plugin loaded with initialize_js_extension, or one loaded
through the library's jsextension= argument — it is not a way to call arbitrary Playwright
methods, so myBlur has to exist in that module.
Calling JavaScript from a Python plugin
Load a JS module in the constructor, then call into it:
This combination is usually the one you want: the keyword signature, type conversion and documentation are Python, and only the part that genuinely needs the page is JavaScript.