UNPKG

selenium-webdriver

Version:

The official WebDriver JavaScript bindings from the Selenium project

453 lines (406 loc) 13.2 kB
// Licensed to the Software Freedom Conservancy (SFC) under one // or more contributor license agreements. See the NOTICE file // distributed with this work for additional information // regarding copyright ownership. The SFC licenses this file // to you under the Apache License, Version 2.0 (the // "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. const { PrimitiveType, NonPrimitiveType, RemoteType, SpecialNumberType } = require('./protocolType') const TYPE_CONSTANT = 'type' const VALUE_CONSTANT = 'value' /** * Represents the types of remote reference. * @enum {string} */ const RemoteReferenceType = { HANDLE: 'handle', SHARED_ID: 'sharedId', } /** * Represents a local value with a specified type and optional value. * @class * Described in https://w3c.github.io/webdriver-bidi/#type-script-LocalValue */ class LocalValue { constructor(type, value = null) { if (type === PrimitiveType.UNDEFINED || type === PrimitiveType.NULL) { this.type = type } else { this.type = type this.value = value } } /** * Creates a new LocalValue object with a string value. * * @param {string} value - The string value to be stored in the LocalValue object. * @returns {LocalValue} - The created LocalValue object. */ static createStringValue(value) { return new LocalValue(PrimitiveType.STRING, value) } /** * Creates a new LocalValue object with a number value. * * @param {number} value - The number value. * @returns {LocalValue} - The created LocalValue object. */ static createNumberValue(value) { return new LocalValue(PrimitiveType.NUMBER, value) } /** * Creates a new LocalValue object with a special number value. * * @param {number} value - The value of the special number. * @returns {LocalValue} - The created LocalValue object. */ static createSpecialNumberValue(value) { return new LocalValue(PrimitiveType.SPECIAL_NUMBER, value) } /** * Creates a new LocalValue object with an undefined value. * @returns {LocalValue} - The created LocalValue object. */ static createUndefinedValue() { return new LocalValue(PrimitiveType.UNDEFINED) } /** * Creates a new LocalValue object with a null value. * @returns {LocalValue} - The created LocalValue object. */ static createNullValue() { return new LocalValue(PrimitiveType.NULL) } /** * Creates a new LocalValue object with a boolean value. * * @param {boolean} value - The boolean value. * @returns {LocalValue} - The created LocalValue object. */ static createBooleanValue(value) { return new LocalValue(PrimitiveType.BOOLEAN, value) } /** * Creates a new LocalValue object with a BigInt value. * * @param {BigInt} value - The BigInt value. * @returns {LocalValue} - The created LocalValue object. */ static createBigIntValue(value) { return new LocalValue(PrimitiveType.BIGINT, value) } /** * Creates a new LocalValue object with an array. * * @param {Array} value - The array. * @returns {LocalValue} - The created LocalValue object. */ static createArrayValue(value) { return new LocalValue(NonPrimitiveType.ARRAY, value) } /** * Creates a new LocalValue object with date value. * * @param {string} value - The date. * @returns {LocalValue} - The created LocalValue object. */ static createDateValue(value) { return new LocalValue(NonPrimitiveType.DATE, value) } /** * Creates a new LocalValue object of map value. * @param {Map} map - The map. * @returns {LocalValue} - The created LocalValue object. */ static createMapValue(map) { let value = [] Object.entries(map).forEach((entry) => { value.push(entry) }) return new LocalValue(NonPrimitiveType.MAP, value) } /** * Creates a new LocalValue object from the passed object. * * @param {Object} object - The object. * @returns {LocalValue} - The created LocalValue object. */ static createObjectValue(object) { let value = [] Object.entries(object).forEach((entry) => { value.push(entry) }) return new LocalValue(NonPrimitiveType.OBJECT, value) } /** * Creates a new LocalValue object of regular expression value. * * @param {string} value - The value of the regular expression. * @returns {LocalValue} - The created LocalValue object. */ static createRegularExpressionValue(value) { return new LocalValue(NonPrimitiveType.REGULAR_EXPRESSION, value) } /** * Creates a new LocalValue object with the specified value. * @param {Set} value - The value to be set. * @returns {LocalValue} - The created LocalValue object. */ static createSetValue(value) { return new LocalValue(NonPrimitiveType.SET, value) } /** * Creates a new LocalValue object with the given channel value * * @param {ChannelValue} value - The channel value. * @returns {LocalValue} - The created LocalValue object. */ static createChannelValue(value) { return new LocalValue(NonPrimitiveType.CHANNEL, value) } static createReferenceValue(handle, sharedId) { return new ReferenceValue(handle, sharedId) } static getArgument(argument) { let localValue = null if ( argument === SpecialNumberType.NAN || argument === SpecialNumberType.MINUS_ZERO || argument === SpecialNumberType.INFINITY || argument === SpecialNumberType.MINUS_INFINITY ) { localValue = LocalValue.createSpecialNumberValue(argument) return localValue } const type = typeof argument switch (type) { case PrimitiveType.STRING: localValue = LocalValue.createStringValue(argument) break case PrimitiveType.NUMBER: localValue = LocalValue.createNumberValue(argument) break case PrimitiveType.BOOLEAN: localValue = LocalValue.createBooleanValue(argument) break case PrimitiveType.BIGINT: localValue = LocalValue.createBigIntValue(argument.toString()) break case PrimitiveType.UNDEFINED: localValue = LocalValue.createUndefinedValue() break case NonPrimitiveType.OBJECT: if (argument === null) { localValue = LocalValue.createNullValue() break } if (argument instanceof Date) { localValue = LocalValue.createDateValue(argument) } else if (argument instanceof Map) { const map = [] argument.forEach((value, key) => { let objectKey if (typeof key === 'string') { objectKey = key } else { objectKey = LocalValue.getArgument(key) } const objectValue = LocalValue.getArgument(value) map.push([objectKey, objectValue]) }) localValue = new LocalValue(NonPrimitiveType.MAP, map) } else if (argument instanceof Set) { const set = [] argument.forEach((value) => { set.push(LocalValue.getArgument(value)) }) localValue = LocalValue.createSetValue(set) } else if (argument instanceof Array) { const arr = [] argument.forEach((value) => { arr.push(LocalValue.getArgument(value)) }) localValue = LocalValue.createArrayValue(arr) } else if (argument instanceof RegExp) { localValue = LocalValue.createRegularExpressionValue({ pattern: argument.source, flags: argument.flags, }) } else { let value = [] Object.entries(argument).forEach((entry) => { value.push([LocalValue.getArgument(entry[0]), LocalValue.getArgument(entry[1])]) }) localValue = new LocalValue(NonPrimitiveType.OBJECT, value) } break } return localValue } asMap() { let toReturn = {} toReturn[TYPE_CONSTANT] = this.type if (!(this.type === PrimitiveType.NULL || this.type === PrimitiveType.UNDEFINED)) { toReturn[VALUE_CONSTANT] = this.value } return toReturn } } /** * Represents a remote value. * Described in https://w3c.github.io/webdriver-bidi/#type-script-RemoteValue. * @class */ class RemoteValue { constructor(remoteValue) { this.type = null this.handle = null this.internalId = null this.value = null this.sharedId = null if ('type' in remoteValue) { const typeString = remoteValue['type'] if (PrimitiveType.findByName(typeString) != null) { this.type = PrimitiveType.findByName(typeString) } else if (NonPrimitiveType.findByName(typeString) != null) { this.type = NonPrimitiveType.findByName(typeString) } else { this.type = RemoteType.findByName(typeString) } } if ('handle' in remoteValue) { this.handle = remoteValue['handle'] } if ('internalId' in remoteValue) { this.internalId = remoteValue['internalId'] } if ('value' in remoteValue) { this.value = remoteValue['value'] } if ('sharedId' in remoteValue) { this.sharedId = remoteValue['sharedId'] } if (this.value != null) { this.value = this.deserializeValue(this.value, this.type) } } deserializeValue(value, type) { if (type === NonPrimitiveType.OBJECT) { return Object.fromEntries(value) } else if (type === NonPrimitiveType.REGULAR_EXPRESSION) { return new RegExpValue(value.pattern, value.flags) } return value } } /** * Represents a reference value in the protocol. * Described in https://w3c.github.io/webdriver-bidi/#type-script-RemoteReference. */ class ReferenceValue { #handle #sharedId /** * Constructs a new ReferenceValue object. * @param {string} handle - The handle value. * @param {string} sharedId - The shared ID value. */ constructor(handle, sharedId) { if (handle === RemoteReferenceType.HANDLE) { this.#handle = sharedId } else if (handle === RemoteReferenceType.SHARED_ID) { this.#sharedId = sharedId } else { this.#handle = handle this.#sharedId = sharedId } } asMap() { const toReturn = {} if (this.#handle != null) { toReturn[RemoteReferenceType.HANDLE] = this.#handle } if (this.#sharedId != null) { toReturn[RemoteReferenceType.SHARED_ID] = this.#sharedId } return toReturn } } /** * Represents a regular expression value. * Described in https://w3c.github.io/webdriver-bidi/#type-script-LocalValue. */ class RegExpValue { /** * Constructs a new RegExpValue object. * @param {string} pattern - The pattern of the regular expression. * @param {string|null} [flags=null] - The flags of the regular expression. */ constructor(pattern, flags = null) { this.pattern = pattern this.flags = flags } } /** * Represents serialization options. * Described in https://w3c.github.io/webdriver-bidi/#type-script-SerializationOptions. */ class SerializationOptions { /** * Constructs a new instance of SerializationOptions. * @param {number} [maxDomDepth=0] - The maximum depth to serialize the DOM. * @param {number|null} [maxObjectDepth=null] - The maximum depth to serialize objects. * @param {'none'|'open'|'all'} [includeShadowTree='none'] - The inclusion level of the shadow tree. * @throws {Error} If the `includeShadowTree` value is not one of 'none', 'open', or 'all'. */ constructor(maxDomDepth = 0, maxObjectDepth = null, includeShadowTree = 'none') { this._maxDomDepth = maxDomDepth this._maxObjectDepth = maxObjectDepth if (['none', 'open', 'all'].includes(includeShadowTree)) { throw Error(`Valid types are 'none', 'open', and 'all'. Received: ${includeShadowTree}`) } this._includeShadowTree = includeShadowTree } } /** * Represents a channel value. * Described in https://w3c.github.io/webdriver-bidi/#type-script-ChannelValue. * @class */ class ChannelValue { constructor(channel, options = undefined, resultOwnership = undefined) { this.channel = channel if (options !== undefined) { if (options instanceof SerializationOptions) { this.options = options } else { throw Error(`Pass in SerializationOptions object. Received: ${options} `) } } if (resultOwnership !== undefined) { if (['root', 'none'].includes(resultOwnership)) { this.resultOwnership = resultOwnership } else { throw Error(`Valid types are 'root' and 'none. Received: ${resultOwnership}`) } } } } module.exports = { ChannelValue, LocalValue, RemoteValue, ReferenceValue, RemoteReferenceType, RegExpValue, SerializationOptions, }