From 06718e85e63ea79470fea49311a9e6e3d9d86007 Mon Sep 17 00:00:00 2001 From: Craig Nishina Date: Sat, 29 Jul 2017 15:21:54 -0700 Subject: [PATCH] fix(local): allow local driver provider to use gecko driver from config - Add gecko driver as configuration option to be used in the local driver provider. - Nit fixes to use string[] over Array in the configParser.ts - Add functionality to addDefaultBinaryLocs_ to use the geckoDriver value set in the config or to check locally in the webdriver-manager/selenium folder closes #4408 and closes #4411. --- lib/config.ts | 14 ++++++++++---- lib/configParser.ts | 28 ++++++++++++++-------------- lib/driverProviders/local.ts | 31 +++++++++++++++++++++++++++++++ 3 files changed, 55 insertions(+), 18 deletions(-) diff --git a/lib/config.ts b/lib/config.ts index d7e51eb6d..eb0be09b9 100644 --- a/lib/config.ts +++ b/lib/config.ts @@ -66,16 +66,22 @@ export interface Config { jvmArgs?: string[]; }; /** - * ChromeDriver location is used to help find the chromedriver binary. - * This will be passed to the Selenium jar as the system property - * webdriver.chrome.driver. If null, Selenium will attempt to find - * ChromeDriver using PATH. + * ChromeDriver location is used to help find the chromedriver binary. This will be passed to the + * Selenium jar as the system property webdriver.chrome.driver. If the value is not set when + * launching locally, it will use the default values downloaded from webdriver-manager. * * example: * chromeDriver: './node_modules/webdriver-manager/selenium/chromedriver_2.20' */ chromeDriver?: string; + /** + * geckoDriver location is used to help find the gecko binary. This will be passed to the Selenium + * jar as the system property webdriver.gecko.driver. If the value is not set when launching + * locally, it will use the default values downloaded from webdriver-manager. + */ + geckoDriver?: string; + // ---- 2. To connect to a Selenium Server which is already running ---------- /** diff --git a/lib/configParser.ts b/lib/configParser.ts index 51715ba30..1c570ba99 100644 --- a/lib/configParser.ts +++ b/lib/configParser.ts @@ -55,9 +55,9 @@ export class ConfigParser { * @return {Array} The resolved file paths. */ public static resolveFilePatterns( - patterns: Array|string, opt_omitWarnings?: boolean, - opt_relativeTo?: string): Array { - let resolvedFiles: Array = []; + patterns: string[]|string, opt_omitWarnings?: boolean, + opt_relativeTo?: string): string[] { + let resolvedFiles: string[] = []; let cwd = opt_relativeTo || process.cwd(); patterns = (typeof patterns === 'string') ? [patterns] : patterns; @@ -82,8 +82,8 @@ export class ConfigParser { * * @return {Array} An array of globs locating the spec files */ - static getSpecs(config: Config): Array { - let specs: Array = []; + static getSpecs(config: Config): string[] { + let specs: string[] = []; if (config.suite) { config.suite.split(',').forEach((suite) => { let suiteList = config.suites ? config.suites[suite] : null; @@ -115,12 +115,12 @@ export class ConfigParser { private addConfig_(additionalConfig: any, relativeTo: string): void { // All filepaths should be kept relative to the current config location. // This will not affect absolute paths. - ['seleniumServerJar', 'chromeDriver', 'onPrepare', 'firefoxPath', 'frameworkPath'].forEach( - (name) => { - if (additionalConfig[name] && typeof additionalConfig[name] === 'string') { - additionalConfig[name] = path.resolve(relativeTo, additionalConfig[name]); - } - }); + ['seleniumServerJar', 'chromeDriver', 'firefoxPath', 'frameworkPath', + 'geckoDriver', 'onPrepare'].forEach((name: string) => { + if (additionalConfig[name] && typeof additionalConfig[name] === 'string') { + additionalConfig[name] = path.resolve(relativeTo, additionalConfig[name]); + } + }); merge_(this.config_, additionalConfig); } @@ -206,10 +206,10 @@ let makeArray = function(item: any): any { * Adds to an array all the elements in another array without adding any * duplicates * - * @param {Array} dest The array to add to - * @param {Array} src The array to copy from + * @param {string[]} dest The array to add to + * @param {string[]} src The array to copy from */ -let union = function(dest: Array, src: Array): void { +let union = function(dest: string[], src: string[]): void { let elems: any = {}; for (let key in dest) { elems[dest[key]] = true; diff --git a/lib/driverProviders/local.ts b/lib/driverProviders/local.ts index 9c9396ea9..91b0a175f 100644 --- a/lib/driverProviders/local.ts +++ b/lib/driverProviders/local.ts @@ -86,6 +86,37 @@ export class Local extends DriverProvider { } } } + + if (this.config_.capabilities.browserName === 'firefox') { + if (!this.config_.geckoDriver) { + logger.debug( + 'Attempting to find the gecko driver binary in the default ' + + 'location used by webdriver-manager'); + + try { + let updateJson = path.resolve(SeleniumConfig.getSeleniumDir(), 'update-config.json'); + let updateConfig = JSON.parse(fs.readFileSync(updateJson).toString()); + this.config_.geckoDriver = updateConfig.gecko.last; + } catch (err) { + throw new BrowserError( + logger, + 'No update-config.json found. ' + + 'Run \'webdriver-manager update\' to download binaries.'); + } + } + + // Check if file exists, if not try .exe or fail accordingly + if (!fs.existsSync(this.config_.geckoDriver)) { + if (fs.existsSync(this.config_.geckoDriver + '.exe')) { + this.config_.geckoDriver += '.exe'; + } else { + throw new BrowserError( + logger, + 'Could not find gecko driver at ' + this.config_.geckoDriver + + '. Run \'webdriver-manager update\' to download binaries.'); + } + } + } } /**