Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[EXPERIMENTAL] expose testdriver + webdriver bidi #448

Closed
wants to merge 21 commits into from
Closed
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions console/console-log-logged.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>Test console log are present</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script>
promise_test(async () => {
const some_message = "SOME MESSAGE";
// Subscribe to log.entryAdded BiDi events.
await test_driver.bidi.session.subscribe("log.entryAdded");
// Add a listener for the log.entryAdded event.
const log_entry_promise = test_driver.bidi.log.entryAdded.once();
// Emit a console.log message.
console.log(some_message)
// Wait for the log.entryAdded event to be received.
const event = await log_entry_promise;
// Assert the log.entryAdded event has the expected message.
const data = event.data;
assert_equals(data.args.length, 1);
const event_message = data.args[0];
assert_equals(event_message.value, some_message);
}, "Assert log event are logged");
</script>
80 changes: 78 additions & 2 deletions resources/testdriver.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,72 @@
return pointerInteractablePaintTree.indexOf(element) !== -1;
}


/**
* @namespace {test_driver}
*/
window.test_driver = {
/**
* @namespace {bidi} - Represents `WebDriver BiDi <https://w3c.github.io/webdriver-bidi>`_ protocol.
*/
bidi: {
/**
* `session <https://w3c.github.io/webdriver-bidi/#module-session>`_ module.
*/
session: {
/**
* Subscribe to event.
*
* Events will be Matches the behaviour of the `session.subscribe
* <https://w3c.github.io/webdriver-bidi/#command-session-subscribe>`_ WebDriver BiDi command.
*
* @param {String} event - The event to subscribe to.
* @param {WindowProxy} context - Browsing context in which
* to run the call, or null for the current
* browsing context.
* @return {Promise<never>}
*/
subscribe: function (event, context = null) {
return window.test_driver_internal.bidi.session.subscribe(event, context);
}
},
/**
* `log <https://w3c.github.io/webdriver-bidi/#module-log>`_ module.
*/
log: {
/**
* `log.entryAdded <https://w3c.github.io/webdriver-bidi/#event-log-entryAdded>`_ event.
*/
entryAdded: {
/**
* Add an event listener for the `log.entryAdded
* <https://w3c.github.io/webdriver-bidi/#event-log-entryAdded>`_ event.
*
* @param callback {function(event): void} - The callback to call when the event is fired.
* @returns {function(): void} - A function to call to remove the event listener.
*/
on: function (callback) {
return window.test_driver_internal.bidi.log.entryAdded.on(callback);
},
/**
* Get a promise that resolves the next time the `log.entryAdded
* <https://w3c.github.io/webdriver-bidi/#event-log-entryAdded>`_ event is fired.
*
* @returns {Promise<Object>}
*/
once: function () {
return new Promise((resolve) => {
const remove_handle = window.test_driver_internal.bidi.log.entryAdded.on(
(event) => {
remove_handle();
resolve(event);
}
);
});
},
}
}
},

/**
* Set the context in which testharness.js is loaded
*
Expand Down Expand Up @@ -1023,7 +1084,7 @@
*/
get_virtual_sensor_information: function(sensor_type, context=null) {
return window.test_driver_internal.get_virtual_sensor_information(sensor_type, context);
}
},
};

window.test_driver_internal = {
Expand All @@ -1035,6 +1096,21 @@
*/
in_automation: false,

bidi: {
session: {
subscribe(event, context=null) {
throw new Error("subscribe() is not implemented by testdriver-vendor.js");
sadym-chromium marked this conversation as resolved.
Show resolved Hide resolved
},
},
log: {
entryAdded: {
on: function () {
throw new Error("bidi.log.entryAdded.on is not implemented by testdriver-vendor.js");
sadym-chromium marked this conversation as resolved.
Show resolved Hide resolved
}
}
}
},

async click(element, coords) {
if (this.in_automation) {
throw new Error("click() is not implemented by testdriver-vendor.js");
Expand Down
15 changes: 14 additions & 1 deletion tools/wptrunner/wptrunner/executors/actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,18 @@ def __call__(self, payload):
self.protocol.click.element(element)


class BidiSessionSubscribeAction:
name = "bidi.session.subscribe"

def __init__(self, logger, protocol):
self.logger = logger
self.protocol = protocol

def __call__(self, payload):
self.logger.debug("Subscribing to event: %s" % payload["event"])
return self.protocol.events.subscribe(payload["event"])


class DeleteAllCookiesAction:
name = "delete_all_cookies"

Expand Down Expand Up @@ -477,4 +489,5 @@ def __call__(self, payload):
CreateVirtualSensorAction,
UpdateVirtualSensorAction,
RemoveVirtualSensorAction,
GetVirtualSensorInformationAction]
GetVirtualSensorInformationAction,
BidiSessionSubscribeAction]
21 changes: 18 additions & 3 deletions tools/wptrunner/wptrunner/executors/base.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# mypy: allow-untyped-defs

import asyncio
import base64
import hashlib
import io
Expand Down Expand Up @@ -755,7 +756,7 @@ def process_action(self, url, payload):
try:
with ActionContext(self.logger, self.protocol, payload.get("context")):
try:
result = action_handler(payload)
maybe_coroutine_result = action_handler(payload)
except AttributeError as e:
# If we fail to get an attribute from the protocol presumably that's a
# ProtocolPart we don't implement
Expand All @@ -776,8 +777,22 @@ def process_action(self, url, payload):
self._send_message(cmd_id, "complete", "error")
raise
else:
self.logger.debug(f"Action {action} completed with result {result}")
return_message = {"result": result}
if asyncio.iscoroutine(maybe_coroutine_result):
async def awaited_result_coroutine():
"""
In case of the action_handler returning a coroutine, we need to await for its result and return a
coroutine with the result to be awaited by the caller.
"""
self.logger.debug(f"Action '{action}' is a coroutine. Waiting for result.")
awaited_result = await maybe_coroutine_result
self.logger.debug(f"Action {action} completed with result {awaited_result}")
self._send_message(cmd_id, "complete", "success", json.dumps({"result": awaited_result}))
return False, None

return awaited_result_coroutine()

self.logger.debug(f"Action {action} completed with result {maybe_coroutine_result}")
return_message = {"result": maybe_coroutine_result}
self._send_message(cmd_id, "complete", "success", json.dumps(return_message))

return False, None
Expand Down
5 changes: 3 additions & 2 deletions tools/wptrunner/wptrunner/executors/executorchrome.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
from .executorwebdriver import (
WebDriverCrashtestExecutor,
WebDriverFedCMProtocolPart,
WebDriverBidiProtocol,
WebDriverProtocol,
WebDriverRefTestExecutor,
WebDriverRun,
Expand Down Expand Up @@ -202,12 +203,12 @@ def confirm_idp_login(self):
self.fedcm_company_prefix + "/fedcm/confirmidplogin")


class ChromeDriverProtocol(WebDriverProtocol):
class ChromeDriverProtocol(WebDriverBidiProtocol):
implements = [
ChromeDriverFedCMProtocolPart,
ChromeDriverPrintProtocolPart,
ChromeDriverTestharnessProtocolPart,
*(part for part in WebDriverProtocol.implements
*(part for part in WebDriverBidiProtocol.implements
if part.name != ChromeDriverTestharnessProtocolPart.name and
part.name != ChromeDriverFedCMProtocolPart.name)
]
Expand Down
Loading