Skip to content

Commit

Permalink
Merge branch 'trunk' into performance-improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
iampopovich authored Jun 20, 2024
2 parents 27ca016 + 8960ff0 commit 0dd4c1e
Show file tree
Hide file tree
Showing 7 changed files with 188 additions and 12 deletions.
1 change: 1 addition & 0 deletions .github/workflows/ci-javascript.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,5 @@ jobs:
bazel test
--flaky_test_attempts 3
--test_tag_filters ${{ matrix.browser }}
--local_test_jobs 1
//javascript/node/...
16 changes: 8 additions & 8 deletions common/repositories.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -199,8 +199,8 @@ js_library(

http_archive(
name = "linux_chrome",
url = "https://storage.googleapis.com/chrome-for-testing-public/126.0.6478.61/linux64/chrome-linux64.zip",
sha256 = "14492d3cfe33cb11d4cc310321182ebf839d33687494c0bb528b05225b9b5f0c",
url = "https://storage.googleapis.com/chrome-for-testing-public/126.0.6478.62/linux64/chrome-linux64.zip",
sha256 = "6f42045c9134bdd3cfcea03fb54876ad061da998cabd624c92a25ac6811cd737",
build_file_content = """
load("@aspect_rules_js//js:defs.bzl", "js_library")
package(default_visibility = ["//visibility:public"])
Expand All @@ -221,8 +221,8 @@ js_library(

http_archive(
name = "mac_chrome",
url = "https://storage.googleapis.com/chrome-for-testing-public/126.0.6478.61/mac-x64/chrome-mac-x64.zip",
sha256 = "5b7753cc0102151c8e162c4ed66df8303e390d90ae193a290db1c406cf0fa644",
url = "https://storage.googleapis.com/chrome-for-testing-public/126.0.6478.62/mac-x64/chrome-mac-x64.zip",
sha256 = "be21f6b9387c6e52c318b60379291959693889e27c3e64111e95135ecffa82ad",
strip_prefix = "chrome-mac-x64",
patch_cmds = [
"mv 'Google Chrome for Testing.app' Chrome.app",
Expand All @@ -243,8 +243,8 @@ js_library(

http_archive(
name = "linux_chromedriver",
url = "https://storage.googleapis.com/chrome-for-testing-public/126.0.6478.61/linux64/chromedriver-linux64.zip",
sha256 = "eef5a27798bd6cecae18bdaff64773bf6c96d99a9634d6434127120eb89ac713",
url = "https://storage.googleapis.com/chrome-for-testing-public/126.0.6478.62/linux64/chromedriver-linux64.zip",
sha256 = "a304e692480c726bae846bf6dee36316305d0b8f4826dfafeab8d6bbbc6e7214",
strip_prefix = "chromedriver-linux64",
build_file_content = """
load("@aspect_rules_js//js:defs.bzl", "js_library")
Expand All @@ -261,8 +261,8 @@ js_library(

http_archive(
name = "mac_chromedriver",
url = "https://storage.googleapis.com/chrome-for-testing-public/126.0.6478.61/mac-x64/chromedriver-mac-x64.zip",
sha256 = "3af4643bf9815ce93722a66dbe32b33ac04f05a673abe60e6fffd2b17b6007d9",
url = "https://storage.googleapis.com/chrome-for-testing-public/126.0.6478.62/mac-x64/chromedriver-mac-x64.zip",
sha256 = "05665a6b5fb71141b5d519998e36f01b650f661942a56dd7f6b929896ae38333",
strip_prefix = "chromedriver-mac-x64",
build_file_content = """
load("@aspect_rules_js//js:defs.bzl", "js_library")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -373,13 +373,16 @@ private Map<String, String> getVideoContainerEnvVars(
// Capabilities set to env vars with higher precedence
setCapsToEnvVars(sessionRequestCapabilities, envVars);
envVars.put("DISPLAY_CONTAINER_NAME", containerIp);
Optional<String> testName = ofNullable(getTestName(sessionRequestCapabilities));
testName.ifPresent(name -> envVars.put("SE_VIDEO_FILE_NAME", String.format("%s.mp4", name)));
Optional<String> videoName =
ofNullable(getVideoFileName(sessionRequestCapabilities, "se:videoName"))
.or(() -> ofNullable(getVideoFileName(sessionRequestCapabilities, "se:name")));
videoName.ifPresent(name -> envVars.put("SE_VIDEO_FILE_NAME", String.format("%s.mp4", name)));
return envVars;
}

private String getTestName(Capabilities sessionRequestCapabilities) {
Optional<Object> testName = ofNullable(sessionRequestCapabilities.getCapability("se:name"));
private String getVideoFileName(Capabilities sessionRequestCapabilities, String capabilityName) {
Optional<Object> testName =
ofNullable(sessionRequestCapabilities.getCapability(capabilityName));
if (testName.isPresent()) {
String name = testName.get().toString();
if (!name.isEmpty()) {
Expand Down
6 changes: 6 additions & 0 deletions javascript/node/selenium-webdriver/bidi/logInspector.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,17 @@ class LogInspector {
}

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) {
Expand Down
63 changes: 63 additions & 0 deletions javascript/node/selenium-webdriver/lib/script.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// 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 logInspector = require('../bidi/logInspector')

class Script {
#driver
#logInspector

constructor(driver) {
this.#driver = driver
}

// This should be done in the constructor.
// But since it needs to call async methods we cannot do that in the constructor.
// We can have a separate async method that initialises the Script instance.
// However, that pattern does not allow chaining the methods as we would like the user to use it.
// Since it involves awaiting to get the instance and then another await to call the method.
// Using this allows the user to do this "await driver.script().addJavaScriptErrorHandler(callback)"
async #init() {
if (this.#logInspector !== undefined) {
return
}
this.#logInspector = await logInspector(this.#driver)
}

async addJavaScriptErrorHandler(callback) {
await this.#init()
return await this.#logInspector.onJavascriptException(callback)
}

async removeJavaScriptErrorHandler(id) {
await this.#init()
await this.#logInspector.removeCallback(id)
}

async addConsoleMessageHandler(callback) {
await this.#init()
return this.#logInspector.onConsoleEntry(callback)
}

async removeConsoleMessageHandler(id) {
await this.#init()

await this.#logInspector.removeCallback(id)
}
}

module.exports = Script
12 changes: 12 additions & 0 deletions javascript/node/selenium-webdriver/lib/webdriver.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ const { isObject } = require('./util')
const BIDI = require('../bidi')
const { PinnedScript } = require('./pinnedScript')
const JSZip = require('jszip')
const Script = require('./script')

// Capability names that are defined in the W3C spec.
const W3C_CAPABILITY_NAMES = new Set([
Expand Down Expand Up @@ -654,6 +655,7 @@ function filterNonW3CCaps(capabilities) {
* @implements {IWebDriver}
*/
class WebDriver {
#script = undefined
/**
* @param {!(./session.Session|IThenable<!./session.Session>)} session Either
* a known session or a promise that will be resolved to a session.
Expand Down Expand Up @@ -1104,6 +1106,16 @@ class WebDriver {
return new TargetLocator(this)
}

script() {
// The Script calls the LogInspector which maintains state of the callbacks.
// Returning a new instance of the same driver will not work while removing callbacks.
if (this.#script === undefined) {
this.#script = new Script(this)
}

return this.#script
}

validatePrintPageParams(keys, object) {
let page = {}
let margin = {}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
// 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.

'use strict'

const assert = require('node:assert')
const { Browser } = require('../../')
const { Pages, suite } = require('../../lib/test')
const { until } = require('../../index')

suite(
function (env) {
let driver

beforeEach(async function () {
driver = await env.builder().build()
})

afterEach(async function () {
await driver.quit()
})

function delay(ms) {
return new Promise((resolve) => setTimeout(resolve, ms))
}

describe('script()', function () {
it('can listen to console log', async function () {
let log = null
const handler = await driver.script().addConsoleMessageHandler((logEntry) => {
log = logEntry
})

await driver.get(Pages.logEntryAdded)
await driver.findElement({ id: 'consoleLog' }).click()

await delay(3000)

assert.equal(log.text, 'Hello, world!')
assert.equal(log.realm, null)
assert.equal(log.type, 'console')
assert.equal(log.level, 'info')
assert.equal(log.method, 'log')
assert.equal(log.args.length, 1)
await driver.script().removeConsoleMessageHandler(handler)
})

it('can listen to javascript error', async function () {
let log = null
const handler = await driver.script().addJavaScriptErrorHandler((logEntry) => {
log = logEntry
})

await driver.get(Pages.logEntryAdded)
await driver.findElement({ id: 'jsException' }).click()

await delay(3000)

assert.equal(log.text, 'Error: Not working')
assert.equal(log.type, 'javascript')
assert.equal(log.level, 'error')

await driver.script().removeJavaScriptErrorHandler(handler)
})

it('throws an error while removing a handler that does not exist', async function () {
try {
await driver.script().removeJavaScriptErrorHandler(10)
assert.fail('Expected error not thrown. Non-existent handler cannot be removed')
} catch (e) {
assert.strictEqual(e.message, 'Callback with id 10 not found')
}
})
})
},
{ browsers: [Browser.FIREFOX, Browser.CHROME, Browser.EDGE] },
)

0 comments on commit 0dd4c1e

Please sign in to comment.