selenium-webdriver
Advanced tools
Comparing version 4.17.0 to 4.18.0
@@ -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) |
432
CHANGES.md
@@ -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 @@ |
136
chromium.js
@@ -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 @@ |
158
firefox.js
@@ -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) |
20
ie.js
@@ -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 @@ |
36
index.js
@@ -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 @@ |
165
lib/http.js
@@ -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
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
18748521
80
17821