/* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ "use strict"; Services.scriptloader.loadSubScript( "chrome://mochitests/content/browser/remote/cdp/test/browser/head.js", this ); const { Input: I } = ChromeUtils.importESModule( "chrome://remote/content/cdp/domains/parent/Input.sys.mjs" ); const { AppInfo } = ChromeUtils.importESModule( "chrome://remote/content/shared/AppInfo.sys.mjs" ); const { alt, ctrl, meta, shift } = I.Modifier; // Map of key codes used in Input tests. const KEYCODES = { a: KeyboardEvent.DOM_VK_A, A: KeyboardEvent.DOM_VK_A, b: KeyboardEvent.DOM_VK_B, B: KeyboardEvent.DOM_VK_B, c: KeyboardEvent.DOM_VK_C, C: KeyboardEvent.DOM_VK_C, h: KeyboardEvent.DOM_VK_H, H: KeyboardEvent.DOM_VK_H, Alt: KeyboardEvent.DOM_VK_ALT, ArrowLeft: KeyboardEvent.DOM_VK_LEFT, ArrowRight: KeyboardEvent.DOM_VK_RIGHT, ArrowDown: KeyboardEvent.DOM_VK_DOWN, Backspace: KeyboardEvent.DOM_VK_BACK_SPACE, Control: KeyboardEvent.DOM_VK_CONTROL, Meta: KeyboardEvent.DM_VK_META, Shift: KeyboardEvent.DOM_VK_SHIFT, Tab: KeyboardEvent.DOM_VK_TAB, }; async function setupForInput(url) { await loadURL(url); info("Focus the input on the page"); await SpecialPowers.spawn(gBrowser.selectedBrowser, [], function () { const input = content.document.querySelector("input"); input.focus(); is(input, content.document.activeElement, "Input should be focused"); is(input.value, "", "Check input content"); is(input.selectionStart, 0, "Check position of input caret"); }); } async function withModifier(Input, modKey, mod, key) { await dispatchKeyEvent(Input, modKey, "rawKeyDown", I.Modifier[mod]); await dispatchKeyEvent(Input, key, "keyDown", I.Modifier[mod]); await dispatchKeyEvent(Input, key, "keyUp", I.Modifier[mod]); await dispatchKeyEvent(Input, modKey, "keyUp"); } function dispatchKeyEvent(Input, key, type, modifiers = 0) { info(`Send ${type} for key ${key}`); return Input.dispatchKeyEvent({ type, modifiers, windowsVirtualKeyCode: KEYCODES[key], key, }); } async function getEvents() { const events = await SpecialPowers.spawn(gBrowser.selectedBrowser, [], () => { return content.wrappedJSObject.allEvents; }); info(`Events: ${JSON.stringify(events)}`); return events; } function getInputContent() { return SpecialPowers.spawn(gBrowser.selectedBrowser, [], function () { const input = content.document.querySelector("input"); return { value: input.value, caret: input.selectionStart }; }); } function checkEvent(event, type, key, property, expectedValue) { let expected = { type, key }; expected[property] = expectedValue; checkProperties(expected, event, "Event"); } async function checkInputContent(expectedValue, expectedCaret) { const { value, caret } = await getInputContent(); is(value, expectedValue, "Check input content"); is(caret, expectedCaret, "Check position of input caret"); } function checkProperties(expectedObj, targetObj, message = "Compare objects") { for (const prop in expectedObj) { is(targetObj[prop], expectedObj[prop], message + `: check ${prop}`); } } function keyForPlatform() { // TODO add cases for other key-combinations as the need arises let primary = ctrl; let primaryKey = "Control"; if (AppInfo.isMac) { primary = alt; primaryKey = "Alt"; } return { primary, primaryKey }; } async function sendTextKey(Input, key, modifiers = 0) { await dispatchKeyEvent(Input, key, "keyDown", modifiers); await dispatchKeyEvent(Input, key, "keyUp", modifiers); } async function sendText(Input, text) { for (const sym of text) { await sendTextKey(Input, sym); } } async function sendRawKey(Input, key, modifiers = 0) { await dispatchKeyEvent(Input, key, "rawKeyDown", modifiers); await dispatchKeyEvent(Input, key, "keyUp", modifiers); } async function checkBackspace(Input, expected, modifiers = 0) { info("Send Backspace"); await sendRawKey(Input, "Backspace", modifiers); await checkInputContent(expected, expected.length); } async function resetEvents() { await SpecialPowers.spawn(gBrowser.selectedBrowser, [], () => { content.wrappedJSObject.resetEvents(); const events = content.wrappedJSObject.allEvents; is(events.length, 0, "List of events should be empty"); }); } function resetInput(value = "") { return SpecialPowers.spawn(gBrowser.selectedBrowser, [value], function (arg) { const input = content.document.querySelector("input"); input.value = arg; input.focus(); }); }