| // Licensed to the Software Freedom Conservancy (SFC) under one |
| // or more contributor license agreements. See the NOTICE file |
| // distributed with this work for additional information |
| // regarding copyright ownership. The SFC licenses this file |
| // to you under the Apache License, Version 2.0 (the |
| // "License"); you may not use this file except in compliance |
| // with the License. You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, |
| // software distributed under the License is distributed on an |
| // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| // KIND, either express or implied. See the License for the |
| // specific language governing permissions and limitations |
| // under the License. |
| |
| /** |
| * This implementation is still in beta, and may change. |
| * |
| * Wrapper for getting information from the Selenium Manager binaries |
| */ |
| |
| const { platform } = require('process') |
| const path = require('path') |
| const fs = require('fs') |
| const spawnSync = require('child_process').spawnSync |
| const { Capability } = require('../lib/capabilities') |
| const logging = require('../lib/logging') |
| |
| const log_ = logging.getLogger(logging.Type.DRIVER) |
| let debugMessagePrinted = false |
| |
| /** |
| * Determines the path of the correct Selenium Manager binary |
| * @returns {string} |
| */ |
| function getBinary () { |
| const directory = { |
| darwin: 'macos', |
| win32: 'windows', |
| cygwin: 'windows', |
| linux: 'linux', |
| }[platform] |
| |
| const file = |
| directory === 'windows' ? 'selenium-manager.exe' : 'selenium-manager' |
| |
| let seleniumManagerBasePath = path.join(__dirname, '..', '/bin') |
| |
| const filePath = process.env.SE_MANAGER_PATH || path.join( |
| seleniumManagerBasePath, directory, file) |
| |
| if (!fs.existsSync(filePath)) { |
| throw new Error(`Unable to obtain Selenium Manager at ${filePath}`) |
| } |
| |
| if (!debugMessagePrinted) { |
| log_.debug(`Selenium Manager binary found at ${filePath}`) |
| debugMessagePrinted = true // Set the flag to true after printing the debug message |
| } |
| |
| return filePath |
| } |
| |
| /** |
| * Determines the path of the correct driver |
| * @param {Capabilities} options browser options to fetch the driver |
| * @returns {{browserPath: string, driverPath: string}} path of the driver and |
| * browser location |
| */ |
| |
| function driverLocation (options) { |
| let args = ['--browser', options.getBrowserName(), '--language-binding', |
| 'javascript', '--output', 'json'] |
| |
| if (options.getBrowserVersion() && options.getBrowserVersion() !== '') { |
| args.push('--browser-version', options.getBrowserVersion()) |
| } |
| |
| const vendorOptions = |
| options.get('goog:chromeOptions') || |
| options.get('ms:edgeOptions') || |
| options.get('moz:firefoxOptions') |
| if (vendorOptions && vendorOptions.binary && vendorOptions.binary !== '') { |
| args.push('--browser-path', path.resolve(vendorOptions.binary)) |
| } |
| |
| const proxyOptions = options.getProxy() |
| |
| // Check if proxyOptions exists and has properties |
| if (proxyOptions && Object.keys(proxyOptions).length > 0) { |
| const httpProxy = proxyOptions['httpProxy'] |
| const sslProxy = proxyOptions['sslProxy'] |
| |
| if (httpProxy !== undefined) { |
| args.push('--proxy', httpProxy) |
| } else if (sslProxy !== undefined) { |
| args.push('--proxy', sslProxy) |
| } |
| } |
| |
| const smBinary = getBinary() |
| const spawnResult = spawnSync(smBinary, args) |
| let output |
| if (spawnResult.status) { |
| let errorMessage |
| if (spawnResult.stderr.toString()) { |
| errorMessage = spawnResult.stderr.toString() |
| } |
| if (spawnResult.stdout.toString()) { |
| try { |
| output = JSON.parse(spawnResult.stdout.toString()) |
| logOutput(output) |
| errorMessage = output.result.message |
| } catch (e) { |
| errorMessage = e.toString() |
| } |
| } |
| throw new Error( |
| `Error executing command for ${smBinary} with ${args}: ${errorMessage}` |
| ) |
| } |
| try { |
| output = JSON.parse(spawnResult.stdout.toString()) |
| } catch (e) { |
| throw new Error( |
| `Error executing command for ${smBinary} with ${args}: ${e.toString()}` |
| ) |
| } |
| |
| // Once driverPath is available, delete browserVersion from payload |
| if (output.result.driver_path) { |
| options.delete(Capability.BROWSER_VERSION) |
| } |
| |
| logOutput(output) |
| return { |
| driverPath: output.result.driver_path, |
| browserPath: output.result.browser_path, |
| } |
| } |
| |
| function logOutput (output) { |
| for (const key in output.logs) { |
| if (output.logs[key].level === 'WARN') { |
| log_.warning(`${output.logs[key].message}`) |
| } |
| if (['DEBUG', 'INFO'].includes(output.logs[key].level)) { |
| log_.debug(`${output.logs[key].message}`) |
| } |
| } |
| } |
| |
| // PUBLIC API |
| module.exports = { driverLocation } |