Bug 1364896 - Part 3 - Add a test for contextmenu touchmode. r=dao,jmaher draft
authorJohann Hofmann <jhofmann@mozilla.com>
Fri, 23 Jun 2017 11:48:35 +0200
changeset 600795 e59df4f487f60cea137fbf8aea71a854a5706de9
parent 600794 8bbf0390a2c0dc82cfe6bb073ee0e6447f4afc81
child 600796 2090e4dde2d7507b73cf966bd946d609876bb480
child 600884 76d43d629d8fcd4d9848d3bf92407f16d264dd19
child 600938 8578cfce32f163c487beae78733ea9a0c9d2b7cf
push id65882
push userbmo:jhofmann@mozilla.com
push dateTue, 27 Jun 2017 21:08:20 +0000
reviewersdao, jmaher
bugs1364896
milestone56.0a1
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;