When testing WebExtensions you might want to automatically load them into Firefox and do functional testing with geckodriver.
npm install --save-dev webextensions-geckodriver
const webExtensionsGeckoDriver = require('webextensions-geckodriver');
const webExtension = await webExtensionsGeckoDriver('/absolute/path/to/manifest.json');
Loads the WebExtension as Temporary Add-on into a new Firefox instance. See API docs for more details.
manifest.json includes
"browser_action": {
"default_title": "Visit Example.com"
},
"applications": {
"gecko": {
"id": "@examplewebextension",
"strict_min_version": "57.0"
}
}
Test could look like this (using mocha
):
const path = require('path');
const assert = require('assert');
const webExtensionsGeckoDriver = require('webextensions-geckodriver');
const {webdriver} = webExtensionsGeckoDriver;
const manifestPath = path.resolve(path.join(__dirname, './path/to/manifest.json'));
describe('Example', () => {
let geckodriver;
before(async () => {
const webExtension = await webExtensionsGeckoDriver(manifestPath);
geckodriver = webExtension.geckodriver;
});
it('should have a Toolbar Button', async () => {
const button = await geckodriver.wait(webdriver.until.elementLocated(
// browser_actions automatically have applications.gecko.id as prefix
// special chars in the id are replaced with _
webdriver.By.id('_examplewebextension-browser-action')
), 1000);
assert.equal(await button.getAttribute('tooltiptext'), 'Visit Example.com');
});
after(() => {
geckodriver.quit();
});
});
Full executable example is in the example directory.
- path
<string>
, required, absolute path to themanifest.json
file - options
<object>
, optional- binary
<string>
, optional, lets you set thebinary
that is passed tofx-runner
. Possible values:firefox
,beta
,aurora
,nightly
,firefoxdeveloperedition
. Defaults to:firefox
. - autoInstall,
<boolean>
, optional, if set tofalse
the extension will not be installed, you can manually do so later by callinginstall
. Defaults totrue
. - webExt
<object>
, optional, lets you overwrite the parameters that get passed intoweb-ext.cmd.build
- fxOptions
firefox.Options
, optional, afirefox.Options
that will be passed to the webdriver
- binary
Returns a Promise that resolves with an initialized WebExtensionsGeckodriver
instance in case of success, notably with the following properties:
- geckodriver,
<object>
, a newselenium-webdriver/firefox
instance with previously loadedgeckodriver
- install,
<function>
, returns a Promise that resolves when installing is finished, accepts an options<object>
:- extensionPath,
<string>
, optional, path to something thatinstallAddon
can handle. Defaults to theweb-ext
build extensionPath. - temporary,
<boolean>
, optional, whether the WebExt should be installed temporary. Defaults totrue
.
- extensionPath,
- internalUUID,
<function>
, returns a Promise that resolves to theInternal UUID
of the installed extension - uninstall,
<function>
, returns a Promise that resolves when uninstalling is finished, accepts an optional extensions id as<string>
Return value of require('selenium-webdriver')
Return value of require('selenium-webdriver/firefox')
dist: xenial
services:
- xvfb
language: node_js
addons:
firefox: latest
node_js:
- 'lts/*'
const webExtensionsGeckoDriver = require('webextensions-geckodriver');
const {firefox} = webExtensionsGeckoDriver;
// or equivalently:
// const firefox = require('selenium-webdriver/firefox')
const fxOptions = new firefox.Options()
.headless()
.windowSize({height: 1080, width: 1920}) // If you rely on viewport size
webExtensionsGeckoDriver(manifestPath, {fxOptions})
If you're looking for a way to test WebExtensions with JSDOM then webextensions-jsdom
might be for you.
Thanks to Standard8 for the original work in example-webextension.