author | Oana Pop Rus <opoprus@mozilla.com> |
Fri, 18 Oct 2019 18:55:01 +0300 | |
changeset 498224 | b92c29aab7c6442c3886adef72b301e31c07a6b2 |
parent 498223 | 10da1f86b789ba3b559da74030f1c317a27c4be7 |
child 498225 | d24926469e8fa45a589bbc1e74aa99245f6844f0 |
push id | 36708 |
push user | nbeleuzu@mozilla.com |
push date | Fri, 18 Oct 2019 21:48:04 +0000 |
treeherder | mozilla-central@27bbc1fba015 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
bugs | 1563206 |
milestone | 71.0a1 |
backs out | 1ce1b20dcc2015fb6a4a244bb851cafec84bb184 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/remote/doc/Testing.md +++ b/remote/doc/Testing.md @@ -27,17 +27,17 @@ Browser chrome tests -------------------- We also have a set of functional [browser chrome] tests located under _remote/test/browser_: % ./mach mochitest remote/test/browser/browser_cdp.js The functional tests will appear under the `M` (for _mochitest_) -category in the `remote` jobs on Treeherder. +category in the `bc` (_browser-chrome_) jobs on Treeherder. As the functional tests will sporadically pop up new Firefox application windows, a helpful tip is to run them in [headless mode]: % ./mach mochitest --headless remote/test/browser The `--headless` flag is equivalent to setting the `MOZ_HEADLESS`
--- a/remote/domains/parent/Input.jsm +++ b/remote/domains/parent/Input.jsm @@ -2,17 +2,16 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ "use strict"; var EXPORTED_SYMBOLS = ["Input"]; const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm"); - const { Domain } = ChromeUtils.import( "chrome://remote/content/domains/Domain.jsm" ); class Input extends Domain { // commands /** @@ -22,26 +21,21 @@ class Input extends Domain { * - autoRepeat (not supported) * - code (not supported) * - key * - isKeypad (not supported) * - location (not supported) * - modifiers * - text (not supported) * - type - * - unmodifiedText (not supported) + * - unmodifiedTest (not supported) * - windowsVirtualKeyCode - * - nativeVirtualKeyCode (not supported) - * - keyIdentifier (not supported) - * - isSystemKey (not supported) */ async dispatchKeyEvent(options) { - // missing code, text, unmodifiedText, autorepeat, location, iskeypad const { key, modifiers, type, windowsVirtualKeyCode } = options; - const { alt, ctrl, meta, shift } = Input.Modifier; let domType; if (type == "keyDown" || type == "rawKeyDown") { // 'rawKeyDown' is passed as type by puppeteer for all non-text keydown events: // See https://github.com/GoogleChrome/puppeteer/blob/2d99d85976dcb28cc6e3bad4b6a00cd61a67a2cf/lib/Input.js#L52 // For now we simply map rawKeyDown to keydown. domType = "keydown"; } else if (type == "keyUp" || type == "char") { @@ -63,58 +57,75 @@ class Input extends Domain { if (type == "char") { // type == "char" is used when doing `await page.keyboard.type( 'I’m a list' );` // the ’ character will be calling dispatchKeyEvent only once with type=char. EventUtils.synthesizeKey(key, {}, browserWindow); } else { // Non printable keys should be prefixed with `KEY_` const eventUtilsKey = key.length == 1 ? key : "KEY_" + key; - const eventInfo = { - keyCode: windowsVirtualKeyCode, - type: domType, - altKey: !!(modifiers & alt), - ctrlKey: !!(modifiers & ctrl), - metaKey: !!(modifiers & meta), - shiftKey: !!(modifiers & shift), - }; - EventUtils.synthesizeKey(eventUtilsKey, eventInfo, browserWindow); + EventUtils.synthesizeKey( + eventUtilsKey, + { + keyCode: windowsVirtualKeyCode, + type: domType, + altKey: !!(modifiers & 1), + ctrlKey: !!(modifiers & 2), + metaKey: !!(modifiers & 4), + shiftKey: !!(modifiers & 8), + }, + browserWindow + ); } await this.executeInChild("waitForContentEvent", eventId); } async dispatchMouseEvent({ type, button, x, y, modifiers, clickCount }) { - const { alt, ctrl, meta, shift } = Input.Modifier; - if (type == "mousePressed") { type = "mousedown"; } else if (type == "mouseReleased") { type = "mouseup"; } else if (type == "mouseMoved") { type = "mousemove"; } else { throw new Error(`Mouse type is not supported: ${type}`); } if (type === "mousedown" && button === "right") { type = "contextmenu"; } - const buttonID = Input.Button[button] || Input.Button.left; + if (button == undefined || button == "none" || button == "left") { + button = 0; + } else if (button == "middle") { + button = 1; + } else if (button == "right") { + button = 2; + } else if (button == "back") { + button = 3; + } else if (button == "forward") { + button = 4; + } else { + throw new Error(`Mouse button is not supported: ${button}`); + } + + // Gutenberg test packages/e2e-tests/specs/blocks/list.test.js: + // "can be created by converting multiple paragraphs" + // Works better with EventUtils, in order to make the Shift+Click to work const { browser } = this.session.target; const currentWindow = browser.ownerGlobal; const EventUtils = this._getEventUtils(currentWindow); EventUtils.synthesizeMouse(browser, x, y, { type, - button: buttonID, + button, clickCount: clickCount || 1, - altKey: !!(modifiers & alt), - ctrlKey: !!(modifiers & ctrl), - metaKey: !!(modifiers & meta), - shiftKey: !!(modifiers & shift), + altKey: !!(modifiers & 1), + ctrlKey: !!(modifiers & 2), + metaKey: !!(modifiers & 4), + shiftKey: !!(modifiers & 8), }); } /** * Memoized EventUtils getter. */ _getEventUtils(win) { if (!this._eventUtils) { @@ -127,23 +138,8 @@ class Input extends Domain { Services.scriptloader.loadSubScript( "chrome://remote/content/external/EventUtils.js", this._eventUtils ); } return this._eventUtils; } } - -Input.Button = { - left: 0, - middle: 1, - right: 2, - back: 3, - forward: 4, -}; - -Input.Modifier = { - alt: 1, - ctrl: 2, - meta: 4, - shift: 8, -};
--- a/remote/test/browser/browser.ini +++ b/remote/test/browser/browser.ini @@ -1,16 +1,15 @@ [DEFAULT] tags = remote subsuite = remote prefs = remote.enabled=true support-files = chrome-remote-interface.js doc_input_dispatchKeyEvent_race.html - doc_input_events.html doc_network_requestWillBeSent.html file_network_requestWillBeSent.js head.js [browser_cdp.js] [browser_input_dispatchKeyEvent.js] [browser_input_dispatchKeyEvent_race.js] [browser_input_dispatchMouseEvent.js]
--- a/remote/test/browser/browser_input_dispatchKeyEvent.js +++ b/remote/test/browser/browser_input_dispatchKeyEvent.js @@ -1,431 +1,154 @@ /* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ "use strict"; -const { Input: I } = ChromeUtils.import( - "chrome://remote/content/domains/parent/Input.jsm" -); - -const { alt, ctrl, meta, shift } = I.Modifier; +// Basic test for dispatch key event API with input type text // Map of key codes used in this test. 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, + a: 65, + Backspace: 8, + h: 72, + H: 72, + AltLeft: 18, + ArrowLeft: 37, + ArrowRight: 39, }; +// Modifier for move forward shortcut is CTRL+RightArrow on Linux/Windows, ALT+RightArrow +// on Mac. const isMac = Services.appinfo.OS === "Darwin"; +const ALT_MODIFIER = 1; +const CTRL_MODIFIER = 2; +const ARROW_MODIFIER = isMac ? ALT_MODIFIER : CTRL_MODIFIER; -const PAGE_URL = - "http://example.com/browser/remote/test/browser/doc_input_events.html"; +add_task(async function() { + // The selectionchange event was flagged behind dom.select_events.textcontrols.enabled, + // which is only true on Nightly and Local builds. Force the pref to true so that + // the test passes on all channels. See Bug 1309628 for more details. + info("Enable selectionchange events on input elements"); + await new Promise(resolve => { + const options = { + set: [["dom.select_events.textcontrols.enabled", true]], + }; + SpecialPowers.pushPrefEnv(options, resolve); + }); -add_task(async function testTypingPrintableCharacters() { - const { client } = await setupForInput(toDataURL("<input>")); + const { client, tab } = await setupForURL(toDataURL("<input>")); + is(gBrowser.selectedTab, tab, "Selected tab is the target tab"); + const { Input } = client; + info("Focus the input on the page"); + await ContentTask.spawn(gBrowser.selectedBrowser, null, function() { + const input = content.document.querySelector("input"); + input.focus(); + is(input, content.document.activeElement, "Input should be focused"); + }); + await checkInputContent("", 0); + info("Write 'h'"); await sendTextKey(Input, "h"); await checkInputContent("h", 1); info("Write 'H'"); await sendTextKey(Input, "H"); await checkInputContent("hH", 2); info("Send char type event for char [’]"); await Input.dispatchKeyEvent({ type: "char", modifiers: 0, key: "’", }); await checkInputContent("hH’", 3); - await teardown(client); -}); - -add_task(async function testArrowKeys() { - const { client } = await setupForInput(toDataURL("<input>")); - const { Input } = client; - - await sendText(Input, "hH’"); info("Send Left"); - await sendRawKey(Input, "ArrowLeft"); + await sendArrowKey(Input, "ArrowLeft"); await checkInputContent("hH’", 2); info("Write 'a'"); await sendTextKey(Input, "a"); await checkInputContent("hHa’", 3); info("Send Left"); - await sendRawKey(Input, "ArrowLeft"); + await sendArrowKey(Input, "ArrowLeft"); await checkInputContent("hHa’", 2); info("Send Left"); - await sendRawKey(Input, "ArrowLeft"); + await sendArrowKey(Input, "ArrowLeft"); await checkInputContent("hHa’", 1); info("Write 'a'"); await sendTextKey(Input, "a"); await checkInputContent("haHa’", 2); - info("Send ALT/CONTROL + Right"); - let modCode = isMac ? alt : ctrl; - let modKey = isMac ? "Alt" : "Control"; - await dispatchKeyEvent(Input, modKey, "rawKeyDown", modCode); - await dispatchKeyEvent(Input, "ArrowRight", "rawKeyDown", modCode); - await dispatchKeyEvent(Input, "ArrowRight", "keyUp"); - await dispatchKeyEvent(Input, modKey, "keyUp"); + info("Send ALT/CTRL + Right"); + await sendArrowKey(Input, "ArrowRight", ARROW_MODIFIER); await checkInputContent("haHa’", 5); - await teardown(client); -}); - -add_task(async function testBackspace() { - const { client } = await setupForInput(toDataURL("<input>")); - const { Input } = client; - - await sendText(Input, "haHa’"); - info("Delete every character in the input"); - await checkBackspace(Input, "haHa"); - await checkBackspace(Input, "haH"); - await checkBackspace(Input, "ha"); - await checkBackspace(Input, "h"); - await checkBackspace(Input, ""); - - await teardown(client); -}); - -add_task(async function testShiftSelect() { - const { client } = await setupForInput(toDataURL("<input>")); - const { Input } = client; - await resetInput("word 2 word3"); - - info("Send Shift + Left (select one char to the left)"); - await dispatchKeyEvent(Input, "Shift", "rawKeyDown", shift); - await sendRawKey(Input, "ArrowLeft", shift); - await sendRawKey(Input, "ArrowLeft", shift); - await sendRawKey(Input, "ArrowLeft", shift); - info("(deleteContentBackward)"); - await checkBackspace(Input, "word 2 wo"); - await dispatchKeyEvent(Input, "Shift", "keyUp"); - - await resetInput("word 2 wo"); - info("Send Shift + Left (select one char to the left)"); - await dispatchKeyEvent(Input, "Shift", "rawKeyDown", shift); - await sendRawKey(Input, "ArrowLeft", shift); - await sendRawKey(Input, "ArrowLeft", shift); - await sendTextKey(Input, "H"); - await checkInputContent("word 2 H", 8); - await dispatchKeyEvent(Input, "Shift", "keyUp"); - - await teardown(client); -}); - -add_task(async function testSelectWord() { - const { client } = await setupForInput(toDataURL("<input>")); - const { Input } = client; - await resetInput("word 2 word3"); - - info("Send Shift + Ctrl/Alt + Left (select one word to the left)"); - const { primary, primaryKey } = keyForPlatform(); - const combined = shift | primary; - await dispatchKeyEvent(Input, "Shift", "rawKeyDown", shift); - await dispatchKeyEvent(Input, primaryKey, "rawKeyDown", combined); - await sendRawKey(Input, "ArrowLeft", combined); - await sendRawKey(Input, "ArrowLeft", combined); - await dispatchKeyEvent(Input, "Shift", "keyUp", primary); - await dispatchKeyEvent(Input, primaryKey, "keyUp"); - info("(deleteContentBackward)"); - await checkBackspace(Input, "word "); - - await teardown(client); -}); + await sendBackspace(Input, "haHa"); + await sendBackspace(Input, "haH"); + await sendBackspace(Input, "ha"); + await sendBackspace(Input, "h"); + await sendBackspace(Input, ""); -add_task(async function testSelectDelete() { - const { client } = await setupForInput(toDataURL("<input>")); - const { Input } = client; - await resetInput("word 2 word3"); - - info("Send Ctrl/Alt + Backspace (deleteWordBackward)"); - const { primary, primaryKey } = keyForPlatform(); - await dispatchKeyEvent(Input, primaryKey, "rawKeyDown", primary); - await checkBackspace(Input, "word 2 ", primary); - await dispatchKeyEvent(Input, primaryKey, "keyUp"); - - await resetInput("word 2 "); - await sendText(Input, "word4"); - await sendRawKey(Input, "ArrowLeft"); - await sendRawKey(Input, "ArrowLeft"); - await checkInputContent("word 2 word4", 10); - - if (isMac) { - info("Send Meta + Backspace (deleteSoftLineBackward)"); - await dispatchKeyEvent(Input, "Meta", "rawKeyDown", meta); - await sendRawKey(Input, "Backspace", meta); - const { value, caret } = await getInputContent(); - await dispatchKeyEvent(Input, "Meta", "keyUp"); - todo_is(value, "d4", "Meta + Backspace should delete line backward"); - todo_is(caret, 0, "Check position after Meta + Backspace"); - } - - await teardown(client); -}); + await client.close(); + ok(true, "The client is closed"); -add_task(async function testShiftEvents() { - const { client } = await setupForInput(PAGE_URL); - const { Input } = client; - await resetEvents(); + BrowserTestUtils.removeTab(tab); - await withModifier(Input, "Shift", "shift", "A"); - await checkInputContent("A", 1); - let events = await getEvents(); - checkEvent(events[0], "keydown", "Shift", "shift", true); - checkEvent(events[1], "keydown", "A", "shift", true); - checkEvent(events[2], "keypress", "A", "shift", true); - checkProperties({ data: "A", inputType: "insertText" }, events[3]); - checkEvent(events[4], "keyup", "A", "shift", true); - checkEvent(events[5], "keyup", "Shift", "shift", false); - await resetEvents(); - - await withModifier(Input, "Shift", "shift", "Enter"); - events = await getEvents(); - checkEvent(events[2], "keypress", "Enter", "shift", true); - await resetEvents(); - - await withModifier(Input, "Shift", "shift", "Tab"); - events = await getEvents(); - checkEvent(events[1], "keydown", "Tab", "shift", true); - await ContentTask.spawn(gBrowser.selectedBrowser, null, function() { - const input = content.document.querySelector("input"); - isnot(input, content.document.activeElement, "input should lose focus"); - }); - - await teardown(client); + await RemoteAgent.close(); }); -add_task(async function testAltEvents() { - const { client } = await setupForInput(PAGE_URL); - const { Input } = client; - - await withModifier(Input, "Alt", "alt", "a"); - if (isMac) { - await checkInputContent("a", 1); - } else { - await checkInputContent("", 0); - } - let events = await getEvents(); - checkEvent(events[1], "keydown", "a", "alt", true); - checkEvent(events[events.length - 1], "keyup", "Alt", "alt", false); - await teardown(client); -}); - -add_task(async function testControlEvents() { - const { client } = await setupForInput(PAGE_URL); - const { Input } = client; - - await withModifier(Input, "Control", "ctrl", "`"); - let events = await getEvents(); - // no keypress or input event - checkEvent(events[1], "keydown", "`", "ctrl", true); - checkEvent(events[events.length - 1], "keyup", "Control", "ctrl", false); - await teardown(client); -}); - -add_task(async function testMetaEvents() { - if (!isMac) { - return; - } - const { client } = await setupForInput(PAGE_URL); - const { Input } = client; - - await withModifier(Input, "Meta", "meta", "a"); - let events = await getEvents(); - // no keypress or input event - checkEvent(events[1], "keydown", "a", "meta", true); - checkEvent(events[events.length - 1], "keyup", "Meta", "meta", false); - - await teardown(client); -}); - -add_task(async function testCtrlShiftArrows() { - const { client } = await setupForURL( - toDataURL('<select multiple size="3"><option>a<option>b<option>c</select>') - ); - const { Input } = client; - - await ContentTask.spawn(gBrowser.selectedBrowser, null, function() { - const select = content.document.querySelector("select"); - select.selectedIndex = 0; - select.focus(); - }); - - const combined = shift | ctrl; - await dispatchKeyEvent(Input, "Control", "rawKeyDown", shift); - await dispatchKeyEvent(Input, "Shift", "rawKeyDown", combined); - await sendRawKey(Input, "ArrowDown", combined); - await dispatchKeyEvent(Input, "Control", "keyUp", shift); - await dispatchKeyEvent(Input, "Shift", "keyUp"); - - await ContentTask.spawn(gBrowser.selectedBrowser, null, function() { - const select = content.document.querySelector("select"); - ok(select[0].selected, "First option should be selected"); - ok(select[1].selected, "Second option should be selected"); - ok(!select[2].selected, "Third option should not be selected"); - }); - await teardown(client); -}); - -add_task(async function testShiftClick() { - const { client } = await setupForURL(PAGE_URL); - const { Input } = client; - await resetEvents(); - - await dispatchKeyEvent(Input, "Shift", "rawKeyDown", shift); - info("Click the 'pointers' div."); - await Input.dispatchMouseEvent({ - type: "mousePressed", - x: 80, - y: 180, - modifiers: shift, - }); - await Input.dispatchMouseEvent({ - type: "mouseReleased", - x: 80, - y: 180, - modifiers: shift, - }); - await dispatchKeyEvent(Input, "Shift", "keyUp", shift); - let events = await getEvents(); - checkProperties({ type: "click", shiftKey: true, button: 0 }, events[2]); - - await teardown(client); -}); - -function keyForPlatform() { - // TODO add cases for other key-combinations as the need arises - let primary = ctrl; - let primaryKey = "Control"; - if (isMac) { - primary = alt; - primaryKey = "Alt"; - } - return { primary, primaryKey }; +async function sendTextKey(Input, key) { + await dispatchKeyEvent(Input, key, "keyDown"); + await dispatchKeyEvent(Input, key, "keyUp"); } -async function setupForInput(url) { - const { client, tab } = await setupForURL(url); - info("Focus the input on the page"); - await ContentTask.spawn(gBrowser.selectedBrowser, null, function() { - const input = content.document.querySelector("input"); - input.focus(); - is(input, content.document.activeElement, "Input should be focused"); - }); - await checkInputContent("", 0); - return { client, tab }; -} - -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 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"); +async function sendArrowKey(Input, arrowKey, modifiers = 0) { + await dispatchKeyEvent(Input, arrowKey, "rawKeyDown", modifiers); + await dispatchKeyEvent(Input, arrowKey, "keyUp", modifiers); } function dispatchKeyEvent(Input, key, type, modifiers = 0) { info(`Send ${type} for key ${key}`); return Input.dispatchKeyEvent({ type, modifiers, windowsVirtualKeyCode: KEYCODES[key], key, }); } -function getInputContent() { - return ContentTask.spawn(gBrowser.selectedBrowser, null, function() { - const input = content.document.querySelector("input"); - return { value: input.value, caret: input.selectionStart }; - }); -} +async function checkInputContent(expectedValue, expectedCaret) { + const { value, caret } = await ContentTask.spawn( + gBrowser.selectedBrowser, + null, + function() { + const input = content.document.querySelector("input"); + return { value: input.value, caret: input.selectionStart }; + } + ); -async function checkInputContent(expectedValue, expectedCaret) { - const { value, caret } = await getInputContent(); - is(value, expectedValue, "Check input content"); - is(caret, expectedCaret, "Check position of input caret"); -} - -// assuming doc_input_events.html -async function getEvents() { - const events = await ContentTask.spawn(gBrowser.selectedBrowser, null, () => { - return content.eval("allEvents"); - }); - info(`Events: ${JSON.stringify(events)}`); - return events; + is( + value, + expectedValue, + `The input value is correct ("${value}"="${expectedValue}")` + ); + is( + caret, + expectedCaret, + `The input caret has the correct index ("${caret}"="${expectedCaret}")` + ); } -// assuming doc_input_events.html -async function resetEvents() { - await ContentTask.spawn(gBrowser.selectedBrowser, null, () => { - content.eval("resetEvents()"); - const events = content.eval("allEvents"); - is(events.length, 0, "List of events should be empty"); - }); -} +async function sendBackspace(Input, expected) { + info("Send Backspace"); + await dispatchKeyEvent(Input, "Backspace", "rawKeyDown"); + await dispatchKeyEvent(Input, "Backspace", "keyUp"); -function resetInput(value = "") { - return ContentTask.spawn(gBrowser.selectedBrowser, value, function(arg) { - const input = content.document.querySelector("input"); - input.value = arg; - input.focus(); - }); + await checkInputContent(expected, expected.length); } - -function checkEvent(event, type, key, property, expectedValue) { - let expected = { type, key }; - expected[property] = expectedValue; - checkProperties(expected, event, "Event"); -} - -function checkProperties(expectedObj, targetObj, message = "Compare objects") { - for (const prop in expectedObj) { - is(targetObj[prop], expectedObj[prop], message + `: check ${prop}`); - } -}
--- a/remote/test/browser/browser_input_dispatchMouseEvent.js +++ b/remote/test/browser/browser_input_dispatchMouseEvent.js @@ -1,15 +1,15 @@ /* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ "use strict"; add_task(async function testDispatchMouseEvent() { - const { client } = await setupForURL(toDataURL("<div>foo</div>")); + const { client, tab } = await setupForURL(toDataURL("<div>foo</div>")); const { Input } = client; await ContentTask.spawn(gBrowser.selectedBrowser, {}, function() { const div = content.document.querySelector("div"); this.mouseDownPromise = new Promise(resolve => { div.addEventListener("mousedown", resolve, { once: true }); }); @@ -47,10 +47,15 @@ add_task(async function testDispatchMous return this.mouseUpPromise; }); info("Waiting for DOM click event on the div"); await ContentTask.spawn(gBrowser.selectedBrowser, {}, function() { return this.clickPromise; }); - await teardown(client); + await client.close(); + ok(true, "The client is closed"); + + BrowserTestUtils.removeTab(tab); + + await RemoteAgent.close(); });
deleted file mode 100644 --- a/remote/test/browser/doc_input_events.html +++ /dev/null @@ -1,148 +0,0 @@ -<!doctype html> -<meta charset=utf-8> -<html> -<head> - <title>Input Events</title> - <style> - div { padding:0px; margin: 0px; } - #trackPointer { position: fixed; } - #resultContainer { width: 600px; height: 60px; } - .area { width: 100px; height: 50px; background-color: #ccc; } - .block { width: 5px; height: 5px; border: solid 1px red; } - #dragArea { position: relative; } - #dragTarget { position: absolute; top:22px; left:47px;} - </style> - <script> - "use strict"; - var allEvents = []; - function makeParagraph(message) { - let paragraph = document.createElement("p"); - paragraph.textContent = message; - return paragraph; - } - function displayMessage(message) { - let eventNode = document.getElementById("events"); - eventNode.innerHTML = "" - eventNode.appendChild(makeParagraph(message)); - } - - function appendMessage(message) { - document.getElementById("events").appendChild(makeParagraph(message)); - } - - /** - * Escape |key| if it's in a surrogate-half character range. - * - * Example: given "\ud83d" return "U+d83d". - * - * Otherwise JSON.stringify will convert it to U+FFFD (REPLACEMENT CHARACTER) - * when returning a value from executeScript, for example. - */ - function escapeSurrogateHalf(key) { - if (typeof key !== "undefined" && key.length === 1) { - var charCode = key.charCodeAt(0); - var highSurrogate = charCode >= 0xD800 && charCode <= 0xDBFF; - var surrogate = highSurrogate || (charCode >= 0xDC00 && charCode <= 0xDFFF); - if (surrogate) { - key = "U+" + charCode.toString(16); - } - } - return key; - } - - function recordKeyboardEvent(event) { - var key = escapeSurrogateHalf(event.key); - allEvents.push({ - "code": event.code, - "key": key, - "which": event.which, - "location": event.location, - "alt": event.altKey, - "ctrl": event.ctrlKey, - "meta": event.metaKey, - "shift": event.shiftKey, - "repeat": event.repeat, - "type": event.type - }); - appendMessage(event.type + " " + - "code: " + event.code + ", " + - "key: " + key + ", " + - "which: " + event.which + ", " + - "keyCode: " + event.keyCode); - } - function recordInputEvent(event) { - allEvents.push({ - "data": event.data, - "inputType": event.inputType, - "isComposing": event.isComposing, - }); - appendMessage("InputEvent " + - "data: " + event.data + ", " + - "inputType: " + event.inputType + ", " + - "isComposing: " + event.isComposing); - } - function recordPointerEvent(event) { - if (event.type === "contextmenu") { - event.preventDefault(); - } - allEvents.push({ - "type": event.type, - "button": event.button, - "buttons": event.buttons, - "pageX": event.pageX, - "pageY": event.pageY, - "ctrlKey": event.ctrlKey, - "metaKey": event.metaKey, - "altKey": event.altKey, - "shiftKey": event.shiftKey, - "target": event.target.id - }); - appendMessage(event.type + " " + - "pageX: " + event.pageX + ", " + - "pageY: " + event.pageY + ", " + - "button: " + event.button + ", " + - "buttons: " + event.buttons + ", " + - "ctrlKey: " + event.ctrlKey + ", " + - "altKey: " + event.altKey + ", " + - "metaKey: " + event.metaKey + ", " + - "shiftKey: " + event.shiftKey + ", " + - "target id: " + event.target.id); - } - function resetEvents() { - allEvents.length = 0; - displayMessage(""); - } - - document.addEventListener("DOMContentLoaded", function() { - let keyReporter = document.getElementById("keys"); - keyReporter.addEventListener("keyup", recordKeyboardEvent); - keyReporter.addEventListener("keypress", recordKeyboardEvent); - keyReporter.addEventListener("keydown", recordKeyboardEvent); - keyReporter.addEventListener("input", recordInputEvent); - - let mouseReporter = document.getElementById("pointers"); - mouseReporter.addEventListener("click", recordPointerEvent); - mouseReporter.addEventListener("dblclick", recordPointerEvent); - mouseReporter.addEventListener("mousedown", recordPointerEvent); - mouseReporter.addEventListener("mouseup", recordPointerEvent); - mouseReporter.addEventListener("contextmenu", recordPointerEvent); - }); - </script> -</head> -<body> - <div id="trackPointer" class="block"></div> - <div> - <h2>KeyReporter</h2> - <input type="text" id="keys" size="80"> - </div> - <div> - <h2>ClickReporter</h2> - <div id="pointers" class="area"> - </div> - </div> - <div id="resultContainer"> - <h2>Events</h2> - <div id="events"></div> - </div> -</body> -</html>
--- a/remote/test/browser/head.js +++ b/remote/test/browser/head.js @@ -111,17 +111,16 @@ async function setup() { /** * Set up test environment by starting the remote agent, connecting * the CDP client over loopback, and creating a fresh tab to avoid * state bleedover from previous test. */ async function setupForURL(url) { const tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, url); - is(gBrowser.selectedTab, tab, "Selected tab is the target tab"); await RemoteAgent.listen(Services.io.newURI("http://localhost:9222")); const CDP = await getCDP(); const client = await CDP({ target(list) { // ensure we are debugging the right target, i.e. the requested URL return list.find(target => target.url == url); @@ -153,20 +152,8 @@ function toDataURL(src, doctype = "html" function getContentProperty(prop) { info(`Retrieve ${prop} on the content window`); return ContentTask.spawn( gBrowser.selectedBrowser, prop, _prop => content[_prop] ); } - -/** - * Close tabs, client, remote agent. - */ -async function teardown(client) { - await client.close(); - ok(true, "The client is closed"); - while (gBrowser.tabs.length > 1) { - gBrowser.removeCurrentTab(); - } - await RemoteAgent.close(); -}