Path: blob/trunk/javascript/selenium-webdriver/lib/script.js
2884 views
// Licensed to the Software Freedom Conservancy (SFC) under one1// or more contributor license agreements. See the NOTICE file2// distributed with this work for additional information3// regarding copyright ownership. The SFC licenses this file4// to you under the Apache License, Version 2.0 (the5// "License"); you may not use this file except in compliance6// with the License. You may obtain a copy of the License at7//8// http://www.apache.org/licenses/LICENSE-2.09//10// Unless required by applicable law or agreed to in writing,11// software distributed under the License is distributed on an12// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY13// KIND, either express or implied. See the License for the14// specific language governing permissions and limitations15// under the License.1617const logInspector = require('../bidi/logInspector')18const scriptManager = require('../bidi//scriptManager')19const { LocalValue, ChannelValue } = require('../bidi/protocolValue')20const fs = require('node:fs')21const path = require('node:path')22const by = require('./by')2324class Script {25#driver26#logInspector27#script2829constructor(driver) {30this.#driver = driver31}3233// This should be done in the constructor.34// But since it needs to call async methods we cannot do that in the constructor.35// We can have a separate async method that initialises the Script instance.36// However, that pattern does not allow chaining the methods as we would like the user to use it.37// Since it involves awaiting to get the instance and then another await to call the method.38// Using this allows the user to do this "await driver.script().addJavaScriptErrorHandler(callback)"39async #init() {40if (this.#logInspector !== undefined) {41return42}43this.#logInspector = await logInspector(this.#driver)44}4546async #initScript() {47if (this.#script !== undefined) {48return49}50this.#script = await scriptManager([], this.#driver)51}5253async addJavaScriptErrorHandler(callback) {54await this.#init()55return await this.#logInspector.onJavascriptException(callback)56}5758async removeJavaScriptErrorHandler(id) {59await this.#init()60await this.#logInspector.removeCallback(id)61}6263async addConsoleMessageHandler(callback) {64await this.#init()65return this.#logInspector.onConsoleEntry(callback)66}6768async removeConsoleMessageHandler(id) {69await this.#init()7071await this.#logInspector.removeCallback(id)72}7374async addDomMutationHandler(callback) {75await this.#initScript()7677let argumentValues = []78let value = LocalValue.createChannelValue(new ChannelValue('channel_name'))79argumentValues.push(value)8081const filePath = path.join(__dirname, 'atoms', 'bidi-mutation-listener.js')8283let mutationListener = fs.readFileSync(filePath, 'utf-8').toString()84await this.#script.addPreloadScript(mutationListener, argumentValues)8586let id = await this.#script.onMessage(async (message) => {87let payload = JSON.parse(message['data']['value'])88let elements = await this.#driver.findElements({89css: '*[data-__webdriver_id=' + by.escapeCss(payload['target']) + ']',90})9192if (elements.length === 0) {93return94}9596let event = {97element: elements[0],98attribute_name: payload['name'],99current_value: payload['value'],100old_value: payload['oldValue'],101}102callback(event)103})104105return id106}107108async removeDomMutationHandler(id) {109await this.#initScript()110111await this.#script.removeCallback(id)112}113114async pin(script) {115await this.#initScript()116return await this.#script.addPreloadScript(script)117}118119async unpin(id) {120await this.#initScript()121await this.#script.removePreloadScript(id)122}123124async execute(script, ...args) {125await this.#initScript()126127const browsingContextId = await this.#driver.getWindowHandle()128129const argumentList = []130131args.forEach((arg) => {132argumentList.push(LocalValue.getArgument(arg))133})134135const response = await this.#script.callFunctionInBrowsingContext(browsingContextId, script, true, argumentList)136137return response.result138}139}140141module.exports = Script142143144