Skip to content

Commit

Permalink
[bidi][js] Add methods to add/remove handlers in Script module (#14230)
Browse files Browse the repository at this point in the history
  • Loading branch information
pujagani authored Jul 5, 2024
1 parent 5e8d6a1 commit 425ed87
Showing 1 changed file with 62 additions and 9 deletions.
71 changes: 62 additions & 9 deletions javascript/node/selenium-webdriver/bidi/scriptManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,58 @@ const { RemoteValue } = require('./protocolValue')
const { Source } = require('./scriptTypes')
const { WebDriverError } = require('../lib/error')

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

/**
* Represents class to run events and commands of Script module.
* Described in https://w3c.github.io/webdriver-bidi/#module-script.
* @class
*/
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) {
Expand Down Expand Up @@ -251,6 +295,14 @@ class ScriptManager {
params.contexts = new Array(this._browsingContextIds)
}

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

const command = {
method: 'script.addPreloadScript',
params,
Expand Down Expand Up @@ -433,7 +485,7 @@ class ScriptManager {
* @returns {Promise<void>} - A promise that resolves when the subscription is successful.
*/
async onMessage(callback) {
await this.subscribeAndHandleEvent('script.message', callback)
return await this.subscribeAndHandleEvent(ScriptEvent.MESSAGE, callback)
}

/**
Expand All @@ -443,7 +495,7 @@ class ScriptManager {
* @returns {Promise<void>} - A promise that resolves when the subscription is successful.
*/
async onRealmCreated(callback) {
await this.subscribeAndHandleEvent('script.realmCreated', callback)
return await this.subscribeAndHandleEvent(ScriptEvent.REALM_CREATED, callback)
}

/**
Expand All @@ -453,19 +505,18 @@ class ScriptManager {
* @returns {Promise<void>} - A promise that resolves when the subscription is successful.
*/
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
this.ws.on('message', (event) => {
const { params } = JSON.parse(Buffer.from(event.toString()))
Expand All @@ -482,9 +533,11 @@ class ScriptManager {
response = params.realm
}
}
callback(response)
this.invokeCallbacks(eventType, response)
}
})

return id
}

async close() {
Expand Down

0 comments on commit 425ed87

Please sign in to comment.