From a07d1fdf932cd41fc0b7484024b5ede6579dc08e Mon Sep 17 00:00:00 2001 From: Diego Molina Date: Tue, 25 Jul 2023 17:53:42 +0200 Subject: [PATCH] [javascript] Add browser output from Selenium Manager to options (#12411) * [javascript] Add browser output from Selenium Manager to options * [javascript] Seems Chrome PDF tests do not need to be using headless anymore --- javascript/node/selenium-webdriver/chrome.js | 8 ++--- .../node/selenium-webdriver/chromium.js | 21 ++++++++--- .../selenium-webdriver/common/driverFinder.js | 3 +- .../common/seleniumManager.js | 9 +++-- javascript/node/selenium-webdriver/edge.js | 6 ++-- javascript/node/selenium-webdriver/firefox.js | 25 ++++++++++--- javascript/node/selenium-webdriver/ie.js | 2 +- javascript/node/selenium-webdriver/safari.js | 6 +++- .../test/chrome/service_test.js | 2 +- .../test/edge/service_test.js | 2 +- .../selenium-webdriver/test/print_pdf_test.js | 35 +------------------ .../node/selenium-webdriver/testing/index.js | 11 +++--- 12 files changed, 66 insertions(+), 64 deletions(-) diff --git a/javascript/node/selenium-webdriver/chrome.js b/javascript/node/selenium-webdriver/chrome.js index 6934c33dde28b..77e14cf6eb1e4 100644 --- a/javascript/node/selenium-webdriver/chrome.js +++ b/javascript/node/selenium-webdriver/chrome.js @@ -130,6 +130,7 @@ const io = require('./io') const { Browser } = require('./lib/capabilities') const chromium = require('./chromium') +const CHROME_CAPABILITY_KEY = 'goog:chromeOptions' /** @type {remote.DriverService} */ @@ -220,7 +221,7 @@ class Driver extends chromium.Driver { static createSession(opt_config, opt_serviceExecutor) { let caps = opt_config || new Options() return /** @type {!Driver} */ ( - super.createSession(caps, opt_serviceExecutor) + super.createSession(caps, opt_serviceExecutor, 'goog', CHROME_CAPABILITY_KEY) ) } @@ -233,13 +234,12 @@ class Driver extends chromium.Driver { } } -Options.prototype.CAPABILITY_KEY = 'goog:chromeOptions' +Options.prototype.CAPABILITY_KEY = CHROME_CAPABILITY_KEY Options.prototype.BROWSER_NAME_VALUE = Browser.CHROME -Driver.prototype.VENDOR_COMMAND_PREFIX = 'goog' // PUBLIC API module.exports = { - Driver: Driver, + Driver, Options, ServiceBuilder, } diff --git a/javascript/node/selenium-webdriver/chromium.js b/javascript/node/selenium-webdriver/chromium.js index a1b8123328141..d9aa404e31fb0 100644 --- a/javascript/node/selenium-webdriver/chromium.js +++ b/javascript/node/selenium-webdriver/chromium.js @@ -669,27 +669,38 @@ class Driver extends webdriver.WebDriver { /** * Creates a new session with the WebDriver server. * - * @param {(Capabilities|Options)=} opt_config The configuration options. + * @param {(Capabilities|Options)=} caps The configuration options. * @param {(remote.DriverService|http.Executor)=} opt_serviceExecutor Either * a DriverService to use for the remote end, or a preconfigured executor * for an externally managed endpoint. If neither is provided, the * {@linkplain ##getDefaultService default service} will be used by * default. + * @param vendorPrefix Either 'goog' or 'ms' + * @param vendorCapabilityKey Either 'goog:chromeOptions' or 'ms:edgeOptions' * @return {!Driver} A new driver instance. */ - static createSession(caps, opt_serviceExecutor) { + static createSession(caps, opt_serviceExecutor, + vendorPrefix = '', vendorCapabilityKey = '') { let executor let onQuit if (opt_serviceExecutor instanceof http.Executor) { executor = opt_serviceExecutor - configureExecutor(executor, this.VENDOR_COMMAND_PREFIX) + configureExecutor(executor, vendorPrefix) } else { let service = opt_serviceExecutor || this.getDefaultService() if (!service.getExecutable()) { - service.setExecutable(getPath(caps)) + const {driverPath, browserPath} = getPath(caps) + service.setExecutable(driverPath) + const vendorOptions = caps.get(vendorCapabilityKey) + if (vendorOptions) { + vendorOptions['binary'] = browserPath + caps.set(vendorCapabilityKey, vendorOptions) + } else { + caps.set(vendorCapabilityKey, {binary: browserPath}) + } } onQuit = () => service.kill() - executor = createExecutor(service.start(), this.VENDOR_COMMAND_PREFIX) + executor = createExecutor(service.start(), vendorPrefix) } // W3C spec requires noProxy value to be an array of strings, but Chromium diff --git a/javascript/node/selenium-webdriver/common/driverFinder.js b/javascript/node/selenium-webdriver/common/driverFinder.js index da0e7de5413da..fcb0c675909dc 100644 --- a/javascript/node/selenium-webdriver/common/driverFinder.js +++ b/javascript/node/selenium-webdriver/common/driverFinder.js @@ -25,7 +25,8 @@ const { driverLocation } = require('./seleniumManager') /** * Determines the path of the correct Selenium Manager binary - * @returns {string} + * @returns {{browserPath: string, driverPath: string}} path of the driver + * and browser location */ function getPath(capabilities) { try { diff --git a/javascript/node/selenium-webdriver/common/seleniumManager.js b/javascript/node/selenium-webdriver/common/seleniumManager.js index 5340401122373..d807a36789fab 100644 --- a/javascript/node/selenium-webdriver/common/seleniumManager.js +++ b/javascript/node/selenium-webdriver/common/seleniumManager.js @@ -62,7 +62,8 @@ function getBinary() { /** * Determines the path of the correct driver * @param {Capabilities} options browser options to fetch the driver - * @returns {string} path of the driver location + * @returns {{browserPath: string, driverPath: string}} path of the driver and + * browser location */ function driverLocation(options) { @@ -126,8 +127,10 @@ function driverLocation(options) { } logOutput(output) - - return output.result.message + return { + driverPath: output.result.driver_path, + browserPath: output.result.browser_path, + } } function logOutput (output) { diff --git a/javascript/node/selenium-webdriver/edge.js b/javascript/node/selenium-webdriver/edge.js index e0e0655f324dd..03dbbeddef00f 100644 --- a/javascript/node/selenium-webdriver/edge.js +++ b/javascript/node/selenium-webdriver/edge.js @@ -79,6 +79,7 @@ const { Browser } = require('./lib/capabilities') const chromium = require('./chromium') +const EDGE_CAPABILITY_KEY = 'ms:edgeOptions' /** @type {remote.DriverService} */ @@ -147,7 +148,7 @@ class Driver extends chromium.Driver { static createSession(opt_config, opt_serviceExecutor) { let caps = opt_config || new Options() return /** @type {!Driver} */ ( - super.createSession(caps, opt_serviceExecutor) + super.createSession(caps, opt_serviceExecutor, 'ms', EDGE_CAPABILITY_KEY) ) } @@ -168,8 +169,7 @@ class Driver extends chromium.Driver { } Options.prototype.BROWSER_NAME_VALUE = Browser.EDGE -Options.prototype.CAPABILITY_KEY = 'ms:edgeOptions' -Driver.prototype.VENDOR_CAPABILITY_PREFIX = 'ms' +Options.prototype.CAPABILITY_KEY = EDGE_CAPABILITY_KEY // PUBLIC API diff --git a/javascript/node/selenium-webdriver/firefox.js b/javascript/node/selenium-webdriver/firefox.js index 0a8ea0fba19ca..569ed515903ff 100644 --- a/javascript/node/selenium-webdriver/firefox.js +++ b/javascript/node/selenium-webdriver/firefox.js @@ -128,6 +128,7 @@ const zip = require('./io/zip') const { Browser, Capabilities } = require('./lib/capabilities') const { Zip } = require('./io/zip') const { getPath } = require('./common/driverFinder') +const FIREFOX_CAPABILITY_KEY = 'moz:firefoxOptions' /** * Thrown when there an add-on is malformed. @@ -263,10 +264,10 @@ class Options extends Capabilities { * @private */ firefoxOptions_() { - let options = this.get('moz:firefoxOptions') + let options = this.get(FIREFOX_CAPABILITY_KEY) if (!options) { options = {} - this.set('moz:firefoxOptions', options) + this.set(FIREFOX_CAPABILITY_KEY, options) } return options } @@ -580,6 +581,8 @@ class Driver extends webdriver.WebDriver { let caps = opt_config instanceof Capabilities ? opt_config : new Options(opt_config) + let firefoxBrowserPath = null + let executor let onQuit @@ -588,19 +591,33 @@ class Driver extends webdriver.WebDriver { configureExecutor(executor) } else if (opt_executor instanceof remote.DriverService) { if (!opt_executor.getExecutable()) { - opt_executor.setExecutable(getPath(opt_config)) + const {driverPath, browserPath} = getPath(caps) + opt_executor.setExecutable(driverPath) + firefoxBrowserPath = browserPath } executor = createExecutor(opt_executor.start()) onQuit = () => opt_executor.kill() } else { let service = new ServiceBuilder().build() if (!service.getExecutable()) { - service.setExecutable(getPath(opt_config)) + const {driverPath, browserPath} = getPath(caps) + service.setExecutable(driverPath) + firefoxBrowserPath = browserPath } executor = createExecutor(service.start()) onQuit = () => service.kill() } + if (firefoxBrowserPath) { + const vendorOptions = caps.get(FIREFOX_CAPABILITY_KEY) + if (vendorOptions) { + vendorOptions['binary'] = firefoxBrowserPath + caps.set(FIREFOX_CAPABILITY_KEY, vendorOptions) + } else { + caps.set(FIREFOX_CAPABILITY_KEY, {binary: firefoxBrowserPath}) + } + } + return /** @type {!Driver} */ (super.createSession(executor, caps, onQuit)) } diff --git a/javascript/node/selenium-webdriver/ie.js b/javascript/node/selenium-webdriver/ie.js index f3e4d48377a26..8cf7d4cab7180 100644 --- a/javascript/node/selenium-webdriver/ie.js +++ b/javascript/node/selenium-webdriver/ie.js @@ -455,7 +455,7 @@ class Driver extends webdriver.WebDriver { service = createServiceFromCapabilities(options) } if (!service.getExecutable()) { - service.setExecutable(getPath(options)) + service.setExecutable(getPath(options).driverPath) } let client = service.start().then((url) => new http.HttpClient(url)) diff --git a/javascript/node/selenium-webdriver/safari.js b/javascript/node/selenium-webdriver/safari.js index 4f54d1482138b..c6893ebf16b34 100644 --- a/javascript/node/selenium-webdriver/safari.js +++ b/javascript/node/selenium-webdriver/safari.js @@ -25,6 +25,7 @@ const http = require('./http') const remote = require('./remote') const webdriver = require('./lib/webdriver') const { Browser, Capabilities } = require('./lib/capabilities') +const { getPath } = require('./common/driverFinder') /** * Creates {@link selenium-webdriver/remote.DriverService} instances that manage @@ -43,7 +44,7 @@ class ServiceBuilder extends remote.DriverService.Builder { } } -const OPTIONS_CAPABILITY_KEY = 'safari.options' +const OPTIONS_CAPABILITY_KEY = 'safari:options' const TECHNOLOGY_PREVIEW_OPTIONS_KEY = 'technologyPreview' /** @@ -122,6 +123,9 @@ class Driver extends webdriver.WebDriver { } let service = new ServiceBuilder(exe).build() + if (!service.getExecutable()) { + service.setExecutable(getPath(caps).driverPath) + } let executor = new http.Executor( service.start().then((url) => new http.HttpClient(url)) ) diff --git a/javascript/node/selenium-webdriver/test/chrome/service_test.js b/javascript/node/selenium-webdriver/test/chrome/service_test.js index 22b237a704897..95d1b16ee8a52 100644 --- a/javascript/node/selenium-webdriver/test/chrome/service_test.js +++ b/javascript/node/selenium-webdriver/test/chrome/service_test.js @@ -35,7 +35,7 @@ test.suite( it('can be started on a custom path', function () { service = new chrome.ServiceBuilder().setPath('/foo/bar/baz').build() if (!service.getExecutable()) { - service.setExecutable(getPath(new chrome.Options())) + service.setExecutable(getPath(new chrome.Options()).driverPath) } return service.start().then(function (url) { assert.ok(url.endsWith('/foo/bar/baz'), 'unexpected url: ' + url) diff --git a/javascript/node/selenium-webdriver/test/edge/service_test.js b/javascript/node/selenium-webdriver/test/edge/service_test.js index 4330832bf0f69..08dc24bc76faf 100644 --- a/javascript/node/selenium-webdriver/test/edge/service_test.js +++ b/javascript/node/selenium-webdriver/test/edge/service_test.js @@ -35,7 +35,7 @@ test.suite( it('can start msedgedriver', async function () { service = new edge.ServiceBuilder().build() - service.setExecutable(getPath(new edge.Options())) + service.setExecutable(getPath(new edge.Options()).driverPath) let url = await service.start() assert(/127\.0\.0\.1/.test(url), `unexpected url: ${url}`) }) diff --git a/javascript/node/selenium-webdriver/test/print_pdf_test.js b/javascript/node/selenium-webdriver/test/print_pdf_test.js index 46197332704a5..25fbe78217f08 100644 --- a/javascript/node/selenium-webdriver/test/print_pdf_test.js +++ b/javascript/node/selenium-webdriver/test/print_pdf_test.js @@ -20,7 +20,6 @@ const test = require('../lib/test') const { Pages } = require('../lib/test') const { Browser } = require('../') -const chrome = require('../chrome') const assert = require('assert') let startIndex = 0 @@ -93,37 +92,5 @@ test.suite( assert.strictEqual(base64Code, pdfMagicNumber) }) }, - { browsers: [Browser.FIREFOX] } -) - -// in chrome printPdf supports in headless mode -test.suite( - function (env) { - let driver - - let options = new chrome.Options() - options.headless() - - afterEach(function () { - return driver.quit() - }) - - it('Should Print pdf with 2 pages', async function () { - driver = env.builder().setChromeOptions(options).build() - - await driver.get(Pages.printPage) - base64Code = await driver.printPage({ pageRanges: ['1-2'] }) - base64Code = base64Code.slice(startIndex, endIndex) - assert.strictEqual(base64Code, pdfMagicNumber) - }) - - it('Should Print pdf with total pages', async function () { - driver = env.builder().setChromeOptions(options).build() - await driver.get(Pages.printPage) - base64Code = await driver.printPage() - base64Code = base64Code.slice(startIndex, endIndex) - assert.strictEqual(base64Code, pdfMagicNumber) - }) - }, - { browsers: [Browser.CHROME] } + { browsers: [Browser.FIREFOX, Browser.CHROME] } ) diff --git a/javascript/node/selenium-webdriver/testing/index.js b/javascript/node/selenium-webdriver/testing/index.js index e535b2ce69970..f9b0882efbc03 100644 --- a/javascript/node/selenium-webdriver/testing/index.js +++ b/javascript/node/selenium-webdriver/testing/index.js @@ -117,13 +117,12 @@ function getBrowsersToTestFromEnv() { function getAvailableBrowsers() { info(`Searching for WebDriver executables installed on the current system...`) - getPath(safari.Options) let targets = [ - [getPath(chrome.Options), Browser.CHROME], - [getPath(edge.Options), Browser.EDGE], - [getPath(firefox.Options), Browser.FIREFOX], - [getPath(ie.Options), Browser.INTERNET_EXPLORER], - [getPath(safari.Options), Browser.SAFARI], + [getPath(chrome.Options).driverPath, Browser.CHROME], + [getPath(edge.Options).driverPath, Browser.EDGE], + [getPath(firefox.Options).driverPath, Browser.FIREFOX], + [getPath(ie.Options).driverPath, Browser.INTERNET_EXPLORER], + [getPath(safari.Options).driverPath, Browser.SAFARI], ] let availableBrowsers = []