Socket
Socket
Sign inDemoInstall

selenium-webdriver

Package Overview
Dependencies
Maintainers
8
Versions
99
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

selenium-webdriver - npm Package Compare versions

Comparing version 4.17.0 to 4.18.0

bidi/addInterceptParameters.js

181

bidi/browsingContext.js

@@ -20,2 +20,51 @@ // Licensed to the Software Freedom Conservancy (SFC) under one

const { BrowsingContextInfo } = require('./browsingContextTypes')
const { SerializationOptions, ReferenceValue, RemoteValue } = require('./protocolValue')
const { WebElement } = require('../lib/webdriver')
class Locator {
static Type = Object.freeze({
CSS: 'css',
INNER_TEXT: 'innerText',
XPATH: 'xpath',
})
#type
#value
#ignoreCase
#matchType
#maxDepth
constructor(type, value, ignoreCase = undefined, matchType = undefined, maxDepth = undefined) {
this.#type = type
this.#value = value
this.#ignoreCase = ignoreCase
this.#matchType = matchType
this.#maxDepth = maxDepth
}
static css(value) {
return new Locator(Locator.Type.CSS, value)
}
static xpath(value) {
return new Locator(Locator.Type.XPATH, value)
}
static innerText(value, ignoreCase = undefined, matchType = undefined, maxDepth = undefined) {
return new Locator(Locator.Type.INNER_TEXT, value, ignoreCase, matchType, maxDepth)
}
toMap() {
const map = new Map()
map.set('type', this.#type.toString())
map.set('value', this.#value)
map.set('ignoreCase', this.#ignoreCase)
map.set('matchType', this.#matchType)
map.set('maxDepth', this.#maxDepth)
return map
}
}
class BrowsingContext {

@@ -69,9 +118,4 @@ constructor(driver) {

async navigate(url, readinessState = undefined) {
if (
readinessState !== undefined &&
!['none', 'interactive', 'complete'].includes(readinessState)
) {
throw Error(
`Valid readiness states are 'none', 'interactive' & 'complete'. Received: ${readinessState}`
)
if (readinessState !== undefined && !['none', 'interactive', 'complete'].includes(readinessState)) {
throw Error(`Valid readiness states are 'none', 'interactive' & 'complete'. Received: ${readinessState}`)
}

@@ -89,6 +133,3 @@

return new NavigateResult(
navigateResult['url'],
navigateResult['navigation']
)
return new NavigateResult(navigateResult['url'], navigateResult['navigation'])
}

@@ -115,8 +156,3 @@

result = result['result']['contexts'][0]
return new BrowsingContextInfo(
result['context'],
result['url'],
result['children'],
result['parent']
)
return new BrowsingContextInfo(result['context'], result['url'], result['children'], result['parent'])
}

@@ -210,7 +246,3 @@

async captureElementScreenshot(
sharedId,
handle = undefined,
scrollIntoView = undefined
) {
async captureElementScreenshot(sharedId, handle = undefined, scrollIntoView = undefined) {
let params = {

@@ -281,9 +313,4 @@ method: 'browsingContext.captureScreenshot',

async reload(ignoreCache = undefined, readinessState = undefined) {
if (
readinessState !== undefined &&
!['none', 'interactive', 'complete'].includes(readinessState)
) {
throw Error(
`Valid readiness states are 'none', 'interactive' & 'complete'. Received: ${readinessState}`
)
if (readinessState !== undefined && !['none', 'interactive', 'complete'].includes(readinessState)) {
throw Error(`Valid readiness states are 'none', 'interactive' & 'complete'. Received: ${readinessState}`)
}

@@ -301,6 +328,3 @@

return new NavigateResult(
navigateResult['url'],
navigateResult['navigation']
)
return new NavigateResult(navigateResult['url'], navigateResult['navigation'])
}

@@ -341,2 +365,87 @@

}
async locateNodes(
locator,
maxNodeCount = undefined,
ownership = undefined,
sandbox = undefined,
serializationOptions = undefined,
startNodes = undefined,
) {
if (!(locator instanceof Locator)) {
throw Error(`Pass in a Locator object. Received: ${locator}`)
}
if (serializationOptions !== undefined && !(serializationOptions instanceof SerializationOptions)) {
throw Error(`Pass in SerializationOptions object. Received: ${serializationOptions} `)
}
if (ownership !== undefined && !['root', 'none'].includes(ownership)) {
throw Error(`Valid types are 'root' and 'none. Received: ${ownership}`)
}
if (startNodes !== undefined && !Array.isArray(startNodes)) {
throw Error(`Pass in an array of ReferenceValue objects. Received: ${startNodes}`)
}
if (startNodes !== undefined && Array.isArray(startNodes)) {
startNodes.forEach((node) => {
if (!(node instanceof ReferenceValue)) {
throw Error(`Pass in a ReferenceValue object. Received: ${node}`)
}
})
}
const params = {
method: 'browsingContext.locateNodes',
params: {
context: this._id,
locator: Object.fromEntries(locator.toMap()),
maxNodeCount: maxNodeCount,
ownership: ownership,
sandbox: sandbox,
serializationOptions: serializationOptions,
startNodes: startNodes,
},
}
let response = await this.bidi.send(params)
if ('error' in response) {
throw Error(response['error'])
}
const nodes = response.result.nodes
const remoteValues = []
nodes.forEach((node) => {
remoteValues.push(new RemoteValue(node))
})
return remoteValues
}
async locateNode(
locator,
ownership = undefined,
sandbox = undefined,
serializationOptions = undefined,
startNodes = undefined,
) {
const elements = await this.locateNodes(locator, 1, ownership, sandbox, serializationOptions, startNodes)
return elements[0]
}
async locateElement(locator) {
const elements = await this.locateNodes(locator, 1)
return new WebElement(this._driver, elements[0].sharedId)
}
async locateElements(locator) {
const elements = await this.locateNodes(locator)
let webElements = []
elements.forEach((element) => {
webElements.push(new WebElement(this._driver, element.sharedId))
})
return webElements
}
}

@@ -377,6 +486,3 @@

*/
async function getBrowsingContextInstance(
driver,
{ browsingContextId, type, referenceContext }
) {
async function getBrowsingContextInstance(driver, { browsingContextId, type, referenceContext }) {
let instance = new BrowsingContext(driver)

@@ -392,1 +498,2 @@ await instance.init({ browsingContextId, type, referenceContext })

module.exports = getBrowsingContextInstance
module.exports.Locator = Locator

@@ -18,6 +18,3 @@ // Licensed to the Software Freedom Conservancy (SFC) under one

const {
BrowsingContextInfo,
NavigationInfo,
} = require('./browsingContextTypes')
const { BrowsingContextInfo, NavigationInfo } = require('./browsingContextTypes')

@@ -35,41 +32,27 @@ class BrowsingContextInspector {

async onBrowsingContextCreated(callback) {
await this.subscribeAndHandleEvent(
'browsingContext.contextCreated',
callback
)
await this.subscribeAndHandleEvent('browsingContext.contextCreated', callback)
}
async onBrowsingContextDestroyed(callback) {
await this.subscribeAndHandleEvent('browsingContext.contextDestroyed', callback)
}
async onNavigationStarted(callback) {
await this.subscribeAndHandleEvent(
'browsingContext.navigationStarted',
callback
)
await this.subscribeAndHandleEvent('browsingContext.navigationStarted', callback)
}
async onFragmentNavigated(callback) {
await this.subscribeAndHandleEvent(
'browsingContext.fragmentNavigated',
callback
)
await this.subscribeAndHandleEvent('browsingContext.fragmentNavigated', callback)
}
async onUserPromptClosed(callback) {
await this.subscribeAndHandleEvent(
'browsingContext.userPromptClosed',
callback
)
await this.subscribeAndHandleEvent('browsingContext.userPromptClosed', callback)
}
async onUserPromptOpened(callback) {
await this.subscribeAndHandleEvent(
'browsingContext.userPromptOpened',
callback
)
await this.subscribeAndHandleEvent('browsingContext.userPromptOpened', callback)
}
async onDomContentLoaded(callback) {
await this.subscribeAndHandleEvent(
'browsingContext.domContentLoaded',
callback
)
await this.subscribeAndHandleEvent('browsingContext.domContentLoaded', callback)
}

@@ -97,17 +80,7 @@

if ('navigation' in params) {
response = new NavigationInfo(
params.context,
params.navigation,
params.timestamp,
params.url
)
response = new NavigationInfo(params.context, params.navigation, params.timestamp, params.url)
} else if ('accepted' in params) {
/* Needs to be updated when browsers implement other events */
} else {
response = new BrowsingContextInfo(
params.context,
params.url,
params.children,
params.parent
)
response = new BrowsingContextInfo(params.context, params.url, params.children, params.parent)
}

@@ -114,0 +87,0 @@ callback(response)

@@ -41,12 +41,6 @@ // Licensed to the Software Freedom Conservancy (SFC) under one

constructor(exceptionDetails) {
this.columnNumber =
'columnNumber' in exceptionDetails
? exceptionDetails['columnNumber']
: null
this.exception =
'exception' in exceptionDetails ? exceptionDetails['exception'] : null
this.lineNumber =
'lineNumber' in exceptionDetails ? exceptionDetails['lineNumber'] : null
this.stackTrace =
'stackTrace' in exceptionDetails ? exceptionDetails['stackTrace'] : null
this.columnNumber = 'columnNumber' in exceptionDetails ? exceptionDetails['columnNumber'] : null
this.exception = 'exception' in exceptionDetails ? exceptionDetails['exception'] : null
this.lineNumber = 'lineNumber' in exceptionDetails ? exceptionDetails['lineNumber'] : null
this.stackTrace = 'stackTrace' in exceptionDetails ? exceptionDetails['stackTrace'] : null
this.text = 'text' in exceptionDetails ? exceptionDetails['text'] : null

@@ -53,0 +47,0 @@ }

@@ -24,9 +24,5 @@ // Licensed to the Software Freedom Conservancy (SFC) under one

static logLevel(level) {
if (
level === undefined ||
(level != undefined &&
!['debug', 'error', 'info', 'warning'].includes(level))
) {
if (level === undefined || (level != undefined && !['debug', 'error', 'info', 'warning'].includes(level))) {
throw Error(
`Please pass valid log level. Valid log levels are 'debug', 'error', 'info' and 'warning'. Received: ${level}`
`Please pass valid log level. Valid log levels are 'debug', 'error', 'info' and 'warning'. Received: ${level}`,
)

@@ -33,0 +29,0 @@ }

@@ -18,2 +18,3 @@ // Licensed to the Software Freedom Conservancy (SFC) under one

// eslint-disable-next-line node/no-missing-require
const { EventEmitter } = require('node:events')

@@ -26,3 +27,3 @@ const WebSocket = require('ws')

id = 0
isConnected = false
connected = false
events = []

@@ -35,8 +36,8 @@ browsingContexts = []

*/
constructor (_webSocketUrl) {
constructor(_webSocketUrl) {
super()
this.isConnected = false
this.connected = false
this._ws = new WebSocket(_webSocketUrl)
this._ws.on('open', () => {
this.isConnected = true
this.connected = true
})

@@ -49,5 +50,5 @@ }

*/
async waitForConnection () {
async waitForConnection() {
return new Promise((resolve) => {
if (this.isConnected) {
if (this.connected) {
resolve()

@@ -65,3 +66,3 @@ } else {

*/
get socket () {
get socket() {
return this._ws

@@ -73,4 +74,4 @@ }

*/
get isConnected () {
return this.isConnected
get isConnected() {
return this.connected
}

@@ -83,4 +84,4 @@

*/
async send (params) {
if (!this.isConnected) {
async send(params) {
if (!this.connected) {
await this.waitForConnection()

@@ -108,2 +109,3 @@ }

} catch (err) {
// eslint-disable-next-line no-undef
log.error(`Failed parse message: ${err.message}`)

@@ -123,4 +125,4 @@ }

*/
async subscribe (events, browsingContexts) {
function toArray (arg) {
async subscribe(events, browsingContexts) {
function toArray(arg) {
if (arg === undefined) {

@@ -137,12 +139,11 @@ return []

const params = {
method: 'session.subscribe', params: {},
method: 'session.subscribe',
params: {},
}
if (eventsArray.length && eventsArray.some(
event => typeof event !== 'string')) {
if (eventsArray.length && eventsArray.some((event) => typeof event !== 'string')) {
throw new TypeError('events should be string or string array')
}
if (contextsArray.length && contextsArray.some(
context => typeof context !== 'string')) {
if (contextsArray.length && contextsArray.some((context) => typeof context !== 'string')) {
throw new TypeError('browsingContexts should be string or string array')

@@ -168,7 +169,7 @@ }

*/
async unsubscribe (events, browsingContexts) {
async unsubscribe(events, browsingContexts) {
if (typeof events === 'string') {
this.events = this.events.filter(event => event !== events)
this.events = this.events.filter((event) => event !== events)
} else if (Array.isArray(events)) {
this.events = this.events.filter(event => !events.includes(event))
this.events = this.events.filter((event) => !events.includes(event))
}

@@ -179,10 +180,10 @@

} else if (Array.isArray(browsingContexts)) {
this.browsingContexts =
this.browsingContexts.filter(id => !browsingContexts.includes(id))
this.browsingContexts = this.browsingContexts.filter((id) => !browsingContexts.includes(id))
}
const params = {
method: 'session.unsubscribe', params: {
method: 'session.unsubscribe',
params: {
events: this.events,
}
},
}

@@ -201,5 +202,6 @@

*/
get status () {
get status() {
return this.send({
method: 'session.status', params: {}
method: 'session.status',
params: {},
})

@@ -212,3 +214,3 @@ }

*/
close () {
close() {
const closeWebSocket = (callback) => {

@@ -228,3 +230,3 @@ // don't close if it's already closed

}
return new Promise((fulfill, reject) => {
return new Promise((fulfill, _) => {
closeWebSocket(fulfill)

@@ -231,0 +233,0 @@ })

@@ -70,6 +70,3 @@ // Licensed to the Software Freedom Conservancy (SFC) under one

for (const sequence of sequenceList) {
if (
(sequence.type === 'pointerMove' || sequence.type === 'scroll') &&
sequence.origin instanceof WebElement
) {
if ((sequence.type === 'pointerMove' || sequence.type === 'scroll') && sequence.origin instanceof WebElement) {
const element = sequence.origin

@@ -76,0 +73,0 @@ const elementId = await element.getId()

@@ -22,4 +22,4 @@ // Licensed to the Software Freedom Conservancy (SFC) under one

const LOG = {
TYPE_CONSOLE : 'console',
TYPE_JS_LOGS : 'javascript',
TYPE_CONSOLE: 'console',
TYPE_JS_LOGS: 'javascript',
}

@@ -31,3 +31,3 @@

constructor (driver, browsingContextIds) {
constructor(driver, browsingContextIds) {
this._driver = driver

@@ -42,3 +42,3 @@ this._browsingContextIds = browsingContextIds

*/
async init () {
async init() {
this.bidi = await this._driver.getBidi()

@@ -51,3 +51,3 @@ await this.bidi.subscribe('log.entryAdded', this._browsingContextIds)

*/
logListener (kind) {
logListener(kind) {
if (!(kind in this.listener)) {

@@ -83,3 +83,3 @@ this.listener[kind] = []

params.args,
params.stackTrace
params.stackTrace,
)

@@ -121,3 +121,3 @@

params.type,
params.stackTrace
params.stackTrace,
)

@@ -144,5 +144,3 @@

this.ws = await this.bidi.socket
let enabled =
LOG.TYPE_JS_EXCEPTION in this.listener ||
this.logListener(LOG.TYPE_JS_EXCEPTION)
let enabled = LOG.TYPE_JS_EXCEPTION in this.listener || this.logListener(LOG.TYPE_JS_EXCEPTION)
this.listener[LOG.TYPE_JS_EXCEPTION].push(callback)

@@ -162,3 +160,3 @@

params.type,
params.stackTrace
params.stackTrace,
)

@@ -194,3 +192,3 @@

params.type,
params.stackTrace
params.stackTrace,
)

@@ -218,3 +216,3 @@

params.args,
params.stackTrace
params.stackTrace,
)

@@ -233,6 +231,3 @@

if (
params !== undefined &&
!['console', 'javascript'].includes(params?.type)
) {
if (params !== undefined && !['console', 'javascript'].includes(params?.type)) {
let genericEntry = new GenericLogEntry(

@@ -243,3 +238,3 @@ params.level,

params.type,
params.stackTrace
params.stackTrace,
)

@@ -263,3 +258,3 @@

*/
async close () {
async close() {
await this.bidi.unsubscribe('log.entryAdded', this._browsingContextIds)

@@ -275,3 +270,3 @@ }

*/
async function getLogInspectorInstance (driver, browsingContextIds) {
async function getLogInspectorInstance(driver, browsingContextIds) {
let instance = new LogInspector(driver, browsingContextIds)

@@ -278,0 +273,0 @@ await instance.init()

@@ -20,2 +20,8 @@ // Licensed to the Software Freedom Conservancy (SFC) under one

/**
* @deprecated
* in favor of using the `Network` class from `bidi/network.js`
* Inspector is specific to listening to events.
* Goal is to club commands and events under one class called Network.
*/
class NetworkInspector {

@@ -69,3 +75,3 @@ constructor(driver, browsingContextIds) {

params.timestamp,
params.initiator
params.initiator,
)

@@ -79,3 +85,3 @@ } else if ('response' in params) {

params.timestamp,
params.response
params.response,
)

@@ -82,0 +88,0 @@ }

@@ -41,14 +41,3 @@ // Licensed to the Software Freedom Conservancy (SFC) under one

class Cookie {
constructor(
name,
value,
binaryValue,
domain,
path,
expires,
size,
httpOnly,
secure,
sameSite
) {
constructor(name, value, binaryValue, domain, path, expires, size, httpOnly, secure, sameSite) {
this._name = name

@@ -122,3 +111,3 @@ this._value = value

responseStart,
responseEnd
responseEnd,
) {

@@ -194,12 +183,3 @@ this._originTime = originTime

class RequestData {
constructor(
request,
url,
method,
headers,
cookies,
headersSize,
bodySize,
timings
) {
constructor(request, url, method, headers, cookies, headersSize, bodySize, timings) {
this._request = request

@@ -230,16 +210,3 @@ this._url = url

this._cookies.push(
new Cookie(
name,
value,
binaryValue,
domain,
path,
expires,
size,
httpOnly,
secure,
sameSite
)
)
this._cookies.push(new Cookie(name, value, binaryValue, domain, path, expires, size, httpOnly, secure, sameSite))
})

@@ -261,3 +228,3 @@ this._headersSize = headersSize

timings.responseStart,
timings.responseEnd
timings.responseEnd,
)

@@ -304,8 +271,3 @@ }

navigation != null
? new NavigationInfo(
navigation.context,
navigation.navigation,
navigation.timestamp,
navigation.url
)
? new NavigationInfo(navigation.context, navigation.navigation, navigation.timestamp, navigation.url)
: null

@@ -321,3 +283,3 @@ this._redirectCount = redirectCount

request.bodySize,
request.timings
request.timings,
)

@@ -386,3 +348,3 @@ this._timestamp = timestamp

initiator.stackTrace,
initiator.request
initiator.request,
)

@@ -396,2 +358,13 @@ }

class FetchError extends BaseParameters {
constructor(id, navigation, redirectCount, request, timestamp, errorText) {
super(id, navigation, redirectCount, request, timestamp)
this._errorText = errorText
}
get errorText() {
return this._errorText
}
}
class ResponseData {

@@ -409,3 +382,3 @@ constructor(

bodySize,
content
content,
) {

@@ -484,3 +457,3 @@ this._url = url

response.bodySize,
response.content
response.content,
)

@@ -494,2 +467,2 @@ }

module.exports = { BeforeRequestSent, ResponseStarted }
module.exports = { BeforeRequestSent, ResponseStarted, FetchError }

@@ -30,5 +30,3 @@ // Licensed to the Software Freedom Conservancy (SFC) under one

Object.values(this).find((type) => {
return (
typeof type === 'string' && name.toLowerCase() === type.toLowerCase()
)
return typeof type === 'string' && name.toLowerCase() === type.toLowerCase()
}) || null

@@ -51,5 +49,3 @@ )

Object.values(this).find((type) => {
return (
typeof type === 'string' && name.toLowerCase() === type.toLowerCase()
)
return typeof type === 'string' && name.toLowerCase() === type.toLowerCase()
}) || null

@@ -80,5 +76,3 @@ )

Object.values(this).find((type) => {
return (
typeof type === 'string' && name.toLowerCase() === type.toLowerCase()
)
return typeof type === 'string' && name.toLowerCase() === type.toLowerCase()
}) || null

@@ -85,0 +79,0 @@ )

@@ -18,7 +18,3 @@ // Licensed to the Software Freedom Conservancy (SFC) under one

const {
PrimitiveType,
NonPrimitiveType,
RemoteType,
} = require('./protocolType')
const { PrimitiveType, NonPrimitiveType, RemoteType } = require('./protocolType')

@@ -110,8 +106,3 @@ const TYPE_CONSTANT = 'type'

if (
!(
this.type === PrimitiveType.NULL ||
this.type === PrimitiveType.UNDEFINED
)
) {
if (!(this.type === PrimitiveType.NULL || this.type === PrimitiveType.UNDEFINED)) {
toReturn[VALUE_CONSTANT] = this.value

@@ -205,7 +196,3 @@ }

class SerializationOptions {
constructor(
maxDomDepth = 0,
maxObjectDepth = null,
includeShadowTree = 'none'
) {
constructor(maxDomDepth = 0, maxObjectDepth = null, includeShadowTree = 'none') {
this._maxDomDepth = maxDomDepth

@@ -215,5 +202,3 @@ this._maxObjectDepth = maxObjectDepth

if (['none', 'open', 'all'].includes(includeShadowTree)) {
throw Error(
`Valid types are 'none', 'open', and 'all'. Received: ${includeShadowTree}`
)
throw Error(`Valid types are 'none', 'open', and 'all'. Received: ${includeShadowTree}`)
}

@@ -232,5 +217,3 @@ this._includeShadowTree = includeShadowTree

} else {
throw Error(
`Pass in SerializationOptions object. Received: ${options} `
)
throw Error(`Pass in SerializationOptions object. Received: ${options} `)
}

@@ -243,5 +226,3 @@ }

} else {
throw Error(
`Valid types are 'root' and 'none. Received: ${resultOwnership}`
)
throw Error(`Valid types are 'root' and 'none. Received: ${resultOwnership}`)
}

@@ -248,0 +229,0 @@ }

@@ -31,5 +31,3 @@ // Licensed to the Software Freedom Conservancy (SFC) under one

Object.values(this).find((type) => {
return (
typeof type === 'string' && name.toLowerCase() === type.toLowerCase()
)
return typeof type === 'string' && name.toLowerCase() === type.toLowerCase()
}) || null

@@ -76,9 +74,3 @@ )

if (realmType === RealmType.WINDOW) {
return new WindowRealmInfo(
realmId,
origin,
realmType,
browsingContext,
sandbox
)
return new WindowRealmInfo(realmId, origin, realmType, browsingContext, sandbox)
}

@@ -85,0 +77,0 @@

@@ -58,7 +58,3 @@ // Licensed to the Software Freedom Conservancy (SFC) under one

async disownBrowsingContextScript(
browsingContextId,
handles,
sandbox = null
) {
async disownBrowsingContextScript(browsingContextId, handles, sandbox = null) {
const params = {

@@ -87,3 +83,3 @@ method: 'script.disown',

thisParameter = null,
resultOwnership = null
resultOwnership = null,
) {

@@ -98,3 +94,3 @@ const params = this.getCallFunctionParams(

thisParameter,
resultOwnership
resultOwnership,
)

@@ -118,3 +114,3 @@

resultOwnership = null,
sandbox = null
sandbox = null,
) {

@@ -129,3 +125,3 @@ const params = this.getCallFunctionParams(

thisParameter,
resultOwnership
resultOwnership,
)

@@ -141,16 +137,4 @@

async evaluateFunctionInRealm(
realmId,
expression,
awaitPromise,
resultOwnership = null
) {
const params = this.getEvaluateParams(
'realm',
realmId,
null,
expression,
awaitPromise,
resultOwnership
)
async evaluateFunctionInRealm(realmId, expression, awaitPromise, resultOwnership = null) {
const params = this.getEvaluateParams('realm', realmId, null, expression, awaitPromise, resultOwnership)

@@ -171,3 +155,3 @@ const command = {

resultOwnership = null,
sandbox = null
sandbox = null,
) {

@@ -180,3 +164,3 @@ const params = this.getEvaluateParams(

awaitPromise,
resultOwnership
resultOwnership,
)

@@ -193,7 +177,3 @@

async addPreloadScript(
functionDeclaration,
argumentValueList = [],
sandbox = null
) {
async addPreloadScript(functionDeclaration, argumentValueList = [], sandbox = null) {
const params = {

@@ -235,3 +215,3 @@ functionDeclaration: functionDeclaration,

thisParameter = null,
resultOwnership = null
resultOwnership = null,
) {

@@ -271,10 +251,3 @@ const params = {

getEvaluateParams(
targetType,
id,
sandbox,
expression,
awaitPromise,
resultOwnership = null
) {
getEvaluateParams(targetType, id, sandbox, expression, awaitPromise, resultOwnership = null) {
const params = {

@@ -307,12 +280,6 @@ expression: expression,

const result = response.result.result
evaluateResult = new EvaluateResultSuccess(
realmId,
new RemoteValue(result)
)
evaluateResult = new EvaluateResultSuccess(realmId, new RemoteValue(result))
} else {
const exceptionDetails = response.result.exceptionDetails
evaluateResult = new EvaluateResultException(
realmId,
new ExceptionDetails(exceptionDetails)
)
evaluateResult = new EvaluateResultException(realmId, new ExceptionDetails(exceptionDetails))
}

@@ -374,2 +341,6 @@ return evaluateResult

async onRealmDestroyed(callback) {
await this.subscribeAndHandleEvent('script.realmDestroyed', callback)
}
async subscribeAndHandleEvent(eventType, callback) {

@@ -391,16 +362,6 @@ if (this._browsingContextIds != null) {

if ('channel' in params) {
response = new Message(
params.channel,
new RemoteValue(params.data),
new Source(params.source)
)
response = new Message(params.channel, new RemoteValue(params.data), new Source(params.source))
} else if ('realm' in params) {
if (params.type === RealmType.WINDOW) {
response = new WindowRealmInfo(
params.realm,
params.origin,
params.type,
params.context,
params.sandbox
)
response = new WindowRealmInfo(params.realm, params.origin, params.type, params.context, params.sandbox)
} else if (params.realm !== null && params.type !== null) {

@@ -407,0 +368,0 @@ response = new RealmInfo(params.realm, params.origin, params.type)

@@ -0,1 +1,14 @@

## 4.18.0
* Fix running the casting related methods in chromium (#13479)
* [bidi] Add browsing context destroyed event
* [bidi] Add realm destroyed event
* [bidi] Add locate node command (#13489)
* [bidi] Deprecate NetworkInspector in favor of Network
* Make `npm run lint` pass for javascript/node/selenium-webdriver (#13560)
* [bidi] Add "addintercept" and "removeintercept" commands (#13564)
* [bidi] Add auth related commands (#13572)
* [bidi] Add 'continueWithAuth' command
* [bidi] Add 'fetchError' command
## 4.17.0

@@ -29,3 +42,2 @@

## 4.15.0

@@ -58,3 +70,3 @@

* Adding CDP v117 and removing v114
* Added file location to exception message for Selenium Manager
* Added file location to exception message for Selenium Manager

@@ -253,11 +265,11 @@ #### :rocket: New Feature

* Adds 'Select' support package
* selectByIndex
* selectByValue
* selectByVisibleText
* getAllSelectedOptions
* getFirstSelectedOption
* deselectAll
* deselectByVisibleText
* deselectByIndex
* deselectByValue
* selectByIndex
* selectByValue
* selectByVisibleText
* getAllSelectedOptions
* getFirstSelectedOption
* deselectAll
* deselectByVisibleText
* deselectByIndex
* deselectByValue
* Add support for Actions API sendKeys to designated element

@@ -270,3 +282,4 @@ * Adds mouse button enum for forward and backward navigation

* fix: geckodriver session with node 18.x.x (issue 2 in #10970)
* fix: JS firefox driver crashes on setting a profile (fixed with [commit](https://github.com/SeleniumHQ/selenium/commit/fa6deeea6bda1e73317157845772e114bd569b7d))
* fix: JS firefox driver crashes on setting a profile (fixed
with [commit](https://github.com/SeleniumHQ/selenium/commit/fa6deeea6bda1e73317157845772e114bd569b7d))
* fix: "SetExperimental" option is not available in webdriverjs (Javascript/Typescript) (#10959)

@@ -341,3 +354,4 @@ * fix: Do not allow Select class to select disabled options (#10812)

* Code cleanup and minor improvements
* Implements 'getDomAttribute' to get attribute value as defined by w3c spec and removes legacy command usages
* Implements 'getDomAttribute' to get attribute value as defined by w3c spec and removes legacy
command usages
* Remove legacy JWP support and w3c<boolean> switch (#10095)

@@ -425,3 +439,3 @@ * update map/filter clean up to common format (#10094)

* JS Binding support for WebDriver Bidi in Firefox
* This requires Firefox 87 and Geckodriver 0.29 to be able to work
* This requires Firefox 87 and Geckodriver 0.29 to be able to work
* Update the supported CDP versions

@@ -440,7 +454,8 @@ * Update tmp package version (#9155)

* Added new ieOptions capabilities:
* fileUploadDialogTimeout
* setEdgePath
* setEdgeChromium
* setScrollBehavior
* For consistent naming, deprecating `addArguments(...args)` in favor of `addBrowserCommandSwitches(...args)`
* fileUploadDialogTimeout
* setEdgePath
* setEdgeChromium
* setScrollBehavior
* For consistent naming, deprecating `addArguments(...args)` in favor
of `addBrowserCommandSwitches(...args)`

@@ -501,7 +516,9 @@ * Added relative locators

* Revamped the actions API to conform with the WebDriver Spec:
<https://www.w3.org/TR/webdriver/#actions>. For details, refer to the JS doc on the `lib/input.Actions` class.
<https://www.w3.org/TR/webdriver/#actions>. For details, refer to the JS doc on
the `lib/input.Actions` class.
As of January, 2018, only Firefox natively supports this new API. You can put the `Actions` class
into "bridge mode" and it will attempt to translate mouse and keyboard actions to the legacy API (
see class docs). Alternatively, you may continue to use the legacy API directly via the `lib/actions` module.
see class docs). Alternatively, you may continue to use the legacy API directly via
the `lib/actions` module.
__NOTE:__ The legacy API is considered strongly deprecated and will be removed in a minor release

@@ -512,5 +529,7 @@ once Google's Chrome and Microsoft's Edge browsers support the new API.

* Added `driver.switchTo().parentFrame()`
* When a named cookie is requested, attempt to fetch it directly using the W3C endpoint, `GET /session/{session id}/cookie/{name}`. If this command is not recognized by the
* When a named cookie is requested, attempt to fetch it directly using the W3C
endpoint, `GET /session/{session id}/cookie/{name}`. If this command is not recognized by the
remote end, fallback to fetching all cookies and then searching for the desired name.
* Replaced `WebElement.getSize()` and `WebElement.getLocation()` with a single method, `WebElement.getRect()`.
* Replaced `WebElement.getSize()` and `WebElement.getLocation()` with a single
method, `WebElement.getRect()`.

@@ -520,7 +539,7 @@ ### API Changes

* The core WebDriver API no longer uses promise manager
* Removed `index.Builder#setControlFlow()`
* The following thenable types no longer have a `cancel()` method:
* The dynamically generated thenable WebDrivers created by `index.Builder`
* `lib/webdriver.AlertPromise`
* `lib/webdriver.WebElementPromise`
* Removed `index.Builder#setControlFlow()`
* The following thenable types no longer have a `cancel()` method:
* The dynamically generated thenable WebDrivers created by `index.Builder`
* `lib/webdriver.AlertPromise`
* `lib/webdriver.WebElementPromise`
* Removed `remote/index.DriverService.prototype.stop()` (use `#kill()` instead)

@@ -533,120 +552,123 @@ * Removed the `lib/actions` module

exported names (replacements, if any, in parentheses):
* CancellableThenable
* CancellationError
* ControlFlow
* Deferred
* LONG_STACK_TRACES
* MultipleUnhandledRejectionError
* Promise (use native Promises)
* Resolver
* Scheduler
* Thenable
* USE_PROMISE_MANAGER
* all (use Promise.all)
* asap (use Promise.resolve)
* captureStackTrace (use Error.captureStackTrace)
* consume (use async functions)
* controlFlow
* createPromise (use new Promise)
* defer
* fulfilled (use Promise.resolve)
* isGenerator
* rejected (use Promise.reject)
* setDefaultFlow
* when (use Promise.resolve)
* CancellableThenable
* CancellationError
* ControlFlow
* Deferred
* LONG_STACK_TRACES
* MultipleUnhandledRejectionError
* Promise (use native Promises)
* Resolver
* Scheduler
* Thenable
* USE_PROMISE_MANAGER
* all (use Promise.all)
* asap (use Promise.resolve)
* captureStackTrace (use Error.captureStackTrace)
* consume (use async functions)
* controlFlow
* createPromise (use new Promise)
* defer
* fulfilled (use Promise.resolve)
* isGenerator
* rejected (use Promise.reject)
* setDefaultFlow
* when (use Promise.resolve)
* Changes to the `Builder` class:
* Added setChromeService, setEdgeService, & setFirefoxService
* Removed setEnableNativeEvents
* Removed setScrollBehavior
* Added setChromeService, setEdgeService, & setFirefoxService
* Removed setEnableNativeEvents
* Removed setScrollBehavior
* Changes to `chrome.Driver`
* Added sendDevToolsCommand
* Added setDownloadPath
* Added sendDevToolsCommand
* Added setDownloadPath
* Changes to `chrome.Options`
* Now extends the `Capabilities` class
* Removed from/toCapabilities
* Now extends the `Capabilities` class
* Removed from/toCapabilities
* Changes to `edge.Options`
* Now extends the `Capabilities` class
* Removed from/toCapabilities
* Now extends the `Capabilities` class
* Removed from/toCapabilities
* Changes to `ie.Options`
* Now extends the `Capabilities` class
* Removed from/toCapabilities
* Removed the `firefox.Binary` class. Custom binaries can still be selected using `firefox.Options#setBinary()`. Likewise, custom binary arguments can be specified
* Now extends the `Capabilities` class
* Removed from/toCapabilities
* Removed the `firefox.Binary` class. Custom binaries can still be selected
using `firefox.Options#setBinary()`. Likewise, custom binary arguments can be specified
with `firefox.Options#addArguments()`.
* Changes to `firefox.Driver`
* Added installAddon(path)
* Added uninstallAddon(id)
* Added installAddon(path)
* Added uninstallAddon(id)
* Changes to `firefox.Options`
* Now extends the `Capabilities` class
* Removed from/toCapabilities
* Removed setLoggingPreferences (was a no-op)
* setProfile now only accepts a path to an existing profile
* Added addExtensions
* Added setPreference
* Removed the `firefox.Profile` class. All of its functionality is now provided directly by `firefox.Options`
* Now extends the `Capabilities` class
* Removed from/toCapabilities
* Removed setLoggingPreferences (was a no-op)
* setProfile now only accepts a path to an existing profile
* Added addExtensions
* Added setPreference
* Removed the `firefox.Profile` class. All of its functionality is now provided directly
by `firefox.Options`
* Removed the `firefox/binary` module
* Removed the `firefox/profile` module
* Changes to `safari.Options`
* Now extends the `Capabilities` class
* Removed from/toCapabilities
* Removed setCleanSession (was a no-op)
* Now extends the `Capabilities` class
* Removed from/toCapabilities
* Removed setCleanSession (was a no-op)
* Changes to `lib/capabilities.Browser`:
* Removed several enum values.
* ANDROID (use Chrome for Android; see docs on the chrome module)
* IPAD (no support available)
* IPHONE (no support available)
* OPERA (use Chrome)
* PHANTOM_JS (use Chrome or Firefox in headless mode)
* HTMLUNIT (use Chrome or Firefox in headless mode)
* Removed several enum values.
* ANDROID (use Chrome for Android; see docs on the chrome module)
* IPAD (no support available)
* IPHONE (no support available)
* OPERA (use Chrome)
* PHANTOM_JS (use Chrome or Firefox in headless mode)
* HTMLUNIT (use Chrome or Firefox in headless mode)
* Changes to `lib/capabilities.Capabilities`:
* Removed static factory methods android(), ipad(), iphone(), opera(), phantomjs(), htmlunit(),
and htmlunitwithjs(). Users can still manually configure capabilities for these, but their use
is not recommended and they will no longer be surfaced in the API.
* Removed static factory methods android(), ipad(), iphone(), opera(), phantomjs(), htmlunit(),
and htmlunitwithjs(). Users can still manually configure capabilities for these, but their use
is not recommended and they will no longer be surfaced in the API.
* Changes to `lib/error`:
* Added
* ElementClickInterceptedError
* InsecureCertificateError
* InvalidCoordinatesError
* NoSuchCookieError
* Removed
* ElementNotVisibleError
* InvalidElementCoordinatesError
* Added
* ElementClickInterceptedError
* InsecureCertificateError
* InvalidCoordinatesError
* NoSuchCookieError
* Removed
* ElementNotVisibleError
* InvalidElementCoordinatesError
* Changes to `lib/webdriver.WebDriver`:
* Dropped support for "requiredCapabilities" from WebDriver.createSession
* actions() now returns the new `lib/input.Actions` class
* Removed touchActions
* Renamed schedule to execute
* Removed the `WebDriver.attachToSession()` factory method. Users can just the `WebDriver`
constructor directly instead.
* Removed the `call()` method. This was used to inject custom function calls into the control
flow. Now that the promise manager is no longer used, this method is no longer necessary. Users are now responsible for coordinating actions (ideally with async functions) and can just
call functions directly instead of through `driver.call()`.
* Dropped support for "requiredCapabilities" from WebDriver.createSession
* actions() now returns the new `lib/input.Actions` class
* Removed touchActions
* Renamed schedule to execute
* Removed the `WebDriver.attachToSession()` factory method. Users can just the `WebDriver`
constructor directly instead.
* Removed the `call()` method. This was used to inject custom function calls into the control
flow. Now that the promise manager is no longer used, this method is no longer necessary.
Users are now responsible for coordinating actions (ideally with async functions) and can just
call functions directly instead of through `driver.call()`.
* Changes to `lib/webdriver.WebElement`:
* Replaced getSize & getLocation with getRect
* Replaced getSize & getLocation with getRect
* Changes to `lib/webdriver.Alert`:
* Removed authenticateAs
* Removed authenticateAs
* Changes to `lib/webdriver.Options` (`driver.manage()`):
* Removed timeouts (use get/setTimeouts)
* Removed timeouts (use get/setTimeouts)
* Changes to `lib/webdriver.Window` (`driver.manage().window()`):
* Added
* getRect
* setRect
* fullscreen
* minimize
* Removed (use the getRect/setRect methods)
* getPosition
* setPosition
* getSize
* setSize
* Added
* getRect
* setRect
* fullscreen
* minimize
* Removed (use the getRect/setRect methods)
* getPosition
* setPosition
* getSize
* setSize
* Removed the `testing/assert` module
* Changes to `testing/index`
* Since the promise manager has been removed, it is no longer necessary to wrap the Mocha test
hooks; instead, users can simply use async functions. The following have all been removed:
* describe
* before
* beforeEach
* after
* afterEach
* it
* Added the `suite` function. For details, refer to the jsdoc or
`example/google_search_test.js`
* Since the promise manager has been removed, it is no longer necessary to wrap the Mocha test
hooks; instead, users can simply use async functions. The following have all been removed:
* describe
* before
* beforeEach
* after
* afterEach
* it
* Added the `suite` function. For details, refer to the jsdoc or
`example/google_search_test.js`

@@ -667,5 +689,5 @@ ## v3.6.0

* Added new methods to `selenium-webdriver/firefox.Options`:
* addArguments()
* headless()
* windowSize()
* addArguments()
* headless()
* windowSize()
* Deprecated `selenium-webdriver/firefox/binary.Binary`

@@ -676,6 +698,6 @@ * Removed `selenium-webdriver/firefox.Options#useGeckoDriver()`

for the legacy FirefoxDriver was dropped in 3.5.0:
* setNativeEventsEnabled
* nativeEventsEnabled
* getPort
* setPort
* setNativeEventsEnabled
* nativeEventsEnabled
* getPort
* setPort
* Removed `selenium-webdriver/firefox.ServiceBuilder#setFirefoxBinary()`; custom binaries should be

@@ -702,7 +724,8 @@ configured through the `firefox.Options` class.

* Removed native support for Firefox 46 and older.
* The `SELENIUM_MARIONETTE` enviornment variable no longer has an effect.
* `selenium-webdriver/firefox.Capability.MARIONETTE` is deprecated.
* `selenium-webdriver/firefox.Options#useGeckoDriver()` is deprecated and now a no-op.
* The `SELENIUM_MARIONETTE` enviornment variable no longer has an effect.
* `selenium-webdriver/firefox.Capability.MARIONETTE` is deprecated.
* `selenium-webdriver/firefox.Options#useGeckoDriver()` is deprecated and now a no-op.
* `firefox.Options` will no longer discard the `"moz:firefoxOptions"` set in user provided
capabilities (via `Builder.withCapabilities({})`). When both are used, the settings in `firefox.Options` will be applied _last_.
capabilities (via `Builder.withCapabilities({})`). When both are used, the settings
in `firefox.Options` will be applied _last_.
* Added `chrome.Options#headless()` and `chrome.Options#windowSize()`, which may be used to start

@@ -721,3 +744,4 @@ Chrome in headless mode (requires Chrome 59+) and to set the initial window size, respectively.

This release requires [geckodriver 0.15.0](https://github.com/mozilla/geckodriver/releases/tag/v0.15.0) or newer.
This release
requires [geckodriver 0.15.0](https://github.com/mozilla/geckodriver/releases/tag/v0.15.0) or newer.

@@ -761,3 +785,4 @@ ### API Changes

* The `lib` package is once again platform agnostic (excluding `lib/devmode`).
* Deprecated `promise.when(value, callback, errback)`. Use `promise.fulfilled(value).then(callback, errback)`
* Deprecated `promise.when(value, callback, errback)`.
Use `promise.fulfilled(value).then(callback, errback)`
* Changed `promise.fulfilled(value)`, `promise.rejected(reason)` and

@@ -779,5 +804,6 @@ `promise.defer()` to all use native promises when the promise manager is disabled.

* More API adjustments to align with native Promises
* Deprecated `promise.fulfilled(value)`, use `promise.Promise#resolve(value)`
* Deprecated `promise.rejected(reason)`, use `promise.Promise#reject(reason)`
* When a `wait()` condition times out, the returned promise will now be rejected with an `error.TimeoutError` instead of a generic `Error` object.
* Deprecated `promise.fulfilled(value)`, use `promise.Promise#resolve(value)`
* Deprecated `promise.rejected(reason)`, use `promise.Promise#reject(reason)`
* When a `wait()` condition times out, the returned promise will now be rejected with
an `error.TimeoutError` instead of a generic `Error` object.
* `WebDriver#wait()` will now throw a TypeError if an invalid wait condition is provided.

@@ -809,3 +835,4 @@ * Properly catch unhandled promise rejections with an action sequence (only impacts when the promise

<https://github.com/SeleniumHQ/selenium/issues/2969>
* When communicating with a W3C-compliant remote end, use the atoms library for the `WebElement.getAttribute()` and `WebElement.isDisplayed()` commands. This behavior is
* When communicating with a W3C-compliant remote end, use the atoms library for
the `WebElement.getAttribute()` and `WebElement.isDisplayed()` commands. This behavior is
consistent with the java, .net, python, and ruby clients.

@@ -817,6 +844,7 @@

* Reduced the API on `promise.Thenable` for compatibility with native promises:
* Removed `#isPending()`
* Removed `#cancel()`
* Removed `#finally()`
* Changed all subclasses of `webdriver.WebDriver` to overload the static function `WebDriver.createSession()` instead of doing work in the constructor. All constructors
* Removed `#isPending()`
* Removed `#cancel()`
* Removed `#finally()`
* Changed all subclasses of `webdriver.WebDriver` to overload the static
function `WebDriver.createSession()` instead of doing work in the constructor. All constructors
now inherit the base class' function signature. Users are still encouraged to use the `Builder`

@@ -834,4 +862,6 @@ class instead of creating drivers directly.

unhandled promise rejection.
* Added the `firefox.ServiceBuilder` class, which may be used to customize the geckodriver used for `firefox.Driver` instances.
* Added support for Safari 10 safaridriver. safaridriver may be disabled via tha API, `safari.Options#useLegacyDriver`, to use the safari extension driver.
* Added the `firefox.ServiceBuilder` class, which may be used to customize the geckodriver used
for `firefox.Driver` instances.
* Added support for Safari 10 safaridriver. safaridriver may be disabled via tha
API, `safari.Options#useLegacyDriver`, to use the safari extension driver.
* Updated the `lib/proxy` module to support configuring a SOCKS proxy.

@@ -860,3 +890,4 @@ * For the `promise.ControlFlow`, fire the "uncaughtException" event in a new turn of the JS event

* Updated command mappings for [getting](https://w3c.github.io/webdriver/webdriver-spec.html#get-window-position)
* Updated command mappings
for [getting](https://w3c.github.io/webdriver/webdriver-spec.html#get-window-position)
and [setting](https://w3c.github.io/webdriver/webdriver-spec.html#set-window-position)

@@ -888,3 +919,4 @@ the window position.

instead of a `command.DeferredExecutor` when creating WebDriver instances.
* For Chrome and Firefox, the `builder.Builder` class will always return an instanceof `chrome.Driver` and `firefox.Driver`, respectively, even when configured to use a
* For Chrome and Firefox, the `builder.Builder` class will always return an
instanceof `chrome.Driver` and `firefox.Driver`, respectively, even when configured to use a
remote server (from `builder.Builder#usingServer(url)`,

@@ -902,28 +934,28 @@ `SELENIUM_REMOTE_URL`, etc).

* Removed deprecated modules:
* `selenium-webdriver/error` (use `selenium-webdriver/lib/error`,\
or the `error` property exported by `selenium-webdriver`)
* `selenium-webdriver/executors` — this was not previously deprecated, but is no longer used.
* `selenium-webdriver/error` (use `selenium-webdriver/lib/error`,\
or the `error` property exported by `selenium-webdriver`)
* `selenium-webdriver/executors` — this was not previously deprecated, but is no longer used.
* Removed deprecated types:
* `command.DeferredExecutor` — this was not previously deprecated, but is no longer used. It can
be trivially implemented by clients should it be needed.
* `error.InvalidSessionIdError` (use `error.NoSuchSessionError`)
* `executors.DeferredExecutor`
* `until.Condition` (use `webdriver.Condition`)
* `until.WebElementCondition` (use `webdriver.WebElementCondition`)
* `webdriver.UnhandledAlertError` (use `error.UnexpectedAlertOpenError`)
* `command.DeferredExecutor` — this was not previously deprecated, but is no longer used. It can
be trivially implemented by clients should it be needed.
* `error.InvalidSessionIdError` (use `error.NoSuchSessionError`)
* `executors.DeferredExecutor`
* `until.Condition` (use `webdriver.Condition`)
* `until.WebElementCondition` (use `webdriver.WebElementCondition`)
* `webdriver.UnhandledAlertError` (use `error.UnexpectedAlertOpenError`)
* Removed deprecated functions:
* `Deferred#cancel()`
* `Deferred#catch()`
* `Deferred#finally()`
* `Deferred#isPending()`
* `Deferred#then()`
* `Promise#thenCatch()`
* `Promise#thenFinally()`
* `WebDriver#isElementPresent()`
* `WebElement#getInnerHtml()`
* `WebElement#getOuterHtml()`
* `WebElement#getRawId()`
* `WebElement#isElementPresent()`
* `Deferred#cancel()`
* `Deferred#catch()`
* `Deferred#finally()`
* `Deferred#isPending()`
* `Deferred#then()`
* `Promise#thenCatch()`
* `Promise#thenFinally()`
* `WebDriver#isElementPresent()`
* `WebElement#getInnerHtml()`
* `WebElement#getOuterHtml()`
* `WebElement#getRawId()`
* `WebElement#isElementPresent()`
* Removed deprecated properties:
* `WebDriverError#code`
* `WebDriverError#code`

@@ -952,3 +984,4 @@ ## v2.53.2

environment variable.
* Moved all logic for parsing and interpreting responses from the remote end into the individual `command.Executor` implementations.
* Moved all logic for parsing and interpreting responses from the remote end into the
individual `command.Executor` implementations.
* For consistency with the other Selenium language bindings,

@@ -975,3 +1008,4 @@ `WebDriver#isElementPresent()` and `WebElement#isElementPresent()` have been deprecated. These

* FIXED: `phantomjs.Driver` now takes a third argument that defines the path to a log file to use
for the phantomjs executable's output. This may be quickly set at runtime with the `SELENIUM_PHANTOMJS_LOG` environment variable.
for the phantomjs executable's output. This may be quickly set at runtime with
the `SELENIUM_PHANTOMJS_LOG` environment variable.

@@ -1014,4 +1048,6 @@ ### Changes for W3C WebDriver Spec Compliance

`lib/command.DeferredExecutor`.
* API documentation is no longer distributed with the npm package, but remains available at <http://seleniumhq.github.io/selenium/docs/api/javascript/>
* Rewrote the `error` module to export an Error subtype for each type of error defined in the [W3C WebDriver spec](https://w3c.github.io/webdriver/webdriver-spec.html#handling-errors).
* API documentation is no longer distributed with the npm package, but remains available
at <http://seleniumhq.github.io/selenium/docs/api/javascript/>
* Rewrote the `error` module to export an Error subtype for each type of error defined in
the [W3C WebDriver spec](https://w3c.github.io/webdriver/webdriver-spec.html#handling-errors).
* Changed the `http.Request` and `http.Response` classes to store headers in maps instead of object

@@ -1029,3 +1065,4 @@ literals.

* Updated the `By` locators that are not in the W3C spec to delegated to using CSS selectors: `By.className`, `By.id`, `By.name`, and `By.tagName`.
* Updated the `By` locators that are not in the W3C spec to delegated to using CSS
selectors: `By.className`, `By.id`, `By.name`, and `By.tagName`.

@@ -1054,3 +1091,4 @@ ## v2.49-51

* FIXED: the `webdriver.promise.ControlFlow` now has a consistent execution order for
tasks/callbacks scheduled in different turns of the JS event loop. Refer to the `webdriver.promise` documentation for more details.
tasks/callbacks scheduled in different turns of the JS event loop. Refer to
the `webdriver.promise` documentation for more details.
* FIXED: do not drop user auth from the WebDriver server URL.

@@ -1085,3 +1123,3 @@ * FIXED: a single `firefox.Binary` instance may be used to configure and launch multiple

* Add support for [Node v4.0.0](https://nodejs.org/en/blog/release/v4.0.0/)
* Updated `ws` dependency from `0.7.1` to `0.8.0`
* Updated `ws` dependency from `0.7.1` to `0.8.0`
* Bumped the minimum supported version of Node from `0.10.x` to `0.12.x`. This is in accordance with

@@ -1103,10 +1141,10 @@ the Node support policy established in `v2.45.0`.

* Removed deprecated functions:
* Capabilities#toJSON()
* UnhandledAlertError#getAlert()
* chrome.createDriver()
* phantomjs.createDriver()
* promise.ControlFlow#annotateError()
* promise.ControlFlow#await()
* promise.ControlFlow#clearHistory()
* promise.ControlFlow#getHistory()
* Capabilities#toJSON()
* UnhandledAlertError#getAlert()
* chrome.createDriver()
* phantomjs.createDriver()
* promise.ControlFlow#annotateError()
* promise.ControlFlow#await()
* promise.ControlFlow#clearHistory()
* promise.ControlFlow#getHistory()
* Removed deprecated enum values: `ErrorCode.NO_MODAL_DIALOG_OPEN` and

@@ -1135,3 +1173,4 @@ `ErrorCode.MODAL_DIALOG_OPENED`. Use `ErrorCode.NO_SUCH_ALERT` and

* FIXED: 8496: Extended the `chrome.Options` API to cover all configuration options (e.g. mobile
emulation and performance logging) documented on the ChromeDriver [project site](https://chromedriver.chromium.org/capabilities).
emulation and performance logging) documented on the
ChromeDriver [project site](https://chromedriver.chromium.org/capabilities).

@@ -1211,3 +1250,4 @@ ## v2.45.0

* FIXED: 8306: Stack overflow in promise callbacks eliminated.
* FIXED: 8221: Added support for defining custom command mappings. Includes support for PhantomJS's `executePhantomJS` (requires PhantomJS 1.9.7 or GhostDriver 1.1.0).
* FIXED: 8221: Added support for defining custom command mappings. Includes support for
PhantomJS's `executePhantomJS` (requires PhantomJS 1.9.7 or GhostDriver 1.1.0).
* FIXED: 8128: When the FirefoxDriver marshals an object to the page for

@@ -1415,10 +1455,10 @@ `executeScript`, it defines additional properties (required by the driver's implementation). These

* Removed deprecated functions originally scheduled for removal in 2.31.0
* promise.Application.getInstance()
* promise.ControlFlow#schedule()
* promise.ControlFlow#scheduleTimeout()
* promise.ControlFlow#scheduleWait()
* promise.Application.getInstance()
* promise.ControlFlow#schedule()
* promise.ControlFlow#scheduleTimeout()
* promise.ControlFlow#scheduleWait()
* Renamed some functions for consistency with Promises/A+ terminology. The original functions have
been deprecated and will be removed in 2.34.0:
* promise.resolved() -> promise.fulfilled()
* promise.Deferred#resolve() -> promise.Deferred#fulfill()
* promise.resolved() -> promise.fulfilled()
* promise.Deferred#resolve() -> promise.Deferred#fulfill()
* FIXED: remote.SeleniumServer#stop now shuts down within the active control flow, allowing scripts

@@ -1425,0 +1465,0 @@ to finish. Use #kill to shutdown immediately.

@@ -217,10 +217,3 @@ // Licensed to the Software Freedom Conservancy (SFC) under one

let caps = opt_config || new Options()
return /** @type {!Driver} */ (
super.createSession(
caps,
opt_serviceExecutor,
'goog',
CHROME_CAPABILITY_KEY
)
)
return /** @type {!Driver} */ (super.createSession(caps, opt_serviceExecutor, 'goog', CHROME_CAPABILITY_KEY))
}

@@ -227,0 +220,0 @@

@@ -122,46 +122,18 @@ // Licensed to the Software Freedom Conservancy (SFC) under one

function configureExecutor(executor, vendorPrefix) {
executor.defineCommand(Command.LAUNCH_APP, 'POST', '/session/:sessionId/chromium/launch_app')
executor.defineCommand(Command.GET_NETWORK_CONDITIONS, 'GET', '/session/:sessionId/chromium/network_conditions')
executor.defineCommand(Command.SET_NETWORK_CONDITIONS, 'POST', '/session/:sessionId/chromium/network_conditions')
executor.defineCommand(Command.DELETE_NETWORK_CONDITIONS, 'DELETE', '/session/:sessionId/chromium/network_conditions')
executor.defineCommand(Command.SEND_DEVTOOLS_COMMAND, 'POST', '/session/:sessionId/chromium/send_command')
executor.defineCommand(
Command.LAUNCH_APP,
'POST',
'/session/:sessionId/chromium/launch_app'
)
executor.defineCommand(
Command.GET_NETWORK_CONDITIONS,
'GET',
'/session/:sessionId/chromium/network_conditions'
)
executor.defineCommand(
Command.SET_NETWORK_CONDITIONS,
'POST',
'/session/:sessionId/chromium/network_conditions'
)
executor.defineCommand(
Command.DELETE_NETWORK_CONDITIONS,
'DELETE',
'/session/:sessionId/chromium/network_conditions'
)
executor.defineCommand(
Command.SEND_DEVTOOLS_COMMAND,
'POST',
'/session/:sessionId/chromium/send_command'
)
executor.defineCommand(
Command.SEND_AND_GET_DEVTOOLS_COMMAND,
'POST',
'/session/:sessionId/chromium/send_command_and_get_result'
'/session/:sessionId/chromium/send_command_and_get_result',
)
executor.defineCommand(Command.SET_PERMISSION, 'POST', '/session/:sessionId/permissions')
executor.defineCommand(Command.GET_CAST_SINKS, 'GET', `/session/:sessionId/${vendorPrefix}/cast/get_sinks`)
executor.defineCommand(
Command.SET_PERMISSION,
'POST',
'/session/:sessionId/permissions'
)
executor.defineCommand(
Command.GET_CAST_SINKS,
'GET',
`/session/:sessionId/${vendorPrefix}/cast/get_sinks`
)
executor.defineCommand(
Command.SET_CAST_SINK_TO_USE,
'POST',
`/session/:sessionId/${vendorPrefix}/cast/set_sink_to_use`
`/session/:sessionId/${vendorPrefix}/cast/set_sink_to_use`,
)

@@ -171,3 +143,3 @@ executor.defineCommand(

'POST',
`/session/:sessionId/${vendorPrefix}/cast/start_desktop_mirroring`
`/session/:sessionId/${vendorPrefix}/cast/start_desktop_mirroring`,
)

@@ -177,3 +149,3 @@ executor.defineCommand(

'POST',
`/session/:sessionId/${vendorPrefix}/cast/start_tab_mirroring`
`/session/:sessionId/${vendorPrefix}/cast/start_tab_mirroring`,
)

@@ -183,9 +155,5 @@ executor.defineCommand(

'GET',
`/session/:sessionId/${vendorPrefix}/cast/get_issue_message`
`/session/:sessionId/${vendorPrefix}/cast/get_issue_message`,
)
executor.defineCommand(
Command.STOP_CASTING,
'POST',
`/session/:sessionId/${vendorPrefix}/cast/stop_casting`
)
executor.defineCommand(Command.STOP_CASTING, 'POST', `/session/:sessionId/${vendorPrefix}/cast/stop_casting`)
}

@@ -629,5 +597,3 @@

}
return io
.read(/** @type {string} */ (extension))
.then((buffer) => buffer.toString('base64'))
return io.read(/** @type {string} */ (extension)).then((buffer) => buffer.toString('base64'))
})

@@ -654,8 +620,3 @@ }

*/
static createSession(
caps,
opt_serviceExecutor,
vendorPrefix = '',
vendorCapabilityKey = ''
) {
static createSession(caps, opt_serviceExecutor, vendorPrefix = '', vendorCapabilityKey = '') {
let executor

@@ -710,5 +671,3 @@ let onQuit

launchApp(id) {
return this.execute(
new command.Command(Command.LAUNCH_APP).setParameter('id', id)
)
return this.execute(new command.Command(Command.LAUNCH_APP).setParameter('id', id))
}

@@ -752,12 +711,5 @@

if (!spec || typeof spec !== 'object') {
throw TypeError(
'setNetworkConditions called with non-network-conditions parameter'
)
throw TypeError('setNetworkConditions called with non-network-conditions parameter')
}
return this.execute(
new command.Command(Command.SET_NETWORK_CONDITIONS).setParameter(
'network_conditions',
spec
)
)
return this.execute(new command.Command(Command.SET_NETWORK_CONDITIONS).setParameter('network_conditions', spec))
}

@@ -776,5 +728,3 @@

return this.execute(
new command.Command(Command.SEND_DEVTOOLS_COMMAND)
.setParameter('cmd', cmd)
.setParameter('params', params)
new command.Command(Command.SEND_DEVTOOLS_COMMAND).setParameter('cmd', cmd).setParameter('params', params),
)

@@ -796,3 +746,3 @@ }

.setParameter('cmd', cmd)
.setParameter('params', params)
.setParameter('params', params),
)

@@ -813,5 +763,3 @@ }

return this.execute(
new command.Command(Command.SET_PERMISSION)
.setParameter('descriptor', { name })
.setParameter('state', state)
new command.Command(Command.SET_PERMISSION).setParameter('descriptor', { name }).setParameter('state', state),
)

@@ -849,6 +797,3 @@ }

getCastSinks() {
return this.schedule(
new command.Command(Command.GET_CAST_SINKS),
'Driver.getCastSinks()'
)
return this.execute(new command.Command(Command.GET_CAST_SINKS))
}

@@ -864,9 +809,3 @@

setCastSinkToUse(deviceName) {
return this.schedule(
new command.Command(Command.SET_CAST_SINK_TO_USE).setParameter(
'sinkName',
deviceName
),
'Driver.setCastSinkToUse(' + deviceName + ')'
)
return this.execute(new command.Command(Command.SET_CAST_SINK_TO_USE).setParameter('sinkName', deviceName))
}

@@ -882,9 +821,3 @@

startDesktopMirroring(deviceName) {
return this.schedule(
new command.Command(Command.START_CAST_DESKTOP_MIRRORING).setParameter(
'sinkName',
deviceName
),
'Driver.startDesktopMirroring(' + deviceName + ')'
)
return this.execute(new command.Command(Command.START_CAST_DESKTOP_MIRRORING).setParameter('sinkName', deviceName))
}

@@ -900,9 +833,3 @@

startCastTabMirroring(deviceName) {
return this.schedule(
new command.Command(Command.START_CAST_TAB_MIRRORING).setParameter(
'sinkName',
deviceName
),
'Driver.startCastTabMirroring(' + deviceName + ')'
)
return this.execute(new command.Command(Command.START_CAST_TAB_MIRRORING).setParameter('sinkName', deviceName))
}

@@ -916,6 +843,3 @@

getCastIssueMessage() {
return this.schedule(
new command.Command(Command.GET_CAST_ISSUE_MESSAGE),
'Driver.getCastIssueMessage()'
)
return this.execute(new command.Command(Command.GET_CAST_ISSUE_MESSAGE))
}

@@ -931,9 +855,3 @@

stopCasting(deviceName) {
return this.schedule(
new command.Command(Command.STOP_CASTING).setParameter(
'sinkName',
deviceName
),
'Driver.stopCasting(' + deviceName + ')'
)
return this.execute(new command.Command(Command.STOP_CASTING).setParameter('sinkName', deviceName))
}

@@ -940,0 +858,0 @@ }

@@ -38,3 +38,3 @@ // Licensed to the Software Freedom Conservancy (SFC) under one

For more information on how to install drivers see
https://www.selenium.dev/documentation/webdriver/troubleshooting/errors/driver_location/. ${e}`
https://www.selenium.dev/documentation/webdriver/troubleshooting/errors/driver_location/. ${e}`,
)

@@ -41,0 +41,0 @@ }

@@ -38,3 +38,3 @@ // Licensed to the Software Freedom Conservancy (SFC) under one

*/
function getBinary () {
function getBinary() {
const directory = {

@@ -47,9 +47,7 @@ darwin: 'macos',

const file =
directory === 'windows' ? 'selenium-manager.exe' : 'selenium-manager'
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)
const filePath = process.env.SE_MANAGER_PATH || path.join(seleniumManagerBasePath, directory, file)

@@ -75,5 +73,4 @@ if (!fs.existsSync(filePath)) {

function driverLocation (options) {
let args = ['--browser', options.getBrowserName(), '--language-binding',
'javascript', '--output', 'json']
function driverLocation(options) {
let args = ['--browser', options.getBrowserName(), '--language-binding', 'javascript', '--output', 'json']

@@ -85,5 +82,3 @@ if (options.getBrowserVersion() && options.getBrowserVersion() !== '') {

const vendorOptions =
options.get('goog:chromeOptions') ||
options.get('ms:edgeOptions') ||
options.get('moz:firefoxOptions')
options.get('goog:chromeOptions') || options.get('ms:edgeOptions') || options.get('moz:firefoxOptions')
if (vendorOptions && vendorOptions.binary && vendorOptions.binary !== '') {

@@ -124,5 +119,3 @@ args.push('--browser-path', path.resolve(vendorOptions.binary))

}
throw new Error(
`Error executing command for ${smBinary} with ${args}: ${errorMessage}`
)
throw new Error(`Error executing command for ${smBinary} with ${args}: ${errorMessage}`)
}

@@ -132,5 +125,3 @@ try {

} catch (e) {
throw new Error(
`Error executing command for ${smBinary} with ${args}: ${e.toString()}`
)
throw new Error(`Error executing command for ${smBinary} with ${args}: ${e.toString()}`)
}

@@ -150,3 +141,3 @@

function logOutput (output) {
function logOutput(output) {
for (const key in output.logs) {

@@ -153,0 +144,0 @@ if (output.logs[key].level === 'WARN') {

@@ -70,5 +70,3 @@ // Licensed to the Software Freedom Conservancy (SFC) under one

} catch (err) {
logging
.getLogger(logging.Type.BROWSER)
.severe(`Failed parse message: ${err.message}`)
logging.getLogger(logging.Type.BROWSER).severe(`Failed parse message: ${err.message}`)
}

@@ -75,0 +73,0 @@ }

@@ -150,5 +150,3 @@ // Licensed to the Software Freedom Conservancy (SFC) under one

let caps = opt_config || new Options()
return /** @type {!Driver} */ (
super.createSession(caps, opt_serviceExecutor, 'ms', EDGE_CAPABILITY_KEY)
)
return /** @type {!Driver} */ (super.createSession(caps, opt_serviceExecutor, 'ms', EDGE_CAPABILITY_KEY))
}

@@ -155,0 +153,0 @@

@@ -32,6 +32,3 @@ // Licensed to the Software Freedom Conservancy (SFC) under one

try {
driver = await new Builder()
.forBrowser('chrome')
.setChromeOptions(new Options().androidChrome())
.build()
driver = await new Builder().forBrowser('chrome').setChromeOptions(new Options().androidChrome()).build()
await driver.get('http://www.google.com/ncr')

@@ -45,3 +42,3 @@ await driver.findElement(By.name('q')).sendKeys('webdriver', Key.RETURN)

(_) => console.log('SUCCESS'),
(err) => console.error('ERROR: ' + err)
(err) => console.error('ERROR: ' + err),
)

@@ -33,5 +33,3 @@ // Licensed to the Software Freedom Conservancy (SFC) under one

.forBrowser('chrome')
.setChromeOptions(
new Options().setMobileEmulation({ deviceName: 'Nexus 5X' })
)
.setChromeOptions(new Options().setMobileEmulation({ deviceName: 'Nexus 5X' }))
.build()

@@ -46,3 +44,3 @@ await driver.get('http://www.google.com/ncr')

(_) => console.log('SUCCESS'),
(err) => console.error('ERROR: ' + err)
(err) => console.error('ERROR: ' + err),
)

@@ -46,6 +46,4 @@ // Licensed to the Software Freedom Conservancy (SFC) under one

.get('http://www.google.com/ncr')
.then((_) =>
driver.findElement(By.name('q')).sendKeys('webdriver', Key.RETURN)
)
.then((_) => driver.findElement(By.name('q')).sendKeys('webdriver', Key.RETURN))
.then((_) => driver.wait(until.titleIs('webdriver - Google Search'), 1000))
.then((_) => driver.quit())

@@ -43,8 +43,4 @@ // Licensed to the Software Freedom Conservancy (SFC) under one

.forBrowser('chrome')
.setChromeOptions(
new chrome.Options().addArguments('-headless').windowSize({ width, height })
)
.setFirefoxOptions(
new firefox.Options().addArguments('-headless').windowSize({ width, height })
)
.setChromeOptions(new chrome.Options().addArguments('-headless').windowSize({ width, height }))
.setFirefoxOptions(new firefox.Options().addArguments('-headless').windowSize({ width, height }))
.build()

@@ -54,5 +50,3 @@

.get('http://www.google.com/ncr')
.then((_) =>
driver.findElement(By.name('q')).sendKeys('webdriver', Key.RETURN)
)
.then((_) => driver.findElement(By.name('q')).sendKeys('webdriver', Key.RETURN))
.then((_) => driver.wait(until.titleIs('webdriver - Google Search'), 1000))

@@ -64,3 +58,3 @@ .then(

throw e
})
}),
)

@@ -43,13 +43,7 @@ // Licensed to the Software Freedom Conservancy (SFC) under one

// will only start the service if needed for the selected browser.
.setChromeService(
new chrome.ServiceBuilder().enableVerboseLogging().setStdio('inherit')
)
.setChromeService(new chrome.ServiceBuilder().enableVerboseLogging().setStdio('inherit'))
.setEdgeService(
process.platform === 'win32'
? new edge.ServiceBuilder().enableVerboseLogging().setStdio('inherit')
: null
process.platform === 'win32' ? new edge.ServiceBuilder().enableVerboseLogging().setStdio('inherit') : null,
)
.setFirefoxService(
new firefox.ServiceBuilder().enableVerboseLogging().setStdio('inherit')
)
.setFirefoxService(new firefox.ServiceBuilder().enableVerboseLogging().setStdio('inherit'))
.build()

@@ -56,0 +50,0 @@

@@ -130,3 +130,3 @@ // Licensed to the Software Freedom Conservancy (SFC) under one

/** @param {string} msg The error message. */
constructor (msg) {
constructor(msg) {
super(msg)

@@ -145,3 +145,3 @@ /** @override */

*/
async function installExtension (extension, dir) {
async function installExtension(extension, dir) {
const ext = extension.slice(-4)

@@ -184,3 +184,3 @@ if (ext !== '.xpi' && ext !== '.zip') {

class Profile {
constructor () {
constructor() {
/** @private {?string} */

@@ -193,3 +193,3 @@ this.template_ = null

addExtensions (/** !Array<string> */ paths) {
addExtensions(/** !Array<string> */ paths) {
this.extensions_ = this.extensions_.concat(...paths)

@@ -202,3 +202,3 @@ }

*/
[Symbols.serialize] () {
[Symbols.serialize]() {
if (this.template_ || this.extensions_.length) {

@@ -217,3 +217,3 @@ return buildProfile(this.template_, this.extensions_)

*/
async function buildProfile (template, extensions) {
async function buildProfile(template, extensions) {
let dir = template

@@ -224,7 +224,3 @@

if (template) {
await io.copyDir(
/** @type {string} */ (template),
dir,
/(parent\.lock|lock|\.parentlock)/
)
await io.copyDir(/** @type {string} */ (template), dir, /(parent\.lock|lock|\.parentlock)/)
}

@@ -255,3 +251,3 @@

*/
constructor (other) {
constructor(other) {
super(other)

@@ -265,3 +261,3 @@ this.setBrowserName(Browser.FIREFOX)

*/
firefoxOptions_ () {
firefoxOptions_() {
let options = this.get(FIREFOX_CAPABILITY_KEY)

@@ -279,3 +275,3 @@ if (!options) {

*/
profile_ () {
profile_() {
let options = this.firefoxOptions_()

@@ -295,3 +291,3 @@ if (!options.profile) {

*/
addArguments (...args) {
addArguments(...args) {
if (args.length) {

@@ -312,4 +308,4 @@ let options = this.firefoxOptions_()

*/
windowSize ({ width, height }) {
function checkArg (arg) {
windowSize({ width, height }) {
function checkArg(arg) {
if (typeof arg !== 'number' || arg <= 0) {

@@ -331,3 +327,3 @@ throw TypeError('Arguments must be {width, height} with numbers > 0')

*/
addExtensions (...paths) {
addExtensions(...paths) {
this.profile_().addExtensions(paths)

@@ -343,14 +339,8 @@ return this

*/
setPreference (key, value) {
setPreference(key, value) {
if (typeof key !== 'string') {
throw TypeError(`key must be a string, but got ${typeof key}`)
}
if (
typeof value !== 'string' &&
typeof value !== 'number' &&
typeof value !== 'boolean'
) {
throw TypeError(
`value must be a string, number, or boolean, but got ${typeof value}`
)
if (typeof value !== 'string' && typeof value !== 'number' && typeof value !== 'boolean') {
throw TypeError(`value must be a string, number, or boolean, but got ${typeof value}`)
}

@@ -372,3 +362,3 @@ let options = this.firefoxOptions_()

*/
setProfile (profile) {
setProfile(profile) {
if (typeof profile !== 'string') {

@@ -389,3 +379,3 @@ throw TypeError(`profile must be a string, but got ${typeof profile}`)

*/
setBinary (binary) {
setBinary(binary) {
if (binary instanceof Channel || typeof binary === 'string') {

@@ -404,7 +394,3 @@ this.firefoxOptions_().binary = binary

*/
enableMobile (
androidPackage = 'org.mozilla.firefox',
androidActivity = null,
deviceSerial = null
) {
enableMobile(androidPackage = 'org.mozilla.firefox', androidActivity = null, deviceSerial = null) {
this.firefoxOptions_().androidPackage = androidPackage

@@ -424,3 +410,3 @@

*/
enableDebugger () {
enableDebugger() {
return this.set('moz:debuggerAddress', true)

@@ -433,3 +419,3 @@ }

*/
enableBidi () {
enableBidi() {
return this.set('webSocketUrl', true)

@@ -460,3 +446,3 @@ }

*/
function findInProgramFiles (file) {
function findInProgramFiles(file) {
let files = [

@@ -470,4 +456,4 @@ process.env['PROGRAMFILES'] || 'C:\\Program Files',

: io.exists(files[1]).then(function (exists) {
return exists ? files[1] : null
})
return exists ? files[1] : null
})
})

@@ -489,3 +475,3 @@ }

*/
function createExecutor (serverUrl) {
function createExecutor(serverUrl) {
let client = serverUrl.then((url) => new http.HttpClient(url))

@@ -501,26 +487,10 @@ let executor = new http.Executor(client)

*/
function configureExecutor (executor) {
executor.defineCommand(
ExtensionCommand.GET_CONTEXT,
'GET',
'/session/:sessionId/moz/context'
)
function configureExecutor(executor) {
executor.defineCommand(ExtensionCommand.GET_CONTEXT, 'GET', '/session/:sessionId/moz/context')
executor.defineCommand(
ExtensionCommand.SET_CONTEXT,
'POST',
'/session/:sessionId/moz/context'
)
executor.defineCommand(ExtensionCommand.SET_CONTEXT, 'POST', '/session/:sessionId/moz/context')
executor.defineCommand(
ExtensionCommand.INSTALL_ADDON,
'POST',
'/session/:sessionId/moz/addon/install'
)
executor.defineCommand(ExtensionCommand.INSTALL_ADDON, 'POST', '/session/:sessionId/moz/addon/install')
executor.defineCommand(
ExtensionCommand.UNINSTALL_ADDON,
'POST',
'/session/:sessionId/moz/addon/uninstall'
)
executor.defineCommand(ExtensionCommand.UNINSTALL_ADDON, 'POST', '/session/:sessionId/moz/addon/uninstall')
}

@@ -538,3 +508,3 @@

*/
constructor (opt_exe) {
constructor(opt_exe) {
super(opt_exe)

@@ -551,3 +521,3 @@ this.setLoopback(true) // Required.

*/
enableVerboseLogging (opt_trace) {
enableVerboseLogging(opt_trace) {
return this.addArguments(opt_trace ? '-vv' : '-v')

@@ -583,5 +553,4 @@ }

*/
static createSession (opt_config, opt_executor) {
let caps =
opt_config instanceof Capabilities ? opt_config : new Options(opt_config)
static createSession(opt_config, opt_executor) {
let caps = opt_config instanceof Capabilities ? opt_config : new Options(opt_config)

@@ -633,3 +602,3 @@ let firefoxBrowserPath = null

*/
setFileDetector () {}
setFileDetector() {}

@@ -641,3 +610,3 @@ /**

*/
getContext () {
getContext() {
return this.execute(new command.Command(ExtensionCommand.GET_CONTEXT))

@@ -660,9 +629,4 @@ }

*/
setContext (ctx) {
return this.execute(
new command.Command(ExtensionCommand.SET_CONTEXT).setParameter(
'context',
ctx
)
)
setContext(ctx) {
return this.execute(new command.Command(ExtensionCommand.SET_CONTEXT).setParameter('context', ctx))
}

@@ -684,3 +648,3 @@

*/
async installAddon (path, temporary = false) {
async installAddon(path, temporary = false) {
let stats = fs.statSync(path)

@@ -698,3 +662,3 @@ let buf

.setParameter('addon', buf.toString('base64'))
.setParameter('temporary', temporary)
.setParameter('temporary', temporary),
)

@@ -711,10 +675,5 @@ }

*/
async uninstallAddon (id) {
async uninstallAddon(id) {
id = await Promise.resolve(id)
return this.execute(
new command.Command(ExtensionCommand.UNINSTALL_ADDON).setParameter(
'id',
id
)
)
return this.execute(new command.Command(ExtensionCommand.UNINSTALL_ADDON).setParameter('id', id))
}

@@ -737,3 +696,3 @@ }

*/
constructor (darwin, win32) {
constructor(darwin, win32) {
/** @private @const */ this.darwin_ = darwin

@@ -754,3 +713,3 @@ /** @private @const */ this.win32_ = win32

*/
locate () {
locate() {
if (this.found_) {

@@ -763,11 +722,7 @@ return this.found_

case 'darwin':
found = io
.exists(this.darwin_)
.then((exists) => (exists ? this.darwin_ : io.findInPath('firefox')))
found = io.exists(this.darwin_).then((exists) => (exists ? this.darwin_ : io.findInPath('firefox')))
break
case 'win32':
found = findInProgramFiles(this.win32_).then(
(found) => found || io.findInPath('firefox.exe')
)
found = findInProgramFiles(this.win32_).then((found) => found || io.findInPath('firefox.exe'))
break

@@ -791,3 +746,3 @@

/** @return {!Promise<string>} */
[Symbols.serialize] () {
[Symbols.serialize]() {
return this.locate()

@@ -804,3 +759,3 @@ }

'/Applications/Firefox Developer Edition.app/Contents/MacOS/firefox',
'Firefox Developer Edition\\firefox.exe'
'Firefox Developer Edition\\firefox.exe',
)

@@ -815,6 +770,3 @@

*/
Channel.BETA = new Channel(
'/Applications/Firefox.app/Contents/MacOS/firefox',
'Mozilla Firefox\\firefox.exe'
)
Channel.BETA = new Channel('/Applications/Firefox.app/Contents/MacOS/firefox', 'Mozilla Firefox\\firefox.exe')

@@ -826,6 +778,3 @@ /**

*/
Channel.RELEASE = new Channel(
'/Applications/Firefox.app/Contents/MacOS/firefox',
'Mozilla Firefox\\firefox.exe'
)
Channel.RELEASE = new Channel('/Applications/Firefox.app/Contents/MacOS/firefox', 'Mozilla Firefox\\firefox.exe')

@@ -837,6 +786,3 @@ /**

*/
Channel.NIGHTLY = new Channel(
'/Applications/Firefox Nightly.app/Contents/MacOS/firefox',
'Nightly\\firefox.exe'
)
Channel.NIGHTLY = new Channel('/Applications/Firefox Nightly.app/Contents/MacOS/firefox', 'Nightly\\firefox.exe')

@@ -843,0 +789,0 @@ // PUBLIC API

@@ -57,4 +57,3 @@ // 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

@@ -66,4 +65,3 @@ }

const version = require('../package.json').version
const platform =
{ darwin: 'mac', win32: 'windows' }[process.platform] || 'linux'
const platform = { darwin: 'mac', win32: 'windows' }[process.platform] || 'linux'
return `selenium/${version} (js ${platform})`

@@ -216,4 +214,3 @@ })()

if (proxy.auth) {
options.headers['Proxy-Authorization'] =
'Basic ' + Buffer.from(proxy.auth).toString('base64')
options.headers['Proxy-Authorization'] = 'Basic ' + Buffer.from(proxy.auth).toString('base64')
}

@@ -235,4 +232,4 @@ }

'\nResponse was: \n' +
new httpLib.Response(response.statusCode, response.headers, '')
)
new httpLib.Response(response.statusCode, response.headers, ''),
),
)

@@ -268,3 +265,3 @@ return

undefined,
opt_proxy
opt_proxy,
)

@@ -280,3 +277,3 @@ return

/** @type {!Object<string>} */ (response.headers),
Buffer.concat(body).toString('utf8').replace(/\0/g, '')
Buffer.concat(body).toString('utf8').replace(/\0/g, ''),
)

@@ -283,0 +280,0 @@ onOk(resp)

@@ -227,5 +227,3 @@ // Licensed to the Software Freedom Conservancy (SFC) under one

if (typeof current == 'string') current = current.split(' ')
this.options_[Key.BROWSER_COMMAND_LINE_SWITCHES] = current
.concat(args)
.join(' ')
this.options_[Key.BROWSER_COMMAND_LINE_SWITCHES] = current.concat(args).join(' ')
return this

@@ -246,5 +244,3 @@ }

if (typeof current == 'string') current = current.split(' ')
this.options_[Key.BROWSER_COMMAND_LINE_SWITCHES] = current
.concat(args)
.join(' ')
this.options_[Key.BROWSER_COMMAND_LINE_SWITCHES] = current.concat(args).join(' ')
return this

@@ -369,7 +365,3 @@ }

setScrollBehavior(behavior) {
if (
behavior &&
behavior !== SCROLL_BEHAVIOUR.TOP &&
behavior !== SCROLL_BEHAVIOUR.BOTTOM
) {
if (behavior && behavior !== SCROLL_BEHAVIOUR.TOP && behavior !== SCROLL_BEHAVIOUR.BOTTOM) {
throw new error.InvalidArgumentError(`Element Scroll Behavior out of range.

@@ -389,3 +381,3 @@ It should be either ${SCROLL_BEHAVIOUR.TOP} or ${SCROLL_BEHAVIOUR.BOTTOM}`)

'. Did you mean to run against a remote ' +
'WebDriver server?'
'WebDriver server?',
)

@@ -468,5 +460,3 @@ }

return /** @type {!Driver} */ (
super.createSession(executor, options, () => service.kill())
)
return /** @type {!Driver} */ (super.createSession(executor, options, () => service.kill()))
}

@@ -473,0 +463,0 @@

@@ -601,4 +601,3 @@ // Licensed to the Software Freedom Conservancy (SFC) under one

throw TypeError(
`Target browser must be a string, but is <${typeof browser}>;` +
' did you forget to call forBrowser()?'
`Target browser must be a string, but is <${typeof browser}>;` + ' did you forget to call forBrowser()?',
)

@@ -624,20 +623,5 @@ }

checkOptions(
capabilities,
'chromeOptions',
chrome.Options,
'setChromeOptions'
)
checkOptions(
capabilities,
'moz:firefoxOptions',
firefox.Options,
'setFirefoxOptions'
)
checkOptions(
capabilities,
'safari.options',
safari.Options,
'setSafariOptions'
)
checkOptions(capabilities, 'chromeOptions', chrome.Options, 'setChromeOptions')
checkOptions(capabilities, 'moz:firefoxOptions', firefox.Options, 'setFirefoxOptions')
checkOptions(capabilities, 'safari.options', safari.Options, 'setSafariOptions')

@@ -658,5 +642,3 @@ // Check for a remote browser.

this.log_.fine('Creating session on remote server')
let client = Promise.resolve(url).then(
(url) => new _http.HttpClient(url, this.agent_, this.proxy_)
)
let client = Promise.resolve(url).then((url) => new _http.HttpClient(url, this.agent_, this.proxy_))
let executor = new _http.Executor(client)

@@ -714,7 +696,3 @@

default:
throw new Error(
'Do not know how to build driver: ' +
browser +
'; did you forget to call usingServer(url)?'
)
throw new Error('Do not know how to build driver: ' + browser + '; did you forget to call usingServer(url)?')
}

@@ -776,3 +754,3 @@ }

`Builder.${setMethod}(). For more information, see the ` +
'documentation attached to the function that threw this error'
'documentation attached to the function that threw this error',
)

@@ -779,0 +757,0 @@ }

@@ -79,4 +79,3 @@ // Licensed to the Software Freedom Conservancy (SFC) under one

const COMMAND_RESULT =
/** !WeakMap<!Command, !Promise<!Result>> */ new WeakMap()
const COMMAND_RESULT = /** !WeakMap<!Command, !Promise<!Result>> */ new WeakMap()
const KILL_HOOK = /** !WeakMap<!Command, function(string)> */ new WeakMap()

@@ -83,0 +82,0 @@

@@ -296,3 +296,3 @@ // Licensed to the Software Freedom Conservancy (SFC) under one

() => callback(null, dir),
(err) => callback(err)
(err) => callback(err),
)

@@ -330,4 +330,4 @@ default:

})
})
)
}),
),
)

@@ -334,0 +334,0 @@ })(rootPath).then(() => seen)

@@ -49,8 +49,3 @@ // Licensed to the Software Freedom Conservancy (SFC) under one

.read(filePath)
.then((buffer) =>
this.z_.file(
/** @type {string} */ (zipPath.replace(/\\/g, '/')),
buffer
)
)
.then((buffer) => this.z_.file(/** @type {string} */ (zipPath.replace(/\\/g, '/')), buffer))
this.pendingAdds_.add(add)

@@ -62,3 +57,3 @@ return add.then(

throw e
}
},
)

@@ -88,8 +83,3 @@ }

} else {
files.push(
this.addFile(
path.join(dirPath, spec.path),
path.join(zipPath, spec.path)
)
)
files.push(this.addFile(path.join(dirPath, spec.path), path.join(zipPath, spec.path)))
}

@@ -124,11 +114,7 @@ })

if (!file) {
return Promise.reject(
new InvalidArgumentError(`No such file in zip archive: ${path}`)
)
return Promise.reject(new InvalidArgumentError(`No such file in zip archive: ${path}`))
}
if (file.dir) {
return Promise.reject(
new InvalidArgumentError(`The requested file is a directory: ${path}`)
)
return Promise.reject(new InvalidArgumentError(`The requested file is a directory: ${path}`))
}

@@ -151,11 +137,5 @@

if (compression !== 'STORE' && compression !== 'DEFLATE') {
return Promise.reject(
new InvalidArgumentError(
`compression must be one of {STORE, DEFLATE}, got ${compression}`
)
)
return Promise.reject(new InvalidArgumentError(`compression must be one of {STORE, DEFLATE}, got ${compression}`))
}
return Promise.resolve(
this.z_.generateAsync({ compression, type: 'nodebuffer' })
)
return Promise.resolve(this.z_.generateAsync({ compression, type: 'nodebuffer' }))
}

@@ -218,5 +198,3 @@ }

function writeFile(relPath, file) {
return file
.async('nodebuffer')
.then((buffer) => io.write(path.join(dst, relPath), buffer))
return file.async('nodebuffer').then((buffer) => io.write(path.join(dst, relPath), buffer))
}

@@ -223,0 +201,0 @@ })

@@ -399,7 +399,3 @@ // Licensed to the Software Freedom Conservancy (SFC) under one

function check(locator) {
if (
locator instanceof By ||
locator instanceof RelativeBy ||
typeof locator === 'function'
) {
if (locator instanceof By || locator instanceof RelativeBy || typeof locator === 'function') {
return locator

@@ -418,6 +414,3 @@ }

for (let key in locator) {
if (
Object.prototype.hasOwnProperty.call(locator, key) &&
Object.prototype.hasOwnProperty.call(By, key)
) {
if (Object.prototype.hasOwnProperty.call(locator, key) && Object.prototype.hasOwnProperty.call(By, key)) {
return By[key](locator[key])

@@ -424,0 +417,0 @@ }

@@ -213,4 +213,3 @@ // Licensed to the Software Freedom Conservancy (SFC) under one

ENABLE_DOWNLOADS: "se:downloadsEnabled",
ENABLE_DOWNLOADS: 'se:downloadsEnabled',
}

@@ -269,5 +268,3 @@

static firefox() {
return new Capabilities()
.setBrowserName(Browser.FIREFOX)
.set('moz:debuggerAddress', true)
return new Capabilities().setBrowserName(Browser.FIREFOX).set('moz:debuggerAddress', true)
}

@@ -522,6 +519,3 @@

setStrictFileInteractability(strictFileInteractability) {
return this.set(
Capability.STRICT_FILE_INTERACTABILITY,
strictFileInteractability
)
return this.set(Capability.STRICT_FILE_INTERACTABILITY, strictFileInteractability)
}

@@ -528,0 +522,0 @@

@@ -185,5 +185,5 @@ // Licensed to the Software Freedom Conservancy (SFC) under one

GET_DOWNLOADABLE_FILES: "getDownloadableFiles",
DOWNLOAD_FILE: "downloadFile",
DELETE_DOWNLOADABLE_FILES: "deleteDownloadableFiles",
GET_DOWNLOADABLE_FILES: 'getDownloadableFiles',
DOWNLOAD_FILE: 'downloadFile',
DELETE_DOWNLOADABLE_FILES: 'deleteDownloadableFiles',
}

@@ -190,0 +190,0 @@

@@ -487,6 +487,3 @@ // Licensed to the Software Freedom Conservancy (SFC) under one

let type = WebDriverError
if (
err instanceof WebDriverError &&
TYPE_TO_ERROR_CODE.has(err.constructor)
) {
if (err instanceof WebDriverError && TYPE_TO_ERROR_CODE.has(err.constructor)) {
type = err.constructor

@@ -545,7 +542,3 @@ }

// Handle the legacy Selenium error response format.
if (
isObject(responseObj) &&
typeof responseObj.status === 'number' &&
responseObj.status !== 0
) {
if (isObject(responseObj) && typeof responseObj.status === 'number' && responseObj.status !== 0) {
const { status, value } = responseObj

@@ -552,0 +545,0 @@

@@ -39,14 +39,5 @@ // Licensed to the Software Freedom Conservancy (SFC) under one

const getAttribute = requireAtom(
'get-attribute.js',
'//javascript/node/selenium-webdriver/lib/atoms:get-attribute.js'
)
const isDisplayed = requireAtom(
'is-displayed.js',
'//javascript/node/selenium-webdriver/lib/atoms:is-displayed.js'
)
const findElements = requireAtom(
'find-elements.js',
'//javascript/node/selenium-webdriver/lib/atoms:find-elements.js'
)
const getAttribute = requireAtom('get-attribute.js', '//javascript/node/selenium-webdriver/lib/atoms:get-attribute.js')
const isDisplayed = requireAtom('is-displayed.js', '//javascript/node/selenium-webdriver/lib/atoms:is-displayed.js')
const findElements = requireAtom('find-elements.js', '//javascript/node/selenium-webdriver/lib/atoms:find-elements.js')

@@ -71,3 +62,3 @@ /**

` need to run \`bazel build ${bazelTarget}\` from the project` +
`root: ${ex}`
`root: ${ex}`,
)

@@ -107,5 +98,3 @@ }

this.data = /** Object */ opt_data
this.headers = /** !Map<string, string> */ new Map([
['Accept', 'application/json; charset=utf-8'],
])
this.headers = /** !Map<string, string> */ new Map([['Accept', 'application/json; charset=utf-8']])
}

@@ -195,9 +184,6 @@

.setParameter('sessionId', command.getParameter('sessionId'))
.setParameter('script', `/* ${name} */return (${atom}).apply(null, arguments)`)
.setParameter(
'script',
`/* ${name} */return (${atom}).apply(null, arguments)`
)
.setParameter(
'args',
params.map((param) => command.getParameter(param))
params.map((param) => command.getParameter(param)),
)

@@ -262,65 +248,27 @@ }

(cmd) => {
return toExecuteAtomCommand(
cmd,
Atom.FIND_ELEMENTS,
'findElements',
'args'
)
return toExecuteAtomCommand(cmd, Atom.FIND_ELEMENTS, 'findElements', 'args')
},
],
[
cmd.Name.FIND_CHILD_ELEMENT,
post('/session/:sessionId/element/:id/element'),
],
[
cmd.Name.FIND_CHILD_ELEMENTS,
post('/session/:sessionId/element/:id/elements'),
],
[cmd.Name.FIND_CHILD_ELEMENT, post('/session/:sessionId/element/:id/element')],
[cmd.Name.FIND_CHILD_ELEMENTS, post('/session/:sessionId/element/:id/elements')],
// Element interaction.
[cmd.Name.GET_ELEMENT_TAG_NAME, get('/session/:sessionId/element/:id/name')],
[cmd.Name.GET_DOM_ATTRIBUTE, get('/session/:sessionId/element/:id/attribute/:name')],
[
cmd.Name.GET_DOM_ATTRIBUTE,
get('/session/:sessionId/element/:id/attribute/:name'),
],
[
cmd.Name.GET_ELEMENT_ATTRIBUTE,
(cmd) => {
return toExecuteAtomCommand(
cmd,
Atom.GET_ATTRIBUTE,
'getAttribute',
'id',
'name'
)
return toExecuteAtomCommand(cmd, Atom.GET_ATTRIBUTE, 'getAttribute', 'id', 'name')
},
],
[
cmd.Name.GET_ELEMENT_PROPERTY,
get('/session/:sessionId/element/:id/property/:name'),
],
[
cmd.Name.GET_ELEMENT_VALUE_OF_CSS_PROPERTY,
get('/session/:sessionId/element/:id/css/:propertyName'),
],
[cmd.Name.GET_ELEMENT_PROPERTY, get('/session/:sessionId/element/:id/property/:name')],
[cmd.Name.GET_ELEMENT_VALUE_OF_CSS_PROPERTY, get('/session/:sessionId/element/:id/css/:propertyName')],
[cmd.Name.GET_ELEMENT_RECT, get('/session/:sessionId/element/:id/rect')],
[cmd.Name.CLEAR_ELEMENT, post('/session/:sessionId/element/:id/clear')],
[cmd.Name.CLICK_ELEMENT, post('/session/:sessionId/element/:id/click')],
[
cmd.Name.SEND_KEYS_TO_ELEMENT,
post('/session/:sessionId/element/:id/value'),
],
[cmd.Name.SEND_KEYS_TO_ELEMENT, post('/session/:sessionId/element/:id/value')],
[cmd.Name.GET_ELEMENT_TEXT, get('/session/:sessionId/element/:id/text')],
[
cmd.Name.GET_COMPUTED_ROLE,
get('/session/:sessionId/element/:id/computedrole'),
],
[
cmd.Name.GET_COMPUTED_LABEL,
get('/session/:sessionId/element/:id/computedlabel'),
],
[cmd.Name.GET_COMPUTED_ROLE, get('/session/:sessionId/element/:id/computedrole')],
[cmd.Name.GET_COMPUTED_LABEL, get('/session/:sessionId/element/:id/computedlabel')],
[cmd.Name.IS_ELEMENT_ENABLED, get('/session/:sessionId/element/:id/enabled')],
[
cmd.Name.IS_ELEMENT_SELECTED,
get('/session/:sessionId/element/:id/selected'),
],
[cmd.Name.IS_ELEMENT_SELECTED, get('/session/:sessionId/element/:id/selected')],

@@ -349,17 +297,8 @@ [

[cmd.Name.SCREENSHOT, get('/session/:sessionId/screenshot')],
[
cmd.Name.TAKE_ELEMENT_SCREENSHOT,
get('/session/:sessionId/element/:id/screenshot'),
],
[cmd.Name.TAKE_ELEMENT_SCREENSHOT, get('/session/:sessionId/element/:id/screenshot')],
// Shadow Root
[cmd.Name.GET_SHADOW_ROOT, get('/session/:sessionId/element/:id/shadow')],
[
cmd.Name.FIND_ELEMENT_FROM_SHADOWROOT,
post('/session/:sessionId/shadow/:id/element'),
],
[
cmd.Name.FIND_ELEMENTS_FROM_SHADOWROOT,
post('/session/:sessionId/shadow/:id/elements'),
],
[cmd.Name.FIND_ELEMENT_FROM_SHADOWROOT, post('/session/:sessionId/shadow/:id/element')],
[cmd.Name.FIND_ELEMENTS_FROM_SHADOWROOT, post('/session/:sessionId/shadow/:id/elements')],
// Log extensions.

@@ -373,42 +312,16 @@ [cmd.Name.GET_LOG, post('/session/:sessionId/se/log')],

// Virtual Authenticator
[cmd.Name.ADD_VIRTUAL_AUTHENTICATOR, post('/session/:sessionId/webauthn/authenticator')],
[cmd.Name.REMOVE_VIRTUAL_AUTHENTICATOR, del('/session/:sessionId/webauthn/authenticator/:authenticatorId')],
[cmd.Name.ADD_CREDENTIAL, post('/session/:sessionId/webauthn/authenticator/:authenticatorId/credential')],
[cmd.Name.GET_CREDENTIALS, get('/session/:sessionId/webauthn/authenticator/:authenticatorId/credentials')],
[
cmd.Name.ADD_VIRTUAL_AUTHENTICATOR,
post('/session/:sessionId/webauthn/authenticator'),
],
[
cmd.Name.REMOVE_VIRTUAL_AUTHENTICATOR,
del('/session/:sessionId/webauthn/authenticator/:authenticatorId'),
],
[
cmd.Name.ADD_CREDENTIAL,
post(
'/session/:sessionId/webauthn/authenticator/:authenticatorId/credential'
),
],
[
cmd.Name.GET_CREDENTIALS,
get(
'/session/:sessionId/webauthn/authenticator/:authenticatorId/credentials'
),
],
[
cmd.Name.REMOVE_CREDENTIAL,
del(
'/session/:sessionId/webauthn/authenticator/:authenticatorId/credentials/:credentialId'
),
del('/session/:sessionId/webauthn/authenticator/:authenticatorId/credentials/:credentialId'),
],
[
cmd.Name.REMOVE_ALL_CREDENTIALS,
del(
'/session/:sessionId/webauthn/authenticator/:authenticatorId/credentials'
),
],
[
cmd.Name.SET_USER_VERIFIED,
post('/session/:sessionId/webauthn/authenticator/:authenticatorId/uv'),
],
[cmd.Name.REMOVE_ALL_CREDENTIALS, del('/session/:sessionId/webauthn/authenticator/:authenticatorId/credentials')],
[cmd.Name.SET_USER_VERIFIED, post('/session/:sessionId/webauthn/authenticator/:authenticatorId/uv')],
[cmd.Name.GET_DOWNLOADABLE_FILES, get('/session/:sessionId/se/files')],
[cmd.Name.DOWNLOAD_FILE, post(`/session/:sessionId/se/files`)],
[cmd.Name.DELETE_DOWNLOADABLE_FILES, del(`/session/:sessionId/se/files`)]
[cmd.Name.DELETE_DOWNLOADABLE_FILES, del(`/session/:sessionId/se/files`)],
])

@@ -456,5 +369,3 @@

}
throw new error.UnknownCommandError(
'Unrecognized command: ' + command.getName()
)
throw new error.UnknownCommandError('Unrecognized command: ' + command.getName())

@@ -473,4 +384,3 @@ /**

const CLIENTS =
/** !WeakMap<!Executor, !(Client|IThenable<!Client>)> */ new WeakMap()
const CLIENTS = /** !WeakMap<!Executor, !(Client|IThenable<!Client>)> */ new WeakMap()

@@ -546,5 +456,3 @@ /**

if (!value || !value.sessionId) {
throw new error.WebDriverError(
`Unable to parse new session response: ${response.body}`
)
throw new error.WebDriverError(`Unable to parse new session response: ${response.body}`)
}

@@ -560,6 +468,3 @@

let capabilities = value.capabilities || value.value
return new Session(
/** @type {{sessionId: string}} */ (value).sessionId,
capabilities
)
return new Session(/** @type {{sessionId: string}} */ (value).sessionId, capabilities)
}

@@ -663,5 +568,3 @@

} else {
throw new error.InvalidArgumentError(
'Missing required parameter: ' + key
)
throw new error.InvalidArgumentError('Missing required parameter: ' + key)
}

@@ -668,0 +571,0 @@ }

@@ -259,5 +259,3 @@ // Licensed to the Software Freedom Conservancy (SFC) under one

if (Array.from(key).length !== 1) {
throw new InvalidArgumentError(
`key input is not a single code point: ${key}`
)
throw new InvalidArgumentError(`key input is not a single code point: ${key}`)
}

@@ -337,6 +335,3 @@ return key

toJSON() {
return Object.assign(
{ parameters: { pointerType: this.pointerType_ } },
super.toJSON()
)
return Object.assign({ parameters: { pointerType: this.pointerType_ } }, super.toJSON())
}

@@ -376,3 +371,3 @@

altitudeAngle = 0,
azimuthAngle = 0
azimuthAngle = 0,
) {

@@ -820,6 +815,3 @@ return {

for (const symbol of key) {
actions.push(
this.keyboard_.keyDown(symbol),
this.keyboard_.keyUp(symbol)
)
actions.push(this.keyboard_.keyDown(symbol), this.keyboard_.keyUp(symbol))
}

@@ -864,6 +856,3 @@ } else {

scroll(x, y, targetDeltaX, targetDeltaY, origin, duration) {
return this.insert(
this.wheel_,
this.wheel_.scroll(x, y, targetDeltaX, targetDeltaY, origin, duration)
)
return this.insert(this.wheel_, this.wheel_.scroll(x, y, targetDeltaX, targetDeltaY, origin, duration))
}

@@ -893,6 +882,3 @@

move({ x = 0, y = 0, duration = 100, origin = Origin.VIEWPORT } = {}) {
return this.insert(
this.mouse_,
this.mouse_.move({ x, y, duration, origin })
)
return this.insert(this.mouse_, this.mouse_.move({ x, y, duration, origin }))
}

@@ -962,9 +948,4 @@

const { WebElement } = require('./webdriver')
if (
!(to instanceof WebElement) &&
(!to || typeof to.x !== 'number' || typeof to.y !== 'number')
) {
throw new InvalidArgumentError(
'Invalid drag target; must specify a WebElement or {x, y} offset'
)
if (!(to instanceof WebElement) && (!to || typeof to.x !== 'number' || typeof to.y !== 'number')) {
throw new InvalidArgumentError('Invalid drag target; must specify a WebElement or {x, y} offset')
}

@@ -1013,5 +994,3 @@

await this.executor_.execute(
new Command(Name.ACTIONS).setParameter('actions', _actions)
)
await this.executor_.execute(new Command(Name.ACTIONS).setParameter('actions', _actions))
}

@@ -1037,6 +1016,3 @@

function isIdle(actions) {
return (
actions.length === 0 ||
actions.every((a) => a.type === Action.Type.PAUSE && !a.duration)
)
return actions.length === 0 || actions.every((a) => a.type === Action.Type.PAUSE && !a.duration)
}

@@ -1043,0 +1019,0 @@

@@ -223,4 +223,3 @@ // Licensed to the Software Freedom Conservancy (SFC) under one

this.message = message
this.timestamp =
typeof opt_timestamp === 'number' ? opt_timestamp : Date.now()
this.timestamp = typeof opt_timestamp === 'number' ? opt_timestamp : Date.now()
this.type = opt_type || ''

@@ -315,6 +314,3 @@ }

isLoggable(level) {
return (
level.value !== Level.OFF.value &&
level.value >= this.getEffectiveLevel().value
)
return level.value !== Level.OFF.value && level.value >= this.getEffectiveLevel().value
}

@@ -363,7 +359,3 @@

}
let message =
'[' +
this.name_ +
'] ' +
(typeof loggable === 'function' ? loggable() : loggable)
let message = '[' + this.name_ + '] ' + (typeof loggable === 'function' ? loggable() : loggable)
let entry = new Entry(level, message, Date.now())

@@ -370,0 +362,0 @@ for (let logger = this; logger; logger = logger.parent_) {

@@ -176,5 +176,3 @@ // Licensed to the Software Freedom Conservancy (SFC) under one

for (const [index, item] of arr.entries()) {
const isConditionTrue = await Promise.resolve(
fn.call(self, item, index, arr)
)
const isConditionTrue = await Promise.resolve(fn.call(self, item, index, arr))
if (isConditionTrue) {

@@ -251,6 +249,3 @@ values.push(item)

await forEachKey(obj, async function (partialValue, key) {
if (
!Array.isArray(partialValue) &&
(!partialValue || typeof partialValue !== 'object')
) {
if (!Array.isArray(partialValue) && (!partialValue || typeof partialValue !== 'object')) {
return

@@ -257,0 +252,0 @@ }

@@ -187,5 +187,3 @@ // Licensed to the Software Freedom Conservancy (SFC) under one

throw new Error(
`Option with index "${index}" not found. Select element only contains ${
options.length - 1
} option elements`
`Option with index "${index}" not found. Select element only contains ${options.length - 1} option elements`,
)

@@ -412,5 +410,3 @@ }

throw new Error(
`Option with index "${index}" not found. Select element only contains ${
options.length - 1
} option elements`
`Option with index "${index}" not found. Select element only contains ${options.length - 1} option elements`,
)

@@ -459,5 +455,3 @@ }

if (!(await option.isEnabled())) {
throw new error.UnsupportedOperationError(
`You may not select a disabled option`
)
throw new error.UnsupportedOperationError(`You may not select a disabled option`)
}

@@ -464,0 +458,0 @@ await option.click()

@@ -99,3 +99,3 @@ // Licensed to the Software Freedom Conservancy (SFC) under one

}
}
},
)

@@ -123,4 +123,3 @@ }

// https://github.com/SeleniumHQ/selenium/pull/2137
(e instanceof error.WebDriverError &&
e.message === `can't convert null to object`)
(e instanceof error.WebDriverError && e.message === `can't convert null to object`)
)

@@ -142,5 +141,3 @@ ) {

function titleIs(title) {
return new Condition('for title to be ' + JSON.stringify(title), function (
driver
) {
return new Condition('for title to be ' + JSON.stringify(title), function (driver) {
return driver.getTitle().then(function (t) {

@@ -161,10 +158,7 @@ return t === title

function titleContains(substr) {
return new Condition(
'for title to contain ' + JSON.stringify(substr),
function (driver) {
return driver.getTitle().then(function (title) {
return title.indexOf(substr) !== -1
})
}
)
return new Condition('for title to contain ' + JSON.stringify(substr), function (driver) {
return driver.getTitle().then(function (title) {
return title.indexOf(substr) !== -1
})
})
}

@@ -195,5 +189,3 @@

function urlIs(url) {
return new Condition('for URL to be ' + JSON.stringify(url), function (
driver
) {
return new Condition('for URL to be ' + JSON.stringify(url), function (driver) {
return driver.getCurrentUrl().then(function (u) {

@@ -214,10 +206,7 @@ return u === url

function urlContains(substrUrl) {
return new Condition(
'for URL to contain ' + JSON.stringify(substrUrl),
function (driver) {
return driver.getCurrentUrl().then(function (url) {
return url && url.includes(substrUrl)
})
}
)
return new Condition('for URL to contain ' + JSON.stringify(substrUrl), function (driver) {
return driver.getCurrentUrl().then(function (url) {
return url && url.includes(substrUrl)
})
})
}

@@ -249,12 +238,8 @@

locator = by.checkedLocator(locator)
let locatorStr =
typeof locator === 'function' ? 'by function()' : locator + ''
return new WebElementCondition(
'for element to be located ' + locatorStr,
function (driver) {
return driver.findElements(locator).then(function (elements) {
return elements[0]
})
}
)
let locatorStr = typeof locator === 'function' ? 'by function()' : locator + ''
return new WebElementCondition('for element to be located ' + locatorStr, function (driver) {
return driver.findElements(locator).then(function (elements) {
return elements[0]
})
})
}

@@ -272,12 +257,8 @@

locator = by.checkedLocator(locator)
let locatorStr =
typeof locator === 'function' ? 'by function()' : locator + ''
return new Condition(
'for at least one element to be located ' + locatorStr,
function (driver) {
return driver.findElements(locator).then(function (elements) {
return elements.length > 0 ? elements : null
})
}
)
let locatorStr = typeof locator === 'function' ? 'by function()' : locator + ''
return new Condition('for at least one element to be located ' + locatorStr, function (driver) {
return driver.findElements(locator).then(function (elements) {
return elements.length > 0 ? elements : null
})
})
}

@@ -304,3 +285,3 @@

throw e
}
},
)

@@ -416,5 +397,3 @@ })

return new WebElementCondition('until element text contains', function () {
return element
.getText()
.then((t) => (t.indexOf(substr) != -1 ? element : null))
return element.getText().then((t) => (t.indexOf(substr) != -1 ? element : null))
})

@@ -421,0 +400,0 @@ }

@@ -40,6 +40,3 @@ // Licensed to the Software Freedom Conservancy (SFC) under one

// contract.
return (
(typeof value === 'object' || typeof value === 'function') &&
typeof value['then'] === 'function'
)
return (typeof value === 'object' || typeof value === 'function') && typeof value['then'] === 'function'
} catch (ex) {

@@ -46,0 +43,0 @@ return false

@@ -122,10 +122,3 @@ // Licensed to the Software Freedom Conservancy (SFC) under one

class Credential {
constructor(
credentialId,
isResidentCredential,
rpId,
userHandle,
privateKey,
signCount
) {
constructor(credentialId, isResidentCredential, rpId, userHandle, privateKey, signCount) {
this._id = credentialId

@@ -211,5 +204,3 @@ this._isResidentCredential = isResidentCredential

if (this.userHandle() != null) {
credentialData['userHandle'] = Buffer.from(this._userHandle).toString(
'base64url'
)
credentialData['userHandle'] = Buffer.from(this._userHandle).toString('base64url')
}

@@ -227,5 +218,3 @@

let rpId = data['rpId']
let privateKey = Buffer.from(data['privateKey'], 'base64url').toString(
'binary'
)
let privateKey = Buffer.from(data['privateKey'], 'base64url').toString('binary')
let signCount = data['signCount']

@@ -239,10 +228,3 @@ let userHandle

}
return new Credential(
id,
isResidentCredential,
rpId,
userHandle,
privateKey,
signCount
)
return new Credential(id, isResidentCredential, rpId, userHandle, privateKey, signCount)
}

@@ -249,0 +231,0 @@ }

@@ -36,7 +36,3 @@ // Licensed to the Software Freedom Conservancy (SFC) under one

function isId(obj) {
return (
isObject(obj) &&
(typeof obj[ELEMENT_ID_KEY] === 'string' ||
typeof obj[LEGACY_ELEMENT_ID_KEY] === 'string')
)
return isObject(obj) && (typeof obj[ELEMENT_ID_KEY] === 'string' || typeof obj[LEGACY_ELEMENT_ID_KEY] === 'string')
}

@@ -43,0 +39,0 @@

@@ -51,6 +51,3 @@ // Licensed to the Software Freedom Conservancy (SFC) under one

for (let ipAddress of interfaces[key]) {
if (
(ipAddress.family === family || `IPv${ipAddress.family}` === family) &&
ipAddress.internal === loopback
) {
if ((ipAddress.family === family || `IPv${ipAddress.family}` === family) && ipAddress.internal === loopback) {
return ipAddress.address

@@ -57,0 +54,0 @@ }

{
"name": "selenium-webdriver",
"version": "4.17.0",
"version": "4.18.0",
"description": "The official WebDriver JavaScript bindings from the Selenium project",

@@ -45,2 +45,3 @@ "license": "Apache-2.0",

"lint": "eslint --ignore-pattern node_modules --ignore-pattern generator --ext js lib/http.js \"**/*.js\"",
"lint:fix": "eslint --ignore-pattern node_modules --ignore-pattern generator --ext js lib/http.js \"**/*.js\" --fix",
"test": "npm run lint && mocha -t 600000 --recursive test",

@@ -47,0 +48,0 @@ "test-jasmine": "bazel test //javascript/node/selenium-webdriver:tests"

@@ -245,5 +245,3 @@ // Licensed to the Software Freedom Conservancy (SFC) under one

if (!hostname) {
hostname =
(!self.loopbackOnly_ && net.getAddress()) ||
net.getLoopbackAddress()
hostname = (!self.loopbackOnly_ && net.getAddress()) || net.getLoopbackAddress()
}

@@ -259,5 +257,3 @@

return new Promise((fulfill, reject) => {
let cancelToken = earlyTermination.catch((e) =>
reject(Error(e.message))
)
let cancelToken = earlyTermination.catch((e) => reject(Error(e.message)))

@@ -272,7 +268,7 @@ httpUtil.waitForServer(serverUrl, timeout, cancelToken).then(

}
}
},
)
})
})
})
}),
)

@@ -308,5 +304,3 @@ })

// Resolve the outer array, then the individual flags.
return Promise.resolve(args).then(
/** !Array<CommandLineFlag> */ (args) => Promise.all(args)
)
return Promise.resolve(args).then(/** !Array<CommandLineFlag> */ (args) => Promise.all(args))
}

@@ -485,7 +479,3 @@

let port = options.port || portprober.findFreePort()
let args = Promise.all([
port,
options.jvmArgs || [],
options.args || [],
]).then((resolved) => {
let args = Promise.all([port, options.jvmArgs || [], options.args || []]).then((resolved) => {
let port = resolved[0]

@@ -495,5 +485,3 @@ let jvmArgs = resolved[1]

const fullArgsList = jvmArgs
.concat('-jar', jar, '-port', port)
.concat(args)
const fullArgsList = jvmArgs.concat('-jar', jar, '-port', port).concat(args)

@@ -617,6 +605,3 @@ return formatSpawnArgs(jar, fullArgsList)

.then((encodedZip) => {
let command = new cmd.Command(cmd.Name.UPLOAD_FILE).setParameter(
'file',
encodedZip
)
let command = new cmd.Command(cmd.Name.UPLOAD_FILE).setParameter('file', encodedZip)
return driver.execute(command)

@@ -630,3 +615,3 @@ })

throw err
}
},
)

@@ -633,0 +618,0 @@ }

@@ -29,5 +29,3 @@ // Licensed to the Software Freedom Conservancy (SFC) under one

function getJavaPath() {
return process.env['JAVA_HOME']
? path.join(process.env['JAVA_HOME'], 'bin/java')
: 'java'
return process.env['JAVA_HOME'] ? path.join(process.env['JAVA_HOME'], 'bin/java') : 'java'
}

@@ -42,7 +40,3 @@

const execRes = cp.execFileSync(javaPath, [
'-jar',
seleniumStandalonePath,
'--version',
])
const execRes = cp.execFileSync(javaPath, ['-jar', seleniumStandalonePath, '--version'])

@@ -62,5 +56,3 @@ return execRes.toString().trim().startsWith('Selenium server version: 3')

.getLogger(logging.Type.SERVER)
.warning(
'Deprecation: Support for Standalone Server 3.x will be removed soon. Please update to version 4.x',
)
.warning('Deprecation: Support for Standalone Server 3.x will be removed soon. Please update to version 4.x')
return args

@@ -75,8 +67,4 @@ }

const standaloneArgIndex = formattedArgs.findIndex(
(arg) => arg === seleniumStandalonePath
)
const v3portArgFormat = formattedArgs.findIndex(
(arg) => arg === port3xArgFormat
)
const standaloneArgIndex = formattedArgs.findIndex((arg) => arg === seleniumStandalonePath)
const v3portArgFormat = formattedArgs.findIndex((arg) => arg === port3xArgFormat)

@@ -90,4 +78,3 @@ // old v3x port arg format was -port, new v4x port arg format is --port

// in case if it is already in place - returns args
if (formattedArgs[standaloneArgIndex + 1] === standaloneArg)
return formattedArgs
if (formattedArgs[standaloneArgIndex + 1] === standaloneArg) return formattedArgs

@@ -94,0 +81,0 @@ // insert 'standalone' right after jar file path

@@ -98,4 +98,3 @@ // Licensed to the Software Freedom Conservancy (SFC) under one

const SAFARIDRIVER_TECHNOLOGY_PREVIEW_EXE =
'/Applications/Safari Technology Preview.app/Contents/MacOS/safaridriver'
const SAFARIDRIVER_TECHNOLOGY_PREVIEW_EXE = '/Applications/Safari Technology Preview.app/Contents/MacOS/safaridriver'

@@ -130,9 +129,5 @@ /**

}
let executor = new http.Executor(
service.start().then((url) => new http.HttpClient(url))
)
let executor = new http.Executor(service.start().then((url) => new http.HttpClient(url)))
return /** @type {!Driver} */ (
super.createSession(executor, caps, () => service.kill())
)
return /** @type {!Driver} */ (super.createSession(executor, caps, () => service.kill()))
}

@@ -139,0 +134,0 @@ }

@@ -217,3 +217,3 @@ // Licensed to the Software Freedom Conservancy (SFC) under one

'Ambiguous test configuration: both SELENIUM_REMOTE_URL' +
' && SELENIUM_SERVER_JAR environment variables are set'
' && SELENIUM_SERVER_JAR environment variables are set',
)

@@ -227,3 +227,3 @@ }

' SELENIUM_SERVER_JAR environment variable is set, the' +
' SELENIUM_BROWSER variable must also be set.'
' SELENIUM_BROWSER variable must also be set.',
)

@@ -233,5 +233,3 @@ }

targetBrowsers = envBrowsers.length > 0 ? envBrowsers : getAvailableBrowsers()
info(
`Running tests against [${targetBrowsers.map((b) => b.name).join(', ')}]`
)
info(`Running tests against [${targetBrowsers.map((b) => b.name).join(', ')}]`)

@@ -246,4 +244,3 @@ after(function () {

const TARGET_MAP = /** !WeakMap<!Environment, !TargetBrowser> */ new WeakMap()
const URL_MAP =
/** !WeakMap<!Environment, ?(string|remote.SeleniumServer)> */ new WeakMap()
const URL_MAP = /** !WeakMap<!Environment, ?(string|remote.SeleniumServer)> */ new WeakMap()

@@ -261,5 +258,3 @@ /**

constructor(browser, url = undefined) {
browser = /** @type {!TargetBrowser} */ (
Object.seal(Object.assign({}, browser))
)
browser = /** @type {!TargetBrowser} */ (Object.seal(Object.assign({}, browser)))

@@ -503,3 +498,3 @@ TARGET_MAP.set(this, browser)

' This can happen if you try using this module when running with' +
' node directly instead of using jasmine or mocha'
' node directly instead of using jasmine or mocha',
)

@@ -506,0 +501,0 @@ }

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

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc