Bug 1364896 - Part 3 - Add a test for contextmenu touchmode. r=dao,jmaher
authorJohann Hofmann <jhofmann@mozilla.com>
Fri, 23 Jun 2017 11:48:35 +0200 (2017-06-23)
changeset 366087 5c870a786e945197a770a308aeeececdff8bac18
parent 366086 134d9ee1e545d7da27888a4c0a3b8eae689bbbba
child 366088 64412d8b6f4b4b64ace0c914fe897b4bc02cefbd
push id45484
push userjhofmann@mozilla.com
push dateMon, 26 Jun 2017 19:01:52 +0000 (2017-06-26)
treeherderautoland@5c870a786e94 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdao, jmaher
bugs1364896
milestone56.0a1
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
Bug 1364896 - Part 3 - Add a test for contextmenu touchmode. r=dao,jmaher This also adds a utility function for synthesizing native touch events to Eventutils.js. I did not add a test for searchbar because of intermittent issues with showing the contextmenu (that are not reproducible manually). I believe this is rather related to searchbar functionality than my patches. MozReview-Commit-ID: Dqm92Saosxz
browser/base/content/test/contextMenu/browser.ini
browser/base/content/test/contextMenu/browser_contextmenu_touch.js
testing/mochitest/tests/SimpleTest/EventUtils.js
--- a/browser/base/content/test/contextMenu/browser.ini
+++ b/browser/base/content/test/contextMenu/browser.ini
@@ -1,6 +1,8 @@
 [DEFAULT]
 support-files =
   !/browser/base/content/test/general/contextmenu_common.js
   subtst_contextmenu_webext.html
 
 [browser_contextmenu_mozextension.js]
+[browser_contextmenu_touch.js]
+skip-if = !(os == 'win' && os_version == '10.0')
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/contextMenu/browser_contextmenu_touch.js
@@ -0,0 +1,73 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * 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/. */
+
+/* This test checks that context menus are in touchmode
+ * when opened through a touch event (long tap). */
+
+async function openAndCheckContextMenu(contextMenu, target) {
+  is(contextMenu.state, "closed", "Context menu is initally closed.");
+
+  let popupshown = BrowserTestUtils.waitForEvent(contextMenu, "popupshown");
+  EventUtils.synthesizeNativeTapAtCenter(target, true);
+  await popupshown;
+
+  is(contextMenu.state, "open", "Context menu is open.");
+  is(contextMenu.getAttribute("touchmode"), "true", "Context menu is in touchmode.");
+
+  contextMenu.hidePopup();
+
+  popupshown = BrowserTestUtils.waitForEvent(contextMenu, "popupshown");
+  EventUtils.synthesizeMouseAtCenter(target, {type: "contextmenu"});
+  await popupshown;
+
+  is(contextMenu.state, "open", "Context menu is open.");
+  ok(!contextMenu.hasAttribute("touchmode"), "Context menu is not in touchmode.");
+
+  contextMenu.hidePopup();
+}
+
+// Test the content area context menu.
+add_task(async function test_contentarea_contextmenu_touch() {
+  await BrowserTestUtils.withNewTab("about:blank", async function(browser) {
+    let contextMenu = document.getElementById("contentAreaContextMenu");
+    await openAndCheckContextMenu(contextMenu, browser);
+  });
+});
+
+// Test the back and forward buttons.
+add_task(async function test_back_forward_button_contextmenu_touch() {
+  await BrowserTestUtils.withNewTab("http://example.com", async function(browser) {
+    let contextMenu = document.getElementById("backForwardMenu");
+
+    let backbutton = document.getElementById("back-button");
+    let notDisabled = BrowserTestUtils.waitForCondition(() => !backbutton.hasAttribute("disabled"));
+    BrowserTestUtils.loadURI(browser, "http://example.org");
+    await notDisabled;
+    await openAndCheckContextMenu(contextMenu, backbutton);
+
+
+    let forwardbutton = document.getElementById("forward-button");
+    notDisabled = BrowserTestUtils.waitForCondition(() => !forwardbutton.hasAttribute("disabled"));
+    backbutton.click();
+    await notDisabled;
+    await openAndCheckContextMenu(contextMenu, forwardbutton);
+  });
+});
+
+// Test the toolbar context menu.
+add_task(async function test_toolbar_contextmenu_touch() {
+  let toolbarContextMenu = document.getElementById("toolbar-context-menu");
+  let target = document.getElementById("PanelUI-menu-button");
+  await openAndCheckContextMenu(toolbarContextMenu, target);
+});
+
+// Test the urlbar input context menu.
+add_task(async function test_urlbar_contextmenu_touch() {
+  let urlbar = document.getElementById("urlbar");
+  let textBox = document.getAnonymousElementByAttribute(urlbar,
+                                      "anonid", "textbox-input-box");
+  let menu = document.getAnonymousElementByAttribute(textBox,
+                                      "anonid", "input-box-contextmenu");
+  await openAndCheckContextMenu(menu, textBox);
+});
--- a/testing/mochitest/tests/SimpleTest/EventUtils.js
+++ b/testing/mochitest/tests/SimpleTest/EventUtils.js
@@ -628,16 +628,41 @@ function sendWheelAndPaint(aTarget, aOff
   };
 
   // Listen for the system wheel event, because it happens after all of
   // the other wheel events, including legacy events.
   SpecialPowers.addSystemEventListener(aWindow, "wheel", onwheel);
   synthesizeWheel(aTarget, aOffsetX, aOffsetY, aEvent, aWindow);
 }
 
+function synthesizeNativeTapAtCenter(aTarget, aLongTap = false, aCallback = null, aWindow = window) {
+  let rect = aTarget.getBoundingClientRect();
+  return synthesizeNativeTap(aTarget, rect.width / 2, rect.height / 2, aLongTap, aCallback, aWindow);
+}
+
+function synthesizeNativeTap(aTarget, aOffsetX, aOffsetY, aLongTap = false, aCallback = null, aWindow = window) {
+  let utils = _getDOMWindowUtils(aWindow);
+  if (!utils)
+    return;
+
+  let scale = utils.screenPixelsPerCSSPixel;
+  let rect = aTarget.getBoundingClientRect();
+  let x = (aWindow.mozInnerScreenX + rect.left + aOffsetX) * scale;
+  let y = (aWindow.mozInnerScreenY + rect.top + aOffsetY) * scale;
+
+  let observer = {
+    observe: (subject, topic, data) => {
+      if (aCallback && topic == "mouseevent") {
+        aCallback(data);
+      }
+    }
+  };
+  utils.sendNativeTouchTap(x, y, aLongTap, observer);
+}
+
 function synthesizeNativeMouseMove(aTarget, aOffsetX, aOffsetY, aCallback, aWindow = window) {
   var utils = _getDOMWindowUtils(aWindow);
   if (!utils)
     return;
 
   var rect = aTarget.getBoundingClientRect();
   var x = aOffsetX + window.mozInnerScreenX + rect.left;
   var y = aOffsetY + window.mozInnerScreenY + rect.top;