Files
ladybird/Tests/LibWeb/Text/input/wpt-import/resources/testdriver-vendor.js
Jelle Raaijmakers acd38ad795 Tests/LibWeb: Implement action_sequence in testdriver-vendor.js
This implements WebDriver Actions API support for key sequences with
modifier tracking in our testdriver-vendor.js. The action_sequence
function processes key sources, tracks Shift/Ctrl/Alt/Meta state across
events, and dispatches keys with the appropriate modifiers via
Internals.sendText().

This allows us to pass WPT tests that make use of that API in our own
test-web runner.
2026-01-23 14:21:35 +01:00

78 lines
2.5 KiB
JavaScript

window.test_driver_internal.click = function(element) {
const boundingRect = element.getBoundingClientRect();
const centerPoint = {
x: boundingRect.left + boundingRect.width / 2,
y: boundingRect.top + boundingRect.height / 2
};
window.internals.click(centerPoint.x, centerPoint.y);
return Promise.resolve();
};
window.test_driver_internal.send_keys = function(element, keys) {
window.internals.sendText(element, keys);
return Promise.resolve();
}
window.test_driver_internal.get_computed_label = async function(element) {
return await window.internals.getComputedLabel(element);
};
window.test_driver_internal.get_computed_role = async function(element) {
return await window.internals.getComputedRole(element);
};
window.test_driver_internal.action_sequence = function(actions, context) {
// Modifier key codes from WebDriver spec
const SHIFT = "\uE008";
const CTRL = "\uE009";
const ALT = "\uE00A";
const META = "\uE03D";
// Modifier flags matching Internals.idl
const MOD_SHIFT = 4;
const MOD_CTRL = 2;
const MOD_ALT = 1;
const MOD_SUPER = 8;
let modifiers = 0;
const target = document.activeElement;
// Collect all key actions with their tick index
const tickActions = [];
for (const source of actions) {
if (source.type !== "key" || !source.actions) {
continue;
}
for (let tick = 0; tick < source.actions.length; tick++) {
const action = source.actions[tick];
if (action.type !== "pause") {
tickActions.push({ tick, action });
}
}
}
// Sort by tick index and process
tickActions.sort((a, b) => a.tick - b.tick);
for (const { action } of tickActions) {
const key = action.value;
const isKeyDown = action.type === "keyDown";
// Update modifier state
if (key === SHIFT) {
modifiers = isKeyDown ? (modifiers | MOD_SHIFT) : (modifiers & ~MOD_SHIFT);
} else if (key === CTRL) {
modifiers = isKeyDown ? (modifiers | MOD_CTRL) : (modifiers & ~MOD_CTRL);
} else if (key === ALT) {
modifiers = isKeyDown ? (modifiers | MOD_ALT) : (modifiers & ~MOD_ALT);
} else if (key === META) {
modifiers = isKeyDown ? (modifiers | MOD_SUPER) : (modifiers & ~MOD_SUPER);
} else if (isKeyDown) {
// For non-modifier keys, only send on keyDown
window.internals.sendText(target, key, modifiers);
}
}
return Promise.resolve();
};