Skip to content

Commit

Permalink
Bug 1351148 Part4: Revise those test cases that have some tasks have …
Browse files Browse the repository at this point in the history
…to be processed before or after the synthesized key events. r=smaug.

Make sure input events are processed before or after the dependent tasks.

MozReview-Commit-ID: 8KfZnT2wjJR
  • Loading branch information
mingchou committed Jun 7, 2017
1 parent 5c6d99d commit a5bccae
Show file tree
Hide file tree
Showing 7 changed files with 124 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ function* respondsToMoveEvents(helper, testActor) {
yield mouse.move(x, y);
} else if (type === "keyboard") {
let options = shift ? {shiftKey: true} : {};
yield EventUtils.synthesizeKey(key, options);
yield EventUtils.synthesizeAndWaitKey(key, options);
}
yield checkPosition(expected, helper);
}
Expand All @@ -128,14 +128,14 @@ function* checkPosition({x, y}, {getElementAttribute}) {
function* respondsToReturnAndEscape({isElementHidden, show}) {
info("Simulating return to select the color and hide the eyedropper");

yield EventUtils.synthesizeKey("VK_RETURN", {});
yield EventUtils.synthesizeAndWaitKey("VK_RETURN", {});
let hidden = yield isElementHidden("root");
ok(hidden, "The eyedropper has been hidden");

info("Showing the eyedropper again and simulating escape to hide it");

yield show("html");
yield EventUtils.synthesizeKey("VK_ESCAPE", {});
yield EventUtils.synthesizeAndWaitKey("VK_ESCAPE", {});
hidden = yield isElementHidden("root");
ok(hidden, "The eyedropper has been hidden again");
}
4 changes: 2 additions & 2 deletions dom/tests/browser/browser_bug1316330.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,14 @@ add_task(async function() {
let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, URL);
let browser = tab.linkedBrowser;

EventUtils.synthesizeKey("d", { code: "KeyD", repeat: 3 });
await EventUtils.synthesizeAndWaitKey("d", { code: "KeyD", repeat: 3 });

await ContentTask.spawn(browser, null, async function() {
is(content.document.body.getAttribute("data-down"), "2", "Correct number of events");
is(content.document.body.getAttribute("data-press"), "2", "Correct number of events");
});

EventUtils.synthesizeKey("p", { code: "KeyP", repeat: 3 });
await EventUtils.synthesizeAndWaitKey("p", { code: "KeyP", repeat: 3 });

await ContentTask.spawn(browser, null, async function() {
is(content.document.body.getAttribute("data-down"), "4", "Correct number of events");
Expand Down
5 changes: 2 additions & 3 deletions editor/libeditor/tests/browser_bug629172.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,10 @@ add_task(async function() {
// but in non-e10s it is handled by the browser UI code and hence won't
// reach the web page. As a result, we need to observe the event in
// the content process only in e10s mode.
var waitForKeypressContent = BrowserTestUtils.waitForContentEvent(aBrowser, "keypress");
EventUtils.synthesizeKey("x", {accelKey: true, shiftKey: true});
if (gMultiProcessBrowser) {
return waitForKeypressContent;
return EventUtils.synthesizeAndWaitKey("x", {accelKey: true, shiftKey: true});
}
EventUtils.synthesizeKey("x", {accelKey: true, shiftKey: true});
return Promise.resolve();
}

Expand Down
83 changes: 83 additions & 0 deletions testing/mochitest/tests/SimpleTest/EventUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -678,6 +678,44 @@ function synthesizeNativeMouseMove(aTarget, aOffsetX, aOffsetY, aCallback, aWind
utils.sendNativeMouseMove(x * scale, y * scale, null, observer);
}

/**
* This is a wrapper around synthesizeNativeMouseMove that waits for the mouse
* event to be dispatched to the target content.
*
* This API is supposed to be used in those test cases that synthesize some
* input events to chrome process and have some checks in content.
*/
function synthesizeAndWaitNativeMouseMove(aTarget, aOffsetX, aOffsetY,
aCallback, aWindow = window) {
let browser = gBrowser.selectedTab.linkedBrowser;
let mm = browser.messageManager;
let ContentTask =
_EU_Cu.import("resource://testing-common/ContentTask.jsm", null).ContentTask;

let eventRegisteredPromise = new Promise(resolve => {
mm.addMessageListener("Test:MouseMoveRegistered", function processed(message) {
mm.removeMessageListener("Test:MouseMoveRegistered", processed);
resolve();
});
});
let eventReceivedPromise = ContentTask.spawn(browser, [aOffsetX, aOffsetY],
([clientX, clientY]) => {
return new Promise(resolve => {
addEventListener("mousemove", function onMouseMoveEvent(e) {
if (e.clientX == clientX && e.clientY == clientY) {
removeEventListener("mousemove", onMouseMoveEvent);
resolve();
}
});
sendAsyncMessage("Test:MouseMoveRegistered");
});
});
eventRegisteredPromise.then(() => {
synthesizeNativeMouseMove(aTarget, aOffsetX, aOffsetY, null, aWindow);
});
return eventReceivedPromise;
}

function _computeKeyCodeFromChar(aChar)
{
if (aChar.length != 1) {
Expand Down Expand Up @@ -829,6 +867,51 @@ function synthesizeKey(aKey, aEvent, aWindow = window, aCallback)
}
}

/**
* This is a wrapper around synthesizeKey that waits for the key event to be
* dispatched to the target content. It returns a promise which is resolved
* when the content receives the key event.
*
* This API is supposed to be used in those test cases that synthesize some
* input events to chrome process and have some checks in content.
*/
function synthesizeAndWaitKey(aKey, aEvent, aWindow = window,
checkBeforeSynthesize, checkAfterSynthesize)
{
let browser = gBrowser.selectedTab.linkedBrowser;
let mm = browser.messageManager;
let keyCode = _createKeyboardEventDictionary(aKey, aEvent, aWindow).dictionary.keyCode;
let ContentTask = _EU_Cu.import("resource://testing-common/ContentTask.jsm", null).ContentTask;

let keyRegisteredPromise = new Promise(resolve => {
mm.addMessageListener("Test:KeyRegistered", function processed(message) {
mm.removeMessageListener("Test:KeyRegistered", processed);
resolve();
});
});
let keyReceivedPromise = ContentTask.spawn(browser, keyCode, (keyCode) => {
return new Promise(resolve => {
addEventListener("keyup", function onKeyEvent(e) {
if (e.keyCode == keyCode) {
removeEventListener("keyup", onKeyEvent);
resolve();
}
});
sendAsyncMessage("Test:KeyRegistered");
});
});
keyRegisteredPromise.then(() => {
if (checkBeforeSynthesize) {
checkBeforeSynthesize();
}
synthesizeKey(aKey, aEvent, aWindow);
if (checkAfterSynthesize) {
checkAfterSynthesize();
}
});
return keyReceivedPromise;
}

function _parseNativeModifiers(aModifiers, aWindow = window)
{
var navigator = _getNavigator(aWindow);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,7 @@ async function do_test(test) {
let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser);

info("Moving mouse out of the way.");
await new Promise(resolve => {
EventUtils.synthesizeNativeMouseMove(tab.linkedBrowser, 300, 300, resolve);
});
await EventUtils.synthesizeAndWaitNativeMouseMove(tab.linkedBrowser, 300, 300);

info("creating input field");
await ContentTask.spawn(tab.linkedBrowser, test, async function(test) {
Expand Down Expand Up @@ -92,15 +90,11 @@ async function do_test(test) {
}, {once: true});
});
info("Initial mouse move");
await new Promise(resolve => {
EventUtils.synthesizeNativeMouseMove(tab.linkedBrowser, 50, 5, resolve);
});
await EventUtils.synthesizeAndWaitNativeMouseMove(tab.linkedBrowser, 50, 5);
info("Waiting");
await new Promise(resolve => setTimeout(resolve, 400));
info("Second mouse move");
await new Promise(resolve => {
EventUtils.synthesizeNativeMouseMove(tab.linkedBrowser, 70, 5, resolve);
});
await EventUtils.synthesizeAndWaitNativeMouseMove(tab.linkedBrowser, 70, 5);
info("Waiting for tooltip to open");
let tooltip = await awaitTooltipOpen;

Expand Down
8 changes: 5 additions & 3 deletions toolkit/content/tests/browser/browser_findbar.js
Original file line number Diff line number Diff line change
Expand Up @@ -175,16 +175,18 @@ add_task(async function() {
let findBar = gFindBar;
let initialValue = findBar._findField.value;

EventUtils.synthesizeKey("f", { accelKey: true }, window);
await EventUtils.synthesizeAndWaitKey("f", { accelKey: true }, window, null,
() => {
isnot(document.activeElement, findBar._findField.inputField,
"findbar is not yet focused");
});

let promises = [
BrowserTestUtils.sendChar("a", browser),
BrowserTestUtils.sendChar("b", browser),
BrowserTestUtils.sendChar("c", browser)
];

isnot(document.activeElement, findBar._findField.inputField,
"findbar is not yet focused");
is(findBar._findField.value, initialValue, "still has initial find query");

await Promise.all(promises);
Expand Down
26 changes: 26 additions & 0 deletions widget/tests/test_assign_event_data.html
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,16 @@
setTimeout(gCallback, 0);
}

function observeKeyUpOnContent(aKeyCode, aCallback)
{
document.addEventListener("keyup", function keyUp(ev) {
if (ev.keyCode == aKeyCode) {
document.removeEventListener("keyup", keyUp);
SimpleTest.executeSoon(aCallback);
}
});
}

const kTests = [
{ description: "InternalScrollPortEvent (overflow, vertical)",
targetID: "scrollable-div", eventType: "overflow",
Expand Down Expand Up @@ -150,6 +160,8 @@
document.getElementById(this.targetID).focus();
synthesizeNativeKey(KEYBOARD_LAYOUT_EN_US, kIsWin ? WIN_VK_A : MAC_VK_ANSI_A,
{}, "a", "a");
observeKeyUpOnContent(KeyboardEvent.DOM_VK_A, runNextTest);
return true;
},
canRun: function () {
return (kIsMac || kIsWin);
Expand All @@ -163,6 +175,8 @@
document.getElementById(this.targetID).focus();
synthesizeNativeKey(KEYBOARD_LAYOUT_EN_US, kIsWin ? WIN_VK_A : MAC_VK_ANSI_A,
{}, "a", "a");
observeKeyUpOnContent(KeyboardEvent.DOM_VK_A, runNextTest);
return true;
},
canRun: function () {
return (kIsMac || kIsWin);
Expand All @@ -176,6 +190,8 @@
document.getElementById(this.targetID).focus();
synthesizeNativeKey(KEYBOARD_LAYOUT_EN_US, kIsWin ? WIN_VK_B : MAC_VK_ANSI_B,
{ shiftKey: true }, "B", "B");
observeKeyUpOnContent(KeyboardEvent.DOM_VK_B, runNextTest);
return true;
},
canRun: function () {
return (kIsMac || kIsWin);
Expand All @@ -189,6 +205,14 @@
document.getElementById(this.targetID).focus();
synthesizeNativeKey(KEYBOARD_LAYOUT_EN_US, kIsWin ? WIN_VK_C : MAC_VK_ANSI_C,
{ accelKey: true }, kIsWin ? "\u0003" : "c", "c");

// On Windows, synthesizeNativeKey will also fire keyup for accelKey
// (control key on Windows). We have to wait for it to prevent the key
// event break the next test case.
let waitKeyCode = _EU_isWin(window) ? KeyboardEvent.DOM_VK_CONTROL :
KeyboardEvent.DOM_VK_C;
observeKeyUpOnContent(waitKeyCode, runNextTest);
return true;
},
canRun: function () {
return (kIsMac || kIsWin);
Expand Down Expand Up @@ -325,6 +349,8 @@
document.getElementById(this.targetID).focus();
synthesizeNativeKey(KEYBOARD_LAYOUT_EN_US, kIsWin ? WIN_VK_B : MAC_VK_ANSI_B,
{ shiftKey: true }, "B", "B");
observeKeyUpOnContent(KeyboardEvent.DOM_VK_B, runNextTest);
return true;
},
canRun: function () {
return (kIsMac || kIsWin);
Expand Down

0 comments on commit a5bccae

Please sign in to comment.