Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

selenium-webdriver

Package Overview
Dependencies
Maintainers
8
Versions
100
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

selenium-webdriver - npm Package Compare versions

Comparing version 4.22.0 to 4.23.0

lib/atoms/bidi-mutation-listener.js

7

bidi/argumentValue.js

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

/**
* @deprecated
* in favor of LocalValue methods for all argument values.
* This extra wrapper is not required.
*/
class ArgumentValue {

@@ -28,3 +33,3 @@ constructor(value) {

if (this.value instanceof LocalValue) {
return this.value.toJson()
return this.value.asMap()
} else {

@@ -31,0 +36,0 @@ // ReferenceValue

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

}
async close() {
if (
this._browsingContextIds !== null &&
this._browsingContextIds !== undefined &&
this._browsingContextIds.length > 0
) {
await this.bidi.unsubscribe(
'browsingContext.contextCreated',
'browsingContext.contextDestroyed',
'browsingContext.fragmentNavigated',
'browsingContext.userPromptClosed',
this._browsingContextIds,
)
} else {
await this.bidi.unsubscribe(
'browsingContext.contextCreated',
'browsingContext.contextDestroyed',
'browsingContext.fragmentNavigated',
'browsingContext.userPromptClosed',
)
}
}
}

@@ -143,0 +166,0 @@

20

bidi/index.js

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

this.events.push(...eventsArray)
await this.send(params)

@@ -171,8 +173,11 @@ }

async unsubscribe(events, browsingContexts) {
if (typeof events === 'string') {
this.events = this.events.filter((event) => event !== events)
} else if (Array.isArray(events)) {
this.events = this.events.filter((event) => !events.includes(event))
}
const eventsToRemove = typeof events === 'string' ? [events] : events
// Check if the eventsToRemove are in the subscribed events array
// Filter out events that are not in this.events before filtering
const existingEvents = eventsToRemove.filter((event) => this.events.includes(event))
// Remove the events from the subscribed events array
this.events = this.events.filter((event) => !existingEvents.includes(event))
if (typeof browsingContexts === 'string') {

@@ -184,6 +189,9 @@ this.browsingContexts.pop()

if (existingEvents.length === 0) {
return
}
const params = {
method: 'session.unsubscribe',
params: {
events: this.events,
events: existingEvents,
},

@@ -190,0 +198,0 @@ }

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

const { Source } = require('./scriptTypes')
/**

@@ -29,2 +31,3 @@ * Represents a base log entry.

* @param {string} level - The log level.
* @param {string} text - The log source.
* @param {string} text - The log text.

@@ -34,4 +37,5 @@ * @param {number} timeStamp - The log timestamp.

*/
constructor(level, text, timeStamp, stackTrace) {
constructor(level, source, text, timeStamp, stackTrace) {
this._level = level
this._source = new Source(source)
this._text = text

@@ -73,2 +77,6 @@ this._timeStamp = timeStamp

}
get source() {
return this._source
}
}

@@ -90,4 +98,4 @@

*/
constructor(level, text, timeStamp, type, stackTrace) {
super(level, text, timeStamp, stackTrace)
constructor(level, source, text, timeStamp, type, stackTrace) {
super(level, source, text, timeStamp, stackTrace)
this._type = type

@@ -111,6 +119,5 @@ }

class ConsoleLogEntry extends GenericLogEntry {
constructor(level, text, timeStamp, type, method, realm, args, stackTrace) {
super(level, text, timeStamp, type, stackTrace)
constructor(level, source, text, timeStamp, type, method, args, stackTrace) {
super(level, source, text, timeStamp, type, stackTrace)
this._method = method
this._realm = realm
this._args = args

@@ -126,12 +133,3 @@ }

}
/**
* Gets the realm associated with the log entry.
* @returns {string} The realm associated with the log entry.
*/
get realm() {
return this._realm
}
/**
* Gets the arguments associated with the log entry.

@@ -151,4 +149,4 @@ * @returns {Array} The arguments associated with the log entry.

class JavascriptLogEntry extends GenericLogEntry {
constructor(level, text, timeStamp, type, stackTrace) {
super(level, text, timeStamp, type, stackTrace)
constructor(level, source, text, timeStamp, type, stackTrace) {
super(level, source, text, timeStamp, type, stackTrace)
}

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

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

params.level,
params.source,
params.text,

@@ -136,3 +137,2 @@ params.timestamp,

params.method,
params.realm,
params.args,

@@ -183,2 +183,3 @@ params.stackTrace,

params.level,
params.source,
params.text,

@@ -218,2 +219,3 @@ params.timestamp,

params.level,
params.source,
params.text,

@@ -257,2 +259,3 @@ params.timestamp,

params.level,
params.source,
params.text,

@@ -287,2 +290,3 @@ params.timestamp,

params.level,
params.source,
params.text,

@@ -292,3 +296,2 @@ params.timestamp,

params.method,
params.realm,
params.args,

@@ -312,2 +315,3 @@ params.stackTrace,

params.level,
params.source,
params.text,

@@ -341,3 +345,11 @@ params.timestamp,

async close() {
await this.bidi.unsubscribe('log.entryAdded', this._browsingContextIds)
if (
this._browsingContextIds !== null &&
this._browsingContextIds !== undefined &&
this._browsingContextIds.length > 0
) {
await this.bidi.unsubscribe('log.entryAdded', this._browsingContextIds)
} else {
await this.bidi.unsubscribe('log.entryAdded')
}
}

@@ -344,0 +356,0 @@ }

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

async close() {
await this.bidi.unsubscribe(
'network.beforeRequestSent',
'network.responseStarted',
'network.responseCompleted',
'network.authRequired',
)
if (
this._browsingContextIds !== null &&
this._browsingContextIds !== undefined &&
this._browsingContextIds.length > 0
) {
await this.bidi.unsubscribe(
'network.beforeRequestSent',
'network.responseStarted',
'network.responseCompleted',
'network.authRequired',
this._browsingContextIds,
)
} else {
await this.bidi.unsubscribe(
'network.beforeRequestSent',
'network.responseStarted',
'network.responseCompleted',
'network.authRequired',
)
}
}

@@ -324,0 +338,0 @@ }

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

toJson() {
static createReferenceValue(handle, sharedId) {
return new ReferenceValue(handle, sharedId)
}
asMap() {
let toReturn = {}

@@ -191,0 +195,0 @@ toReturn[TYPE_CONSTANT] = this.type

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

const ScriptEvent = {
MESSAGE: 'script.message',
REALM_CREATED: 'script.realmCreated',
REALM_DESTROYED: 'script.realmDestroyed',
}
/**

@@ -37,6 +43,44 @@ * Represents class to run events and commands of Script module.

class ScriptManager {
#callbackId = 0
#listener
constructor(driver) {
this._driver = driver
this.#listener = new Map()
this.#listener.set(ScriptEvent.MESSAGE, new Map())
this.#listener.set(ScriptEvent.REALM_CREATED, new Map())
this.#listener.set(ScriptEvent.REALM_DESTROYED, new Map())
}
addCallback(eventType, callback) {
const id = ++this.#callbackId
const eventCallbackMap = this.#listener.get(eventType)
eventCallbackMap.set(id, callback)
return id
}
removeCallback(id) {
let hasId = false
for (const [, callbacks] of this.#listener) {
if (callbacks.has(id)) {
callbacks.delete(id)
hasId = true
}
}
if (!hasId) {
throw Error(`Callback with id ${id} not found`)
}
}
invokeCallbacks(eventType, data) {
const callbacks = this.#listener.get(eventType)
if (callbacks) {
for (const [, callback] of callbacks) {
callback(data)
}
}
}
async init(browsingContextIds) {

@@ -256,2 +300,10 @@ if (!(await this._driver.getCapabilities()).get('webSocketUrl')) {

if (argumentValueList != null) {
let argumentParams = []
argumentValueList.forEach((argumentValue) => {
argumentParams.push(argumentValue.asMap())
})
params['arguments'] = argumentParams
}
const command = {

@@ -439,3 +491,3 @@ method: 'script.addPreloadScript',

async onMessage(callback) {
await this.subscribeAndHandleEvent('script.message', callback)
return await this.subscribeAndHandleEvent(ScriptEvent.MESSAGE, callback)
}

@@ -450,3 +502,3 @@

async onRealmCreated(callback) {
await this.subscribeAndHandleEvent('script.realmCreated', callback)
return await this.subscribeAndHandleEvent(ScriptEvent.REALM_CREATED, callback)
}

@@ -461,15 +513,14 @@

async onRealmDestroyed(callback) {
await this.subscribeAndHandleEvent('script.realmDestroyed', callback)
return await this.subscribeAndHandleEvent(ScriptEvent.REALM_DESTROYED, callback)
}
async subscribeAndHandleEvent(eventType, callback) {
if (this.browsingContextIds != null) {
await this.bidi.subscribe(eventType, this.browsingContextIds)
if (this._browsingContextIds != null) {
await this.bidi.subscribe(eventType, this._browsingContextIds)
} else {
await this.bidi.subscribe(eventType)
}
await this._on(callback)
}
async _on(callback) {
let id = this.addCallback(eventType, callback)
this.ws = await this.bidi.socket

@@ -491,6 +542,25 @@ this.ws.on('message', (event) => {

}
callback(response)
this.invokeCallbacks(eventType, response)
}
})
return id
}
async close() {
if (
this._browsingContextIds !== null &&
this._browsingContextIds !== undefined &&
this._browsingContextIds.length > 0
) {
await this.bidi.unsubscribe(
'script.message',
'script.realmCreated',
'script.realmDestroyed',
this._browsingContextIds,
)
} else {
await this.bidi.unsubscribe('script.message', 'script.realmCreated', 'script.realmDestroyed')
}
}
}

@@ -497,0 +567,0 @@

@@ -0,1 +1,13 @@

## 4.23.0
- Expose pnpm as a tool we can use
- [bidi] Fix the event unsubscribe method. Update modules to have close methods. (#14192)
- Run Node browser tests on the RBE (#14194)
- [bidi] Add methods to add/remove handlers in Script module (#14230)
- [bidi] Add source type to log entry (#14244)
- [bidi] Add dom mutation handlers (#14238)
- [bidi] Add high-level script pinning APIs (#14250)
- [bidi] Deprecate argument value wrapper class (#14251)
- Add CDP for Chrome 127 and remove 124
## 4.22.0

@@ -2,0 +14,0 @@

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

this.scriptSource_ = script
// eslint-disable-next-line
this.scriptHandle_ = crypto.randomUUID().replace(/-/gi, '')

@@ -25,0 +26,0 @@ }

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

const logInspector = require('../bidi/logInspector')
const scriptManager = require('../bidi//scriptManager')
const { LocalValue, ChannelValue } = require('../bidi/protocolValue')
const fs = require('node:fs')
const path = require('node:path')
const by = require('./by')

@@ -24,2 +29,3 @@ class Script {

#logInspector
#script

@@ -43,2 +49,9 @@ constructor(driver) {

async #initScript() {
if (this.#script !== undefined) {
return
}
this.#script = await scriptManager([], this.#driver)
}
async addJavaScriptErrorHandler(callback) {

@@ -64,4 +77,54 @@ await this.#init()

}
async addDomMutationHandler(callback) {
await this.#initScript()
let argumentValues = []
let value = LocalValue.createChannelValue(new ChannelValue('channel_name'))
argumentValues.push(value)
const filePath = path.join(__dirname, 'atoms', 'bidi-mutation-listener.js')
let mutationListener = fs.readFileSync(filePath, 'utf-8').toString()
await this.#script.addPreloadScript(mutationListener, argumentValues)
let id = await this.#script.onMessage(async (message) => {
let payload = JSON.parse(message['data']['value'])
let elements = await this.#driver.findElements({
css: '*[data-__webdriver_id=' + by.escapeCss(payload['target']) + ']',
})
if (elements.length === 0) {
return
}
let event = {
element: elements[0],
attribute_name: payload['name'],
current_value: payload['value'],
old_value: payload['oldValue'],
}
callback(event)
})
return id
}
async removeDomMutationHandler(id) {
await this.#initScript()
await this.#script.removeCallback(id)
}
async pin(script) {
await this.#initScript()
return await this.#script.addPreloadScript(script)
}
async unpin(id) {
await this.#initScript()
await this.#script.removePreloadScript(id)
}
}
module.exports = Script
{
"name": "selenium-webdriver",
"version": "4.22.0",
"version": "4.23.0",
"description": "The official WebDriver JavaScript bindings from the Selenium project",

@@ -26,25 +26,27 @@ "license": "Apache-2.0",

"dependencies": {
"@bazel/runfiles": "^5.8.1",
"jszip": "^3.10.1",
"tmp": "^0.2.3",
"ws": ">=8.16.0"
"ws": "^8.17.1"
},
"devDependencies": {
"@bazel/runfiles": "^5.8.1",
"@eslint/js": "^9.1.1",
"@eslint/js": "^9.5.0",
"clean-jsdoc-theme": "^4.3.0",
"eslint": "^9.1.0",
"eslint": "^9.5.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-mocha": "^10.4.3",
"eslint-plugin-n": "^17.2.1",
"eslint-plugin-n": "^17.9.0",
"eslint-plugin-no-only-tests": "^3.1.0",
"eslint-plugin-prettier": "^5.1.3",
"express": "^4.19.2",
"globals": "^15.0.0",
"globals": "^15.6.0",
"has-flag": "^4.0.0",
"jsdoc": "^4.0.3",
"mocha": "^10.4.0",
"mocha": "^10.5.1",
"mocha-junit-reporter": "^2.2.1",
"multer": "^1.4.5-lts.1",
"prettier": "^3.2.5",
"multer": "1.4.5-lts.1",
"prettier": "^3.3.2",
"serve-index": "^1.9.1",
"sinon": "^17.0.1"
"sinon": "^17.0.1",
"supports-color": "^9.4.0"
},

@@ -54,4 +56,3 @@ "scripts": {

"lint:fix": "eslint . --fix",
"test": "npm run lint && mocha -t 600000 --recursive test",
"test-jasmine": "bazel test //javascript/node/selenium-webdriver:tests",
"test": "bazel test //javascript/node/selenium-webdriver/...",
"generate-docs": "jsdoc --configure jsdoc_conf.json --verbose"

@@ -58,0 +59,0 @@ },

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

const fs = require('node:fs')
const path = require('node:path')
const { isatty } = require('node:tty')
const { runfiles } = require('@bazel/runfiles')
const chrome = require('../chrome')

@@ -292,2 +295,33 @@ const edge = require('../edge')

const builder = new Builder()
// Sniff the environment variables for paths to use for the common browsers
// Chrome
if ('SE_CHROMEDRIVER' in process.env) {
const found = locate(process.env.SE_CHROMEDRIVER)
const service = new chrome.ServiceBuilder(found)
builder.setChromeService(service)
}
if ('SE_CHROME' in process.env) {
const binary = locate(process.env.SE_CHROME)
const options = new chrome.Options()
options.setChromeBinaryPath(binary)
options.setAcceptInsecureCerts(true)
options.addArguments('disable-infobars', 'disable-breakpad', 'disable-dev-shm-usage', 'no-sandbox')
builder.setChromeOptions(options)
}
// Edge
// Firefox
if ('SE_GECKODRIVER' in process.env) {
const found = locate(process.env.SE_GECKODRIVER)
const service = new firefox.ServiceBuilder(found)
builder.setFirefoxService(service)
}
if ('SE_FIREFOX' in process.env) {
const binary = locate(process.env.SE_FIREFOX)
const options = new firefox.Options()
options.enableBidi()
options.setBinary(binary)
builder.setFirefoxOptions(options)
}
builder.disableEnvironmentOverrides()

@@ -510,2 +544,55 @@

function locate(fileLike) {
if (fs.existsSync(fileLike)) {
return fileLike
}
try {
return runfiles.resolve(fileLike)
} catch {
// Fall through
}
// Is the item in the workspace?
try {
return runfiles.resolveWorkspaceRelative(fileLike)
} catch {
// Fall through
}
// Find the repo mapping file
let repoMappingFile
try {
repoMappingFile = runfiles.resolve('_repo_mapping')
} catch {
throw new Error('Unable to locate (no repo mapping file): ' + fileLike)
}
const lines = fs.readFileSync(repoMappingFile, { encoding: 'utf8' }).split('\n')
// Build a map of "repo we declared we need" to "path"
const mapping = {}
for (const line of lines) {
if (line.startsWith(',')) {
const parts = line.split(',', 3)
mapping[parts[1]] = parts[2]
}
}
// Get the first segment of the path
const pathSegments = fileLike.split('/')
if (!pathSegments.length) {
throw new Error('Unable to locate ' + fileLike)
}
pathSegments[0] = mapping[pathSegments[0]] ? mapping[pathSegments[0]] : '_main'
try {
return runfiles.resolve(path.join(...pathSegments))
} catch {
// Fall through
}
throw new Error('Unable to find ' + fileLike)
}
// PUBLIC API

@@ -512,0 +599,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

SocketSocket SOC 2 Logo

Product

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

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc