1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-11-29 23:58:06 +01:00
metamask-extension/test/e2e/webdriver/firefox.js
Mark Stacey 8f40cd8438
Update selenium-webdriver (#7749)
Update `selenium-webdriver` to v4.0.0-alpha.5. Despite the fact that
this version has "alpha" in the name, the maintainer of
`selenium-webdriver` has described this release as stable [1].

A few APIs were removed or changed in v4, which required changes to our
Firefox webdriver.

The port used for webdriver communication can now be specified
manually. This was required to ensure the threebox tests kept working,
because they used two different driver instances. This new version of
`selenium-webdriver` now uses the same port for each instance of the
webdriver (unlike the old version, which generated a new port for each
one), so it was necessary to manually specify the port to prevent the
same port from being used for both instances.

`chromedriver` required an update, as the version we were using was not
compatible with the new W3C WebDriver protocol. I've updated
`geckodriver` as well, just to bring it in line with the version of
Firefox we are using.

[1]: https://github.com/SeleniumHQ/selenium/issues/5617#issuecomment-373446249
2020-01-07 10:01:06 -04:00

104 lines
3.0 KiB
JavaScript

const fs = require('fs')
const os = require('os')
const path = require('path')
const { Builder, By, until } = require('selenium-webdriver')
const firefox = require('selenium-webdriver/firefox')
const { Command } = require('selenium-webdriver/lib/command')
/**
* The prefix for temporary Firefox profiles. All Firefox profiles used for e2e tests
* will be created as random directories inside this.
* @type {string}
*/
const TEMP_PROFILE_PATH_PREFIX = path.join(os.tmpdir(), 'MetaMask-Fx-Profile')
const GeckoDriverCommand = {
INSTALL_ADDON: 'install addon',
}
/**
* A wrapper around a {@code WebDriver} instance exposing Firefox-specific functionality
*/
class FirefoxDriver {
/**
* Builds a {@link FirefoxDriver} instance
* @param {{extensionPath: string}} options the options for the build
* @return {Promise<{driver: !ThenableWebDriver, extensionUrl: string, extensionId: string}>}
*/
static async build ({ extensionPath, responsive, port }) {
const templateProfile = fs.mkdtempSync(TEMP_PROFILE_PATH_PREFIX)
const options = new firefox.Options()
.setProfile(templateProfile)
const builder = new Builder()
.forBrowser('firefox')
.setFirefoxOptions(options)
if (port) {
const service = new firefox.ServiceBuilder()
.setPort(port)
builder.setFirefoxService(service)
}
const driver = builder.build()
const fxDriver = new FirefoxDriver(driver)
await fxDriver.init()
const extensionId = await fxDriver.installExtension(extensionPath)
const internalExtensionId = await fxDriver.getInternalId()
if (responsive) {
await driver.manage().window().setRect({ width: 320, height: 600 })
}
return {
driver,
extensionId,
extensionUrl: `moz-extension://${internalExtensionId}/home.html`,
}
}
/**
* @constructor
* @param {!ThenableWebDriver} driver a {@code WebDriver} instance
*/
constructor (driver) {
this._driver = driver
}
/**
* Initializes the driver
* @return {Promise<void>}
*/
async init () {
await this._driver.getExecutor()
.defineCommand(
GeckoDriverCommand.INSTALL_ADDON,
'POST',
'/session/:sessionId/moz/addon/install',
)
}
/**
* Installs the extension at the given path
* @param {string} addonPath the path to the unpacked extension or XPI
* @return {Promise<string>} the extension ID
*/
async installExtension (addonPath) {
const cmd = new Command(GeckoDriverCommand.INSTALL_ADDON)
.setParameter('path', path.resolve(addonPath))
.setParameter('temporary', true)
return await this._driver.execute(cmd)
}
/**
* Returns the Internal UUID for the given extension
* @return {Promise<string>} the Internal UUID for the given extension
*/
async getInternalId () {
await this._driver.get('about:debugging#addons')
return await this._driver.wait(until.elementLocated(By.xpath('//dl/div[contains(., \'Internal UUID\')]/dd')), 1000).getText()
}
}
module.exports = FirefoxDriver