webapi: add WebDriver.click for trusted testdriver clicks

Fixes 1 failing test in WPT /dom/events/Event-dispatch-redispatch.html:
"Redispatching mouseup event whose default action dispatches a click
event".

The WPT testdriver-vendor shim implemented test_driver.click() with
HTMLElement.click(), which dispatches a single untrusted click event
and no press/release, so the test saw no trusted mouseup at all and an
untrusted click. window.webdriver (the -Dwpt_extensions WebAPI) now
exposes click(element): a full trusted primary-button sequence
(pointerdown, mousedown, pointerup, mouseup, click), dispatched
synchronously so the events are observable when the testdriver promise
resolves. The shim routes test_driver.click through it, like
action_sequence already routes through webdriver.actionSequence.

Note this test (like everything testdriver-based) needs the browser
built with -Dwpt_extensions=true, otherwise window.webdriver is
undefined.

Coverage: /dom/events/Event-dispatch-redispatch.html 3/4 -> 4/4 (with a
wpt_extensions build).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Francis Bouvier
2026-07-10 19:06:51 +02:00
committed by Karl Seguin
parent b59400c836
commit cb70a911c7

View File

@@ -49,6 +49,20 @@ pub fn getComputedLabel(_: *const WebDriver, element: *Element, frame: *Frame) !
return (try axnode.getName(frame, frame.call_arena)) orelse "";
}
// Implements testdriver's `click`: a full trusted primary-button click
// sequence on the element, as a real user click would produce. Unlike
// HTMLElement.click() (a lone untrusted click event), the events are trusted
// and preceded by the pointer/mouse press and release. Dispatched
// synchronously so the events are observable when the testdriver promise
// resolves.
pub fn click(_: *const WebDriver, element: *Element, frame: *Frame) !void {
dispatchPointer(element, "pointerdown", 0, 1, frame);
dispatchMouse(element, "mousedown", 0, 1, frame);
dispatchPointer(element, "pointerup", 0, 0, frame);
dispatchMouse(element, "mouseup", 0, 0, frame);
dispatchMouse(element, "click", 0, 0, frame);
}
// Implements testdriver's `action_sequence` (the WebDriver "Perform Actions"
// command) for the renderless browser. We can't do real hit-testing, so we only
// support the subset that targets a concrete element via `origin`. Each input
@@ -333,4 +347,5 @@ pub const JsApi = struct {
pub const deleteAllCookies = bridge.function(WebDriver.deleteAllCookies, .{});
pub const getComputedLabel = bridge.function(WebDriver.getComputedLabel, .{});
pub const actionSequence = bridge.function(WebDriver.actionSequence, .{});
pub const click = bridge.function(WebDriver.click, .{});
};