selenium-webdriver
Advanced tools
Comparing version 4.7.0 to 4.14.0
174
CHANGES.md
@@ -0,1 +1,162 @@ | ||
## 4.14.0 | ||
#### :nail_care: Polish | ||
* Adding CDP v118 and removing v115 | ||
## 4.13.0 | ||
#### :nail_care: Polish | ||
* Adding CDP v117 and removing v114 | ||
* Added file location to exception message for Selenium Manager | ||
#### :rocket: New Feature | ||
* Allow users to set Selenium Manager path by environment variable (#12752) | ||
## 4.12.0 | ||
#### :bug: Bug fix | ||
* Adding browsers when they are present on the host (#12456) | ||
* Create absolute path for browser binary (#12479) | ||
* Fix how browsers and drivers are discovered (#12456) | ||
#### :nail_care: Polish | ||
* Add support for Chrome 116 and remove support for Chrome 113 | ||
* Remove browserVersion from options in Selenium Manager (#12641) | ||
## 4.11.1 | ||
#### :bug: Bug fix | ||
* Update testing/index.js code snippet to fix function call (#12456) | ||
## v4.11.0 | ||
#### :nail_care: Polish | ||
* [BiDi] fix addPreloadScript failing tests (#12182) | ||
* Print debug message once for each browser when selenium manager used | ||
* Add forgotten RelativeBy in check options (#12289) | ||
* SM supports all browsers in Selenium since a while ago | ||
* Using SM to check drivers on the PATH | ||
* Display info about SM activity | ||
* Removing logic to find drivers, delegating to Selenium Manager | ||
* Removing service parameter from getPath | ||
* add support for Chrome 115 and remove support for Chrome 112 | ||
* Update webdriver-bootstrap.js (#12276) | ||
#### :rocket: New Feature | ||
* [BiDi] add Network module events (#12197) | ||
* Adding ignore process match for IE Mode across bindings (#12279) | ||
* Add browser output from Selenium Manager to options (#12411) | ||
#### :bug: Bug Fix | ||
* fix SeleniumServer.start() crashes on MacOS with nodejs selenium-webdriver (#12158) | ||
* Update by.js: Add forgotten RelativeBy in check options (#12289) | ||
## v4.10.0 | ||
#### :nail_care: Polish | ||
* Adding CDP v114 and removing v111 | ||
#### :rocket: New Feature | ||
* [Edge] Support webview2 (#11978) | ||
* [BiDi] Add Script module commands to add/remove preloaded scripts (#11847) | ||
* [BiDi] Add printPage command (#12124) | ||
* Add support for proxies with Selenium Manager | ||
## v4.9.2 | ||
#### :nail_care: Polish | ||
* Handle rejection of the driver if not found | ||
## v4.9.1 | ||
#### :nail_care: Polish | ||
* Add CDP files for v113 and remove v110 | ||
## v4.9.0 | ||
#### :nail_care: Polish | ||
* Adding CDP v112 and removing v109 | ||
#### :bug: Bug Fix | ||
* Fix: return statement in submit() (#11883) | ||
* [grid] Refining the UI configuration to allow sub paths work properly. | ||
* Replace `execSync` with `spawnSync` in `seleniumManager.js` (#11649) (#11873) | ||
#### :rocket: New Feature | ||
* [BiDi] Add Script module commands and types (#11847) | ||
* Selenium Manager get Browser Version from Options classes | ||
* Selenium Manager use binary from Browser Options | ||
## v4.8.2 | ||
#### :nail_care: Polish | ||
* Add CDP support for v111 and remove v108 | ||
* Using json output with Selenium Manager | ||
#### :bug: Bug Fix | ||
* fix: Using status from response (#11742) | ||
## v4.8.1 | ||
#### :rocket: New Feature | ||
* Add script pinning (#11584) | ||
#### :nail_care: Polish | ||
* Add CDP support for v110 and remove v107 | ||
* Updating Selenium Manager binaries for 4.8.1 release | ||
#### :bug: Bug Fix | ||
fix: iedriver download with selenium-manager #11579 | ||
## v4.8.0 | ||
#### :rocket: New Feature | ||
* Add initial BiDi Support (#11395) | ||
* Add window wrappers getSize and setSize | ||
* Add BiDi browser context commands (#11473) | ||
* Add BiDi methods to listen to js logs and any type of logs | ||
* Add BiDi filtering capability to LogInspector (#11495) | ||
* Add comment with name of large JS executions (#11038) | ||
#### :nail_care: Polish | ||
* Add CDP support for v109 and remove v106 | ||
* Deprecate setHeadless() in Chrome and Firefox (#11467) | ||
## v4.7.1 | ||
#### :nail_care: Polish | ||
* feat/deprecation message for standalone3x (#11422) | ||
#### :bug: Bug Fix | ||
* feat/fix spawn format for SeleniumServer, issue 11405 (#11412) | ||
#### Committers: 1 | ||
* Potapov Dmitriy ([@potapovDim](https://github.com/potapovDim)) | ||
## v4.7.0 | ||
@@ -20,3 +181,3 @@ | ||
* Fix typos (#11258) | ||
* Fix typos (#11258) | ||
@@ -76,3 +237,3 @@ ## v4.6.0 | ||
* Removing circular dependency Between webdriver.js and http.js | ||
* fix some typos in code and documentation | ||
* fix some typos in code and documentation | ||
* add cdp v105 remove v102 | ||
@@ -82,2 +243,3 @@ * add cdp v106 remove v103 | ||
## v4.4.0 | ||
* Add support CDP 104 and remove CDP 101 | ||
@@ -1214,1 +1376,9 @@ | ||
@@ -130,15 +130,6 @@ // Licensed to the Software Freedom Conservancy (SFC) under one | ||
const io = require('./io') | ||
const { Browser } = require('./lib/capabilities') | ||
const chromium = require('./chromium') | ||
const { driverLocation } = require('./common/seleniumManager') | ||
const CHROME_CAPABILITY_KEY = 'goog:chromeOptions' | ||
/** | ||
* Name of the ChromeDriver executable. | ||
* @type {string} | ||
* @const | ||
*/ | ||
const CHROMEDRIVER_EXE = | ||
process.platform === 'win32' ? 'chromedriver.exe' : 'chromedriver' | ||
/** @type {remote.DriverService} */ | ||
@@ -161,26 +152,3 @@ | ||
constructor(opt_exe) { | ||
let exe = opt_exe || locateSynchronously() | ||
if (!exe) { | ||
console.log( | ||
` The ChromeDriver could not be found on the current PATH, trying Selenium Manager` | ||
) | ||
try { | ||
exe = driverLocation(Browser.CHROME) | ||
} catch (err) { | ||
console.log(`Unable to obtain driver using Selenium Manager: ${err}`) | ||
} | ||
} | ||
if (!exe) { | ||
throw Error( | ||
`The ChromeDriver could not be found on the current PATH. | ||
Please download the latest version of the ChromeDriver | ||
from http://chromedriver.storage.googleapis.com/index.html | ||
and ensure it can be found on your PATH.` | ||
) | ||
} | ||
super(exe) | ||
super(opt_exe) | ||
} | ||
@@ -257,3 +225,8 @@ } | ||
return /** @type {!Driver} */ ( | ||
super.createSession(caps, opt_serviceExecutor) | ||
super.createSession( | ||
caps, | ||
opt_serviceExecutor, | ||
'goog', | ||
CHROME_CAPABILITY_KEY | ||
) | ||
) | ||
@@ -271,22 +244,10 @@ } | ||
/** | ||
* _Synchronously_ attempts to locate the chromedriver executable on the current | ||
* system. | ||
* | ||
* @return {?string} the located executable, or `null`. | ||
*/ | ||
function locateSynchronously() { | ||
return io.findInPath(CHROMEDRIVER_EXE, true) | ||
} | ||
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, | ||
locateSynchronously, | ||
} |
@@ -86,2 +86,3 @@ // Licensed to the Software Freedom Conservancy (SFC) under one | ||
const remote = require('./remote') | ||
const { getPath } = require('./common/driverFinder') | ||
@@ -314,2 +315,11 @@ /** | ||
/** | ||
* @deprecated Use {@link Options#addArguments} instead. | ||
* @example | ||
* options.addArguments('--headless=chrome'); (or) | ||
* options.addArguments('--headless'); | ||
* @example | ||
* | ||
* Recommended to use '--headless=chrome' as argument for browsers v94-108. | ||
* Recommended to use '--headless=new' as argument for browsers v109+. | ||
* | ||
* Configures the driver to start the browser in headless mode. | ||
@@ -605,2 +615,10 @@ * | ||
} | ||
/** | ||
* Enable bidi connection | ||
* @returns {!Capabilities} | ||
*/ | ||
enableBidi() { | ||
return this.set('webSocketUrl', true) | ||
} | ||
} | ||
@@ -657,3 +675,3 @@ | ||
* | ||
* @param {(Capabilities|Options)=} opt_config The configuration options. | ||
* @param {(Capabilities|Options)=} caps The configuration options. | ||
* @param {(remote.DriverService|http.Executor)=} opt_serviceExecutor Either | ||
@@ -664,5 +682,12 @@ * a DriverService to use for the remote end, or a preconfigured executor | ||
* 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 | ||
@@ -672,7 +697,18 @@ let onQuit | ||
executor = opt_serviceExecutor | ||
configureExecutor(executor, this.VENDOR_COMMAND_PREFIX) | ||
configureExecutor(executor, vendorPrefix) | ||
} else { | ||
let service = opt_serviceExecutor || this.getDefaultService() | ||
if (!service.getExecutable()) { | ||
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) | ||
} | ||
@@ -679,0 +715,0 @@ |
@@ -27,9 +27,6 @@ // Licensed to the Software Freedom Conservancy (SFC) under one | ||
const fs = require('fs') | ||
const execSync = require('child_process').execSync | ||
const spawnSync = require('child_process').spawnSync | ||
const { Capability } = require('../lib/capabilities') | ||
/** | ||
* currently supported browsers for selenium-manager | ||
* @type {string[]} | ||
*/ | ||
const Browser = ['chrome', 'firefox', 'edge'] | ||
let debugMessagePrinted = false | ||
@@ -51,8 +48,15 @@ /** | ||
const filePath = path.join(__dirname, '..', '/bin', directory, file) | ||
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`) | ||
throw new Error(`Unable to obtain Selenium Manager at ${filePath}`) | ||
} | ||
if (!debugMessagePrinted) { | ||
console.debug(`Selenium Manager binary found at ${filePath}`) | ||
debugMessagePrinted = true // Set the flag to true after printing the debug message | ||
} | ||
return filePath | ||
@@ -63,32 +67,89 @@ } | ||
* Determines the path of the correct driver | ||
* @param {Browser|string} browser name to fetch the driver | ||
* @returns {string} path of the driver location | ||
* @param {Capabilities} options browser options to fetch the driver | ||
* @returns {{browserPath: string, driverPath: string}} path of the driver and | ||
* browser location | ||
*/ | ||
function driverLocation(browser) { | ||
if (!Browser.includes(browser.toLocaleString())) { | ||
function driverLocation(options) { | ||
let args = ['--browser', options.getBrowserName(), '--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( | ||
`Unable to locate driver associated with browser name: ${browser}` | ||
`Error executing command for ${smBinary} with ${args}: ${errorMessage}` | ||
) | ||
} | ||
let args = [getBinary(), '--browser', browser] | ||
let result | ||
try { | ||
result = execSync(args.join(' ')).toString() | ||
output = JSON.parse(spawnResult.stdout.toString()) | ||
} catch (e) { | ||
throw new Error( | ||
`Error executing command with ${args}\n${e.stdout.toString()}${e.stderr.toString()}` | ||
`Error executing command for ${smBinary} with ${args}: ${e.toString()}` | ||
) | ||
} | ||
if (!result.startsWith('INFO\t')) { | ||
throw new Error(`Unsuccessful command executed: ${args}\n${result}`) | ||
// Once driverPath is available, delete browserVersion from payload | ||
if (output.result.driver_path) { | ||
options.delete(Capability.BROWSER_VERSION) | ||
} | ||
return result.replace('INFO\t', '').trim() | ||
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') { | ||
console.warn(`${output.logs[key].message}`) | ||
} | ||
if (['DEBUG', 'INFO'].includes(output.logs[key].level)) { | ||
console.debug(`${output.logs[key].message}`) | ||
} | ||
} | ||
} | ||
// PUBLIC API | ||
module.exports = { driverLocation } |
@@ -18,2 +18,3 @@ // Licensed to the Software Freedom Conservancy (SFC) under one | ||
const RESPONSE_TIMEOUT = 1000 * 30 | ||
class CDPConnection { | ||
@@ -39,4 +40,40 @@ constructor(wsConnection) { | ||
} | ||
async send(method, params) { | ||
let cdp_id = this.cmd_id++ | ||
let message = { | ||
method, | ||
id: cdp_id, | ||
} | ||
if (this.sessionId) { | ||
message['sessionId'] = this.sessionId | ||
} | ||
const mergedMessage = Object.assign({ params: params }, message) | ||
this._wsConnection.send(JSON.stringify(mergedMessage)) | ||
return new Promise((resolve, reject) => { | ||
const timeoutId = setTimeout(() => { | ||
reject(new Error(`Request with id ${cdp_id} timed out`)) | ||
handler.off('message', listener) | ||
}, RESPONSE_TIMEOUT) | ||
const listener = (data) => { | ||
try { | ||
const payload = JSON.parse(data.toString()) | ||
if (payload.id === cdp_id) { | ||
clearTimeout(timeoutId) | ||
handler.off('message', listener) | ||
resolve(payload) | ||
} | ||
} catch (err) { | ||
console.error(`Failed parse message: ${err.message}`) | ||
} | ||
} | ||
const handler = this._wsConnection.on('message', listener) | ||
}) | ||
} | ||
} | ||
exports.CdpConnection = CDPConnection |
65
edge.js
@@ -81,14 +81,5 @@ // Licensed to the Software Freedom Conservancy (SFC) under one | ||
const { Browser } = require('./lib/capabilities') | ||
const io = require('./io') | ||
const chromium = require('./chromium') | ||
const { driverLocation } = require('./common/seleniumManager') | ||
const EDGE_CAPABILITY_KEY = 'ms:edgeOptions' | ||
/** | ||
* Name of the EdgeDriver executable. | ||
* @type {string} | ||
* @const | ||
*/ | ||
const EDGEDRIVER_CHROMIUM_EXE = | ||
process.platform === 'win32' ? 'msedgedriver.exe' : 'msedgedriver' | ||
/** @type {remote.DriverService} */ | ||
@@ -110,26 +101,3 @@ | ||
constructor(opt_exe) { | ||
let exe = opt_exe || locateSynchronously() | ||
if (!exe) { | ||
console.log( | ||
`The WebDriver for Edge could not be found on the current PATH, trying Selenium Manager` | ||
) | ||
try { | ||
exe = driverLocation('edge') | ||
} catch (err) { | ||
console.log(`Unable to obtain driver using Selenium Manager: ${err}`) | ||
} | ||
} | ||
if (!exe) { | ||
throw Error( | ||
`The WebDriver for Edge could not be found on the current PATH. Please download the ` + | ||
`latest version of ${EDGEDRIVER_CHROMIUM_EXE} from ` + | ||
`https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/ ` + | ||
`and ensure it can be found on your PATH.` | ||
) | ||
} | ||
super(exe) | ||
super(opt_exe) | ||
this.setLoopback(true) | ||
@@ -155,2 +123,15 @@ } | ||
} | ||
/** | ||
* Changes the browser name to 'webview2' to enable | ||
* <a href="https://learn.microsoft.com/en-us/microsoft-edge/webview2/how-to/webdriver"> | ||
* test automation of WebView2 apps with Microsoft Edge WebDriver | ||
* </a> | ||
* | ||
* @param {boolean} enable flag to enable or disable the 'webview2' usage | ||
*/ | ||
useWebView(enable) { | ||
const browserName = enable ? 'webview2' : Browser.EDGE | ||
return this.setBrowserName(browserName) | ||
} | ||
} | ||
@@ -173,3 +154,3 @@ | ||
return /** @type {!Driver} */ ( | ||
super.createSession(caps, opt_serviceExecutor) | ||
super.createSession(caps, opt_serviceExecutor, 'ms', EDGE_CAPABILITY_KEY) | ||
) | ||
@@ -194,15 +175,4 @@ } | ||
/** | ||
* _Synchronously_ attempts to locate the chromedriver executable on the current | ||
* system. | ||
* | ||
* @return {?string} the located executable, or `null`. | ||
*/ | ||
function locateSynchronously() { | ||
return io.findInPath(EDGEDRIVER_CHROMIUM_EXE, true) | ||
} | ||
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 | ||
@@ -215,3 +185,2 @@ // PUBLIC API | ||
ServiceBuilder, | ||
locateSynchronously, | ||
} |
@@ -130,3 +130,4 @@ // Licensed to the Software Freedom Conservancy (SFC) under one | ||
const { Zip } = require('./io/zip') | ||
const { driverLocation } = require('./common/seleniumManager') | ||
const { getPath } = require('./common/driverFinder') | ||
const FIREFOX_CAPABILITY_KEY = 'moz:firefoxOptions' | ||
@@ -267,6 +268,6 @@ /** | ||
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) | ||
} | ||
@@ -304,2 +305,6 @@ return options | ||
/** | ||
* @deprecated Use {@link Options#addArguments} instead. | ||
* @example | ||
* options.addArguments('-headless'); | ||
* @example | ||
* Configures the geckodriver to start Firefox in headless mode. | ||
@@ -430,2 +435,10 @@ * | ||
} | ||
/** | ||
* Enable bidi connection | ||
* @returns {!Capabilities} | ||
*/ | ||
enableBidi() { | ||
return this.set('webSocketUrl', true) | ||
} | ||
} | ||
@@ -448,46 +461,3 @@ | ||
const GECKO_DRIVER_EXE = | ||
process.platform === 'win32' ? 'geckodriver.exe' : 'geckodriver' | ||
/** | ||
* _Synchronously_ attempts to locate the geckodriver executable on the current | ||
* system. | ||
* | ||
* @return {?string} the located executable, or `null`. | ||
*/ | ||
function locateSynchronously() { | ||
return io.findInPath(GECKO_DRIVER_EXE, true) | ||
} | ||
/** | ||
* @return {string} . | ||
* @throws {Error} | ||
*/ | ||
function findGeckoDriver() { | ||
let exe = locateSynchronously() | ||
if (!exe) { | ||
console.log( | ||
`The ${GECKO_DRIVER_EXE} executable could not be found on the current PATH, trying Selenium Manager` | ||
) | ||
try { | ||
exe = driverLocation(Browser.FIREFOX) | ||
} catch (err) { | ||
console.log(`Unable to obtain driver using Selenium Manager: ${err}`) | ||
} | ||
} | ||
if (!exe) { | ||
throw Error( | ||
`The ${GECKO_DRIVER_EXE} executable could not be found on the current PATH. | ||
Please download the latest version from https://github.com/mozilla/geckodriver/releases/ | ||
and ensure it can be found on your PATH.` | ||
) | ||
} | ||
return exe | ||
} | ||
/** | ||
* @param {string} file Path to the file to find, relative to the program files | ||
@@ -573,3 +543,3 @@ * root. | ||
constructor(opt_exe) { | ||
super(opt_exe || findGeckoDriver()) | ||
super(opt_exe) | ||
this.setLoopback(true) // Required. | ||
@@ -620,2 +590,4 @@ } | ||
let firefoxBrowserPath = null | ||
let executor | ||
@@ -628,2 +600,7 @@ let onQuit | ||
} else if (opt_executor instanceof remote.DriverService) { | ||
if (!opt_executor.getExecutable()) { | ||
const { driverPath, browserPath } = getPath(caps) | ||
opt_executor.setExecutable(driverPath) | ||
firefoxBrowserPath = browserPath | ||
} | ||
executor = createExecutor(opt_executor.start()) | ||
@@ -633,2 +610,7 @@ onQuit = () => opt_executor.kill() | ||
let service = new ServiceBuilder().build() | ||
if (!service.getExecutable()) { | ||
const { driverPath, browserPath } = getPath(caps) | ||
service.setExecutable(driverPath) | ||
firefoxBrowserPath = browserPath | ||
} | ||
executor = createExecutor(service.start()) | ||
@@ -638,2 +620,12 @@ 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)) | ||
@@ -849,3 +841,2 @@ } | ||
ServiceBuilder, | ||
locateSynchronously, | ||
} |
@@ -57,3 +57,4 @@ // Licensed to the Software Freedom Conservancy (SFC) under one | ||
options.path = options.pathname | ||
options.hostname = options.hostname === 'localhost' ? '127.0.0.1' : options.hostname // To support Node 17 and above. Refer https://github.com/nodejs/node/issues/40702 for details. | ||
options.hostname = | ||
options.hostname === 'localhost' ? '127.0.0.1' : options.hostname // To support Node 17 and above. Refer https://github.com/nodejs/node/issues/40702 for details. | ||
return options | ||
@@ -60,0 +61,0 @@ } |
45
ie.js
@@ -30,5 +30,3 @@ // Licensed to the Software Freedom Conservancy (SFC) under one | ||
const fs = require('fs') | ||
const http = require('./http') | ||
const io = require('./io') | ||
const portprober = require('./net/portprober') | ||
@@ -39,5 +37,4 @@ const remote = require('./remote') | ||
const error = require('./lib/error') | ||
const { driverLocation } = require('./common/seleniumManager') | ||
const { getPath } = require('./common/driverFinder') | ||
const IEDRIVER_EXE = 'IEDriverServer.exe' | ||
const OPTIONS_CAPABILITY_KEY = 'se:ieOptions' | ||
@@ -88,2 +85,3 @@ const SCROLL_BEHAVIOUR = { | ||
EDGE_EXECUTABLE_PATH: 'ie.edgepath', | ||
IGNORE_PROCESS_MATCH: 'ie.ignoreprocessmatch', | ||
} | ||
@@ -385,12 +383,2 @@ | ||
/** | ||
* _Synchronously_ attempts to locate the IE driver executable on the current | ||
* system. | ||
* | ||
* @return {?string} the located executable, or `null`. | ||
*/ | ||
function locateSynchronously() { | ||
return process.platform === 'win32' ? io.findInPath(IEDRIVER_EXE, true) : null | ||
} | ||
function createServiceFromCapabilities(capabilities) { | ||
@@ -406,24 +394,3 @@ if (process.platform !== 'win32') { | ||
let exe = locateSynchronously() | ||
if (!exe) { | ||
console.log( | ||
`The ${IEDRIVER_EXE} executable could not be found on the current PATH, trying Selenium Manager` | ||
) | ||
try { | ||
exe = driverLocation(Browser.INTERNET_EXPLORER) | ||
} catch (err) { | ||
console.log(`Unable to obtain driver using Selenium Manager: ${err}`) | ||
} | ||
} | ||
if (!exe || !fs.existsSync(exe)) { | ||
throw Error( | ||
`${IEDRIVER_EXE} could not be found on the current PATH. Please ` + | ||
`download the latest version of ${IEDRIVER_EXE} from ` + | ||
'https://www.selenium.dev/downloads/ and ' + | ||
'ensure it can be found on your system PATH.' | ||
) | ||
} | ||
let exe = null // Let Selenium Manager find it | ||
var args = [] | ||
@@ -468,3 +435,3 @@ if (capabilities.has(Key.HOST)) { | ||
constructor(opt_exe) { | ||
super(opt_exe || IEDRIVER_EXE) | ||
super(opt_exe) | ||
this.setLoopback(true) // Required. | ||
@@ -496,2 +463,5 @@ } | ||
} | ||
if (!service.getExecutable()) { | ||
service.setExecutable(getPath(options).driverPath) | ||
} | ||
@@ -523,2 +493,1 @@ let client = service.start().then((url) => new http.HttpClient(url)) | ||
exports.Behavior = SCROLL_BEHAVIOUR | ||
exports.locateSynchronously = locateSynchronously |
10
index.js
@@ -42,2 +42,7 @@ // Licensed to the Software Freedom Conservancy (SFC) under one | ||
const select = require('./lib/select') | ||
const LogInspector = require('./bidi/logInspector') | ||
const BrowsingContext = require('./bidi/browsingContext') | ||
const BrowsingConextInspector = require('./bidi/browsingContextInspector') | ||
const ScriptManager = require('./bidi/scriptManager') | ||
const NetworkInspector = require('./bidi/networkInspector') | ||
@@ -799,1 +804,6 @@ const Browser = capabilities.Browser | ||
exports.Select = select.Select | ||
exports.LogInspector = LogInspector | ||
exports.BrowsingContext = BrowsingContext | ||
exports.BrowsingConextInspector = BrowsingConextInspector | ||
exports.ScriptManager = ScriptManager | ||
exports.NetworkInspector = NetworkInspector |
@@ -137,3 +137,3 @@ // Licensed to the Software Freedom Conservancy (SFC) under one | ||
const result = new Promise((resolve) => { | ||
const result = new Promise((resolve, reject) => { | ||
proc.once('exit', (code, signal) => { | ||
@@ -144,2 +144,6 @@ proc = null | ||
}) | ||
proc.once('error', (err) => { | ||
reject(err) | ||
}) | ||
}) | ||
@@ -146,0 +150,0 @@ return new Command(result, killCommand) |
@@ -117,8 +117,7 @@ // GENERATED CODE - DO NOT EDIT | ||
"\\$1")}};var Y={},rd={};Y.N=function(a,b,c){try{var d=Nc.j("a",b)}catch(e){d=mb(eb(b),"A",null,b)}return ua(d,function(e){e=id(e);e=e.replace(/^[\s]+|[\s]+$/g,"");return c&&-1!=e.indexOf(a)||e==a})};Y.K=function(a,b,c){try{var d=Nc.j("a",b)}catch(e){d=mb(eb(b),"A",null,b)}return pa(d,function(e){e=id(e);e=e.replace(/^[\s]+|[\s]+$/g,"");return c&&-1!=e.indexOf(a)||e==a})};Y.o=function(a,b){return Y.N(a,b,!1)};Y.j=function(a,b){return Y.K(a,b,!1)};rd.o=function(a,b){return Y.N(a,b,!0)}; | ||
rd.j=function(a,b){return Y.K(a,b,!0)};var Z={F:function(a,b){return function(c){var d=Z.u(a);d=W(d);c=W(c);return b.call(null,d,c)}},R:function(a){return Z.F(a,function(b,c){return c.b+c.height<b.b})},S:function(a){return Z.F(a,function(b,c){return b.b+b.height<c.b})},V:function(a){return Z.F(a,function(b,c){return c.a+c.width<b.a})},aa:function(a){return Z.F(a,function(b,c){return b.a+b.width<c.a})},W:function(a,b){var c;b?c=b:"number"==typeof a.distance&&(c=a.distance);c||(c=100);return function(d){var e=Z.u(a);if(e===d)return!1;e= | ||
W(e);d=W(d);var f=Math.abs(e.a+e.width-d.a),g=Math.abs(e.b+e.height-d.b);g=Math.abs(e.b-(d.b+d.height))<=c||g<=c;return(Math.abs(e.a-(d.a+d.width))<=c||f<=c)&&g?!0:Math.sqrt(Math.pow(Math.abs(e.a+e.width/2-(d.a+d.width/2)),2)+Math.pow(Math.abs(e.b+e.height/2-(d.b+d.height/2)),2))<=c}},u:function(a){if(ha(a)&&1==a.nodeType)return a;if(ea(a))return Z.u(a.call(null));if(ha(a)){var b;a:{if(b=sd(a)){var c=td[b];if(c&&ea(c.o)){b=c.o(a[b],Bc.document);break a}}throw new P(61,"Unsupported locator strategy: "+ | ||
b);}if(!b)throw new P(7,"No element has been found by "+JSON.stringify(a));return b}throw new P(61,"Selector is of wrong type: "+JSON.stringify(a));}};Z.P={left:Z.V,right:Z.aa,above:Z.R,below:Z.S,near:Z.W};Z.O={left:Z.u,right:Z.u,above:Z.u,below:Z.u,near:Z.u}; | ||
Z.U=function(a,b){var c=[];l(a,function(e){e&&ta(b,function(f){var g=f.kind,h=Z.P[g];if(!h)throw new P(61,"Cannot find filter suitable for "+g);return h.apply(null,f.args)(e)},null)&&c.push(e)},null);a=b[b.length-1];var d=Z.O[a?a.kind:"unknown"];return d?(a=d.apply(null,a.args))?Z.ba(a,c):c:c}; | ||
rd.j=function(a,b){return Y.K(a,b,!0)};var Z={F:function(a,b){return function(c){var d=Z.u(a);d=W(d);c=W(c);return b.call(null,d,c)}},R:function(a){return Z.F(a,function(b,c){return c.b+c.height<b.b})},S:function(a){return Z.F(a,function(b,c){return b.b+b.height<c.b})},V:function(a){return Z.F(a,function(b,c){return c.a+c.width<b.a})},aa:function(a){return Z.F(a,function(b,c){return b.a+b.width<c.a})},W:function(a,b){var c;b?c=b:"number"==typeof a.distance&&(c=a.distance);c||(c=50);return function(d){var e=Z.u(a);if(e===d)return!1;e=W(e); | ||
d=W(d);e=new U(e.a-c,e.b-c,e.width+2*c,e.height+2*c);return e.a<=d.a+d.width&&d.a<=e.a+e.width&&e.b<=d.b+d.height&&d.b<=e.b+e.height}},u:function(a){if(ha(a)&&1==a.nodeType)return a;if(ea(a))return Z.u(a.call(null));if(ha(a)){var b;a:{if(b=sd(a)){var c=td[b];if(c&&ea(c.o)){b=c.o(a[b],Bc.document);break a}}throw new P(61,"Unsupported locator strategy: "+b);}if(!b)throw new P(7,"No element has been found by "+JSON.stringify(a));return b}throw new P(61,"Selector is of wrong type: "+JSON.stringify(a)); | ||
}};Z.P={left:Z.V,right:Z.aa,above:Z.R,below:Z.S,near:Z.W};Z.O={left:Z.u,right:Z.u,above:Z.u,below:Z.u,near:Z.u};Z.U=function(a,b){var c=[];l(a,function(e){e&&ta(b,function(f){var g=f.kind,h=Z.P[g];if(!h)throw new P(61,"Cannot find filter suitable for "+g);return h.apply(null,f.args)(e)},null)&&c.push(e)},null);a=b[b.length-1];var d=Z.O[a?a.kind:"unknown"];return d?(a=d.apply(null,a.args))?Z.ba(a,c):c:c}; | ||
Z.ba=function(a,b){function c(f){f=W(f);return Math.sqrt(Math.pow(d-(f.a+Math.max(1,f.width)/2),2)+Math.pow(e-(f.b+Math.max(1,f.height)/2),2))}a=W(a);var d=a.a+Math.max(1,a.width)/2,e=a.b+Math.max(1,a.height)/2;xa(b,function(f,g){return c(f)-c(g)});return b};Z.o=function(a,b){a=Z.j(a,b);return 0==a.length?null:a[0]}; | ||
Z.j=function(a,b){if(!a.hasOwnProperty("root")||!a.hasOwnProperty("filters"))throw new P(61,"Locator not suitable for relative locators: "+JSON.stringify(a));var c=a.filters,d=da(c);if("array"!=d&&("object"!=d||"number"!=typeof c.length))throw new P(61,"Targets should be an array: "+JSON.stringify(a));var e;S(a.root)?e=[a.root]:e=ud(a.root,b);return 0==e.length?[]:Z.U(e,a.filters)};var vd={o:function(a,b){if(""===a)throw new P(32,'Unable to locate an element with the tagName ""');return b.getElementsByTagName(a)[0]||null},j:function(a,b){if(""===a)throw new P(32,'Unable to locate an element with the tagName ""');return b.getElementsByTagName(a)}};var td={className:Dc,"class name":Dc,css:Nc,"css selector":Nc,relative:Z,id:qd,linkText:Y,"link text":Y,name:{o:function(a,b){b=mb(eb(b),"*",null,b);return ua(b,function(c){return Uc(c,"name")==a})},j:function(a,b){b=mb(eb(b),"*",null,b);return pa(b,function(c){return Uc(c,"name")==a})}},partialLinkText:rd,"partial link text":rd,tagName:vd,"tag name":vd,xpath:T};function sd(a){for(var b in a)if(a.hasOwnProperty(b))return b;return null} | ||
function ud(a,b){var c=sd(a);if(c){var d=td[c];if(d&&ea(d.j))return d.j(a[c],b||Bc.document)}throw new P(61,"Unsupported locator strategy: "+c);};ca("_",ud);; return this._.apply(null,arguments);}).apply({navigator:typeof window!='undefined'?window.navigator:null,document:typeof window!='undefined'?window.document:null}, arguments);}; |
@@ -399,3 +399,7 @@ // Licensed to the Software Freedom Conservancy (SFC) under one | ||
function check(locator) { | ||
if (locator instanceof By || typeof locator === 'function') { | ||
if ( | ||
locator instanceof By || | ||
locator instanceof RelativeBy || | ||
typeof locator === 'function' | ||
) { | ||
return locator | ||
@@ -402,0 +406,0 @@ } |
@@ -185,3 +185,3 @@ // Licensed to the Software Freedom Conservancy (SFC) under one | ||
*/ | ||
function toExecuteAtomCommand(command, atom, ...params) { | ||
function toExecuteAtomCommand(command, atom, name, ...params) { | ||
if (typeof atom !== 'function') { | ||
@@ -193,4 +193,7 @@ throw new InternalTypeError('atom is not a function: ' + typeof atom) | ||
.setParameter('sessionId', command.getParameter('sessionId')) | ||
.setParameter('script', `return (${atom}).apply(null, arguments)`) | ||
.setParameter( | ||
'script', | ||
`/* ${name} */return (${atom}).apply(null, arguments)` | ||
) | ||
.setParameter( | ||
'args', | ||
@@ -257,3 +260,8 @@ params.map((param) => command.getParameter(param)) | ||
(cmd) => { | ||
return toExecuteAtomCommand(cmd, Atom.FIND_ELEMENTS, 'args') | ||
return toExecuteAtomCommand( | ||
cmd, | ||
Atom.FIND_ELEMENTS, | ||
'findElements', | ||
'args' | ||
) | ||
}, | ||
@@ -278,3 +286,9 @@ ], | ||
(cmd) => { | ||
return toExecuteAtomCommand(cmd, Atom.GET_ATTRIBUTE, 'id', 'name') | ||
return toExecuteAtomCommand( | ||
cmd, | ||
Atom.GET_ATTRIBUTE, | ||
'getAttribute', | ||
'id', | ||
'name' | ||
) | ||
}, | ||
@@ -315,3 +329,3 @@ ], | ||
(cmd) => { | ||
return toExecuteAtomCommand(cmd, Atom.IS_DISPLAYED, 'id') | ||
return toExecuteAtomCommand(cmd, Atom.IS_DISPLAYED, 'isDisplayed', 'id') | ||
}, | ||
@@ -318,0 +332,0 @@ ], |
{ | ||
"name": "selenium-webdriver", | ||
"version": "4.7.0", | ||
"version": "4.14.0", | ||
"description": "The official WebDriver JavaScript bindings from the Selenium project", | ||
@@ -26,24 +26,23 @@ "license": "Apache-2.0", | ||
"dependencies": { | ||
"jszip": "^3.10.0", | ||
"jszip": "^3.10.1", | ||
"tmp": "^0.2.1", | ||
"ws": ">=8.7.0" | ||
"ws": ">=8.14.2" | ||
}, | ||
"devDependencies": { | ||
"eslint": "^8.27.0", | ||
"eslint-config-prettier": "^8.5.0", | ||
"eslint": "^8.50.0", | ||
"eslint-config-prettier": "^9.0.0", | ||
"eslint-plugin-no-only-tests": "^3.1.0", | ||
"eslint-plugin-node": "^11.1.0", | ||
"eslint-plugin-prettier": "^4.2.0", | ||
"eslint-plugin-prettier": "^5.0.0", | ||
"express": "^4.18.2", | ||
"jasmine": "^4.5.0", | ||
"mocha": "^10.1.0", | ||
"mocha": "^10.2.0", | ||
"multer": "^1.4.5-lts.1", | ||
"prettier": "^2.7.1", | ||
"prettier": "^3.0.3", | ||
"serve-index": "^1.9.1", | ||
"sinon": "^14.0.2" | ||
"sinon": "^16.1.0" | ||
}, | ||
"scripts": { | ||
"lint": "eslint --ignore-pattern node_modules --ignore-pattern generator --fix --ext js lib/http.js \"**/*.js\"", | ||
"lint": "eslint --ignore-pattern node_modules --ignore-pattern generator --ext js lib/http.js \"**/*.js\"", | ||
"test": "npm run lint && mocha -t 600000 --recursive test", | ||
"test-jasmine": "jasmine JASMINE_CONFIG_PATH=jasmine.json" | ||
"test-jasmine": "bazel test //javascript/node/selenium-webdriver:tests" | ||
}, | ||
@@ -50,0 +49,0 @@ "mocha": { |
@@ -20,4 +20,2 @@ // Licensed to the Software Freedom Conservancy (SFC) under one | ||
const fs = require('fs') | ||
const path = require('path') | ||
const url = require('url') | ||
@@ -33,3 +31,6 @@ | ||
const portprober = require('../net/portprober') | ||
const logging = require('../lib/logging') | ||
const { getJavaPath, formatSpawnArgs } = require('./util') | ||
/** | ||
@@ -123,2 +124,4 @@ * @typedef {(string|!Array<string|number|!stream.Stream|null|undefined>)} | ||
constructor(executable, options) { | ||
/** @private @const */ | ||
this.log_ = logging.getLogger('webdriver.DriverService') | ||
/** @private {string} */ | ||
@@ -169,2 +172,10 @@ this.executable_ = executable | ||
getExecutable() { | ||
return this.executable_ | ||
} | ||
setExecutable(value) { | ||
this.executable_ = value | ||
} | ||
/** | ||
@@ -243,3 +254,3 @@ * @return {!Promise<string>} A promise that resolves to the server's address. | ||
var serverUrl = url.format({ | ||
const serverUrl = url.format({ | ||
protocol: 'http', | ||
@@ -322,6 +333,2 @@ hostname: hostname, | ||
constructor(exe) { | ||
if (!fs.existsSync(exe)) { | ||
throw Error(`The specified executable path does not exist: ${exe}`) | ||
} | ||
/** @private @const {string} */ | ||
@@ -488,9 +495,11 @@ this.exe_ = exe | ||
let args = resolved[2] | ||
return jvmArgs.concat('-jar', jar, '-port', port).concat(args) | ||
const fullArgsList = jvmArgs | ||
.concat('-jar', jar, '-port', port) | ||
.concat(args) | ||
return formatSpawnArgs(jar, fullArgsList) | ||
}) | ||
let java = 'java' | ||
if (process.env['JAVA_HOME']) { | ||
java = path.join(process.env['JAVA_HOME'], 'bin/java') | ||
} | ||
const java = getJavaPath() | ||
@@ -497,0 +506,0 @@ super(java, { |
@@ -25,35 +25,8 @@ // Licensed to the Software Freedom Conservancy (SFC) under one | ||
const http = require('./http') | ||
const io = require('./io') | ||
const remote = require('./remote') | ||
const webdriver = require('./lib/webdriver') | ||
const { Browser, Capabilities } = require('./lib/capabilities') | ||
const { getPath } = require('./common/driverFinder') | ||
/** | ||
* _Synchronously_ attempts to locate the IE driver executable on the current | ||
* system. | ||
* | ||
* @return {?string} the located executable, or `null`. | ||
*/ | ||
function locateSynchronously() { | ||
return process.platform === 'darwin' | ||
? io.findInPath('safaridriver', true) | ||
: null | ||
} | ||
/** | ||
* @return {string} . | ||
* @throws {Error} | ||
*/ | ||
function findSafariDriver() { | ||
let exe = locateSynchronously() | ||
if (!exe) { | ||
throw Error( | ||
`The safaridriver executable could not be found on the current PATH. | ||
Please ensure you are using Safari 10.0 or above.` | ||
) | ||
} | ||
return exe | ||
} | ||
/** | ||
* Creates {@link selenium-webdriver/remote.DriverService} instances that manage | ||
@@ -70,3 +43,3 @@ * a [safaridriver] server in a child process. | ||
constructor(opt_exe) { | ||
super(opt_exe || findSafariDriver()) | ||
super(opt_exe) | ||
this.setLoopback(true) // Required. | ||
@@ -76,3 +49,3 @@ } | ||
const OPTIONS_CAPABILITY_KEY = 'safari.options' | ||
const OPTIONS_CAPABILITY_KEY = 'safari:options' | ||
const TECHNOLOGY_PREVIEW_OPTIONS_KEY = 'technologyPreview' | ||
@@ -156,2 +129,5 @@ | ||
let service = new ServiceBuilder(exe).build() | ||
if (!service.getExecutable()) { | ||
service.setExecutable(getPath(caps).driverPath) | ||
} | ||
let executor = new http.Executor( | ||
@@ -172,2 +148,1 @@ service.start().then((url) => new http.HttpClient(url)) | ||
exports.ServiceBuilder = ServiceBuilder | ||
exports.locateSynchronously = locateSynchronously |
@@ -44,2 +44,3 @@ // Licensed to the Software Freedom Conservancy (SFC) under one | ||
const { Builder } = require('../index') | ||
const { getPath } = require('../common/driverFinder') | ||
@@ -121,15 +122,20 @@ /** | ||
let targets = [ | ||
[chrome.locateSynchronously, Browser.CHROME], | ||
[edge.locateSynchronously, Browser.EDGE], | ||
[firefox.locateSynchronously, Browser.FIREFOX], | ||
[ie.locateSynchronously, Browser.INTERNET_EXPLORER], | ||
[safari.locateSynchronously, Browser.SAFARI], | ||
[getPath(new chrome.Options()), Browser.CHROME], | ||
[getPath(new edge.Options()), Browser.EDGE], | ||
[getPath(new firefox.Options()), Browser.FIREFOX], | ||
] | ||
if (process.platform === 'win32') { | ||
targets.push([getPath(new ie.Options()), Browser.INTERNET_EXPLORER]) | ||
} | ||
if (process.platform === 'darwin') { | ||
targets.push([getPath(new safari.Options()), Browser.SAFARI]) | ||
} | ||
let availableBrowsers = [] | ||
for (let pair of targets) { | ||
const fn = pair[0] | ||
const driverPath = pair[0].driverPath | ||
const browserPath = pair[0].browserPath | ||
const name = pair[1] | ||
const capabilities = pair[2] | ||
if (fn()) { | ||
if (driverPath.length > 0 && browserPath && browserPath.length > 0) { | ||
info(`... located ${name}`) | ||
@@ -136,0 +142,0 @@ availableBrowsers.push({ name, capabilities }) |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
18481998
11
75
18070
28
6
Updatedjszip@^3.10.1
Updatedws@>=8.14.2