Bug 678748 - Add tests for textbox context menu [r=mbrubeck]
authorMark Finkle <mfinkle@mozilla.com>
Wed, 24 Aug 2011 17:24:47 -0400
changeset 77161 f43d16688b14e8bb0b28f69400e6adbbbdd2e61f
parent 77160 b1cab441835f70d24ac0c78bde4d24070178971f
child 77162 654622f352f30ccb4f2520f2db0196e95da5df86
push id78
push userclegnitto@mozilla.com
push dateFri, 16 Dec 2011 17:32:24 +0000
treeherdermozilla-release@79d24e644fdd [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmbrubeck
bugs678748
milestone9.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 678748 - Add tests for textbox context menu [r=mbrubeck]
mobile/chrome/content/content.js
mobile/chrome/tests/Makefile.in
mobile/chrome/tests/browser_tap_contentedit.html
mobile/chrome/tests/browser_tapping_edit.js
--- a/mobile/chrome/content/content.js
+++ b/mobile/chrome/content/content.js
@@ -1008,20 +1008,16 @@ ContextHandler.registerType("callto", fu
 ContextHandler.registerType("link-openable", function(aState, aElement) {
   return Util.isOpenableScheme(aState.linkProtocol);
 });
 
 ContextHandler.registerType("link-shareable", function(aState, aElement) {
   return Util.isShareableScheme(aState.linkProtocol);
 });
 
-ContextHandler.registerType("input-text", function(aState, aElement) {
-    return (aElement instanceof Ci.nsIDOMHTMLInputElement && aElement.mozIsTextField(false)) || aElement instanceof Ci.nsIDOMHTMLTextAreaElement;
-});
-
 ["image", "video"].forEach(function(aType) {
   ContextHandler.registerType(aType+"-shareable", function(aState, aElement) {
     if (aState.types.indexOf(aType) == -1)
       return false;
 
     let protocol = ContextHandler._getProtocol(ContextHandler._getURI(aState.mediaURL));
     return Util.isShareableScheme(protocol);
   });
--- a/mobile/chrome/tests/Makefile.in
+++ b/mobile/chrome/tests/Makefile.in
@@ -80,16 +80,18 @@ include $(topsrcdir)/config/rules.mk
   browser_scroll.html \
   browser_scrollbar.js \
   browser_select.html \
   browser_select.js \
   browser_sessionstore.js \
   browser_tabs.js \
   browser_tapping.js \
   browser_tap_content.html \
+  browser_tapping_edit.js \
+  browser_tap_contentedit.html \
   browser_test.js \
   browser_vkb.js \
   $(warning browser_viewport.js disabled due to failures) \
   browser_viewport.sjs \
   browser_scrollbar.sjs \
   browser_title.sjs \
   browser_thumbnails.js \
   browser_install.xml \
new file mode 100644
--- /dev/null
+++ b/mobile/chrome/tests/browser_tap_contentedit.html
@@ -0,0 +1,14 @@
+<html style="border: 1px solid red">
+<title>Browser Tap Page w/ Editboxes</title>
+<body>
+
+  <div style="margin-bottom:20px">
+    <input id="plain-edit" type="text" value="Some text"/>
+  </div>
+
+  <div style="margin-bottom:20px">
+    <input id="url-edit" type="url" value="http://foo.bar"/>
+  </div>
+
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/mobile/chrome/tests/browser_tapping_edit.js
@@ -0,0 +1,246 @@
+/*
+ * Testing the context menus on editboxes:
+ *   plain and url
+ */
+
+let testURL = chromeRoot + "browser_tap_contentedit.html";
+
+let gTests = [];
+let gCurrentTest = null;
+let gCurrentTab;
+
+const kDoubleClickIntervalPlus = kDoubleClickInterval + 100;
+
+let gEvents = [];
+function dumpEvents(aEvent) {
+  if (aEvent.target != gCurrentTab.browser.parentNode)
+    return;
+
+  gEvents.push(aEvent.type);
+}
+
+function clearEvents() {
+  gEvents = [];
+}
+
+function checkEvents(aEvents) {
+  if (aEvents.length != gEvents.length) {
+    info("---- event check: failed length (" + aEvents.length + " != " + gEvents.length + ")\n");
+    info("---- expected: [" + aEvents.join(",") + "] actual: [" + gEvents.join(",") + "]\n");
+    return false;
+  }
+
+  for (let i=0; i<aEvents.length; i++) {
+    if (aEvents[i] != gEvents[i]) {
+      info("---- event check: failed match (" + aEvents[i] + " != " + gEvents[i] + "\n");
+      return false;
+    }
+  }
+  return true;
+}
+
+let gContextTypes = "";
+function clearContextTypes() {
+  gContextTypes = [];
+
+  if (ContextHelper.popupState)
+    ContextHelper.hide();
+}
+
+function checkContextTypes(aTypes) {
+  if (aTypes.length != gContextTypes.length) {
+    info("---- type check: failed length (" + aTypes.length + " != " + gContextTypes.length + ")\n");
+    info("---- expected: [" + aTypes.join(",") + "] actual: [" + gContextTypes.join(",") + "]\n");
+    return false;
+  }
+
+  for (let i=0; i<aTypes.length; i++) {
+    if (gContextTypes.indexOf(aTypes[i]) == -1) {
+      info("---- type check: failed match (" + aTypes[i] + ")\n");
+      info("---- expected: [" + aTypes.join(",") + "] actual: [" + gContextTypes.join(",") + "]\n");
+      return false;
+    }
+  }
+  return true;
+}
+
+function waitForContextMenu(aCallback, aNextTest) {
+  clearContextTypes();
+
+  let browser = gCurrentTab.browser;
+  browser.messageManager.addMessageListener("Browser:ContextMenu", function(aMessage) {
+    browser.messageManager.removeMessageListener(aMessage.name, arguments.callee);
+    aMessage.json.types.forEach(function(aType) {
+      gContextTypes.push(aType);
+    });
+    setTimeout(function() {
+      aCallback(aMessage.json);
+      clearContextTypes();
+      aNextTest();
+    }, 0);
+  });
+}
+
+function test() {
+  // The "runNextTest" approach is async, so we need to call "waitForExplicitFinish()"
+  // We call "finish()" when the tests are finished
+  waitForExplicitFinish();
+
+  // Add new tab
+  gCurrentTab = Browser.addTab(testURL, true);
+  ok(gCurrentTab, "Tab Opened");
+
+  let clipboard = Cc["@mozilla.org/widget/clipboard;1"].getService(Ci.nsIClipboard);
+  clipboard.emptyClipboard(Ci.nsIClipboard.kGlobalClipboard);
+
+  SelectionHelper.enabled = false;
+
+  window.addEventListener("TapSingle", dumpEvents, true);
+  window.addEventListener("TapDouble", dumpEvents, true);
+  window.addEventListener("TapLong", dumpEvents, true);
+
+  // Wait for the tab to load, then do the tests
+  messageManager.addMessageListener("Browser:FirstPaint", function() {
+  if (gCurrentTab.browser.currentURI.spec == testURL) {
+    messageManager.removeMessageListener("Browser:FirstPaint", arguments.callee);
+    // Hack the allowZoom getter since we want to observe events
+    // for testing purpose even if it is a local tab
+    gCurrentTab.__defineGetter__("allowZoom", function() {
+      return true;
+    });
+
+    // Using setTimeout(..., 0) here result into a duplicate mousedown/mouseup
+    // sequence that makes the double tap test fails (add some dump in input.js
+    // to see that...)
+    runNextTest();
+  }});
+}
+
+//------------------------------------------------------------------------------
+// Iterating tests by shifting test out one by one as runNextTest is called.
+function runNextTest() {
+  // Run the next test until all tests completed
+  if (gTests.length > 0) {
+    gCurrentTest = gTests.shift();
+    info(gCurrentTest.desc);
+    gCurrentTest.run();
+  }
+  else {
+    let clipboard = Cc["@mozilla.org/widget/clipboard;1"].getService(Ci.nsIClipboard);
+    clipboard.emptyClipboard(Ci.nsIClipboard.kGlobalClipboard);
+
+    window.removeEventListener("TapSingle", dumpEvents, true);
+    window.removeEventListener("TapDouble", dumpEvents, true);
+    window.removeEventListener("TapLong", dumpEvents, true);
+
+    SelectionHelper.enabled = true;
+    Browser.closeTab(gCurrentTab);
+
+    finish();
+  }
+}
+
+//------------------------------------------------------------------------------
+gTests.push({
+  desc: "Test empty plain textbox",
+
+  run: function() {
+    waitForContextMenu(function(aJSON) {
+      ok(checkContextTypes(["input-text"]), "Editbox with no text, no selection and no clipboard");
+    }, runNextTest);
+
+    let browser = gCurrentTab.browser;
+    let plainEdit = browser.contentDocument.getElementById("plain-edit");
+    plainEdit.readOnly = false;
+    plainEdit.value = "";
+
+    // Try very hard to keep "paste" from if the clipboard has data
+    let clipboard = Cc["@mozilla.org/widget/clipboard;1"].getService(Ci.nsIClipboard);
+    clipboard.emptyClipboard(Ci.nsIClipboard.kGlobalClipboard);
+    plainEdit.readOnly = true;
+    
+    let event = content.document.createEvent("PopupEvents");
+    event.initEvent("contextmenu", true, true);
+    plainEdit.dispatchEvent(event);
+  }
+});
+
+//------------------------------------------------------------------------------
+gTests.push({
+  desc: "Test plain textbox with text fully selected",
+
+  run: function() {
+    waitForContextMenu(function(aJSON) {
+      ok(checkContextTypes(["input-text", "copy"]), "Editbox with text and full selection, but no clipboard");
+    }, runNextTest);
+
+    let browser = gCurrentTab.browser;
+    let plainEdit = browser.contentDocument.getElementById("plain-edit");
+    plainEdit.readOnly = false;
+    plainEdit.value = "Every time we fix a bug, Stuart call's the President";
+    let plainEdit = plainEdit.QueryInterface(Ci.nsIDOMNSEditableElement);
+    plainEdit.editor.selectAll();
+
+    // Try very hard to keep "paste" from if the clipboard has data
+    let clipboard = Cc["@mozilla.org/widget/clipboard;1"].getService(Ci.nsIClipboard);
+    clipboard.emptyClipboard(Ci.nsIClipboard.kGlobalClipboard);
+    plainEdit.readOnly = true;
+    
+    let event = content.document.createEvent("PopupEvents");
+    event.initEvent("contextmenu", true, true);
+    plainEdit.dispatchEvent(event);
+  }
+});
+
+//------------------------------------------------------------------------------
+gTests.push({
+  desc: "Test plain textbox with text no selection",
+
+  run: function() {
+    waitForContextMenu(function(aJSON) {
+      ok(checkContextTypes(["input-text", "copy-all", "select-all"]), "Editbox with text, but no selection and no clipboard");
+    }, runNextTest);
+
+    let browser = gCurrentTab.browser;
+    let plainEdit = browser.contentDocument.getElementById("plain-edit");
+    plainEdit.readOnly = false;
+    plainEdit.value = "Every time we fix a bug, Stuart call's the President";
+    plainEdit.selectionStart = 0;
+    plainEdit.selectionEnd = 0;
+
+    // Try very hard to keep "paste" from if the clipboard has data
+    let clipboard = Cc["@mozilla.org/widget/clipboard;1"].getService(Ci.nsIClipboard);
+    clipboard.emptyClipboard(Ci.nsIClipboard.kGlobalClipboard);
+    plainEdit.readOnly = true;
+    
+    let event = content.document.createEvent("PopupEvents");
+    event.initEvent("contextmenu", true, true);
+    plainEdit.dispatchEvent(event);
+  }
+});
+
+//------------------------------------------------------------------------------
+gTests.push({
+  desc: "Test plain textbox with text no selection and text on clipboard",
+
+  run: function() {
+    waitForContextMenu(function(aJSON) {
+      ok(checkContextTypes(["input-text", "copy-all", "select-all", "paste"]), "Editbox with text and clipboard, but no selection");
+    }, runNextTest);
+
+    let browser = gCurrentTab.browser;
+    let plainEdit = browser.contentDocument.getElementById("plain-edit");
+    plainEdit.readOnly = false;
+    plainEdit.value = "Every time we fix a bug, Stuart call's the President";
+    plainEdit.selectionStart = 0;
+    plainEdit.selectionEnd = 0;
+
+    // Put some data on the clipboard to get "paste" to be active
+    let clipboard = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper);
+    clipboard.copyString("We are testing Firefox");
+    
+    let event = content.document.createEvent("PopupEvents");
+    event.initEvent("contextmenu", true, true);
+    plainEdit.dispatchEvent(event);
+  }
+});