Bug 678748 - Add tests for textbox context menu [r=mbrubeck]
authorMark Finkle <mfinkle@mozilla.com>
Wed, 24 Aug 2011 17:24:47 -0400
changeset 75850 f43d16688b14e8bb0b28f69400e6adbbbdd2e61f
parent 75849 b1cab441835f70d24ac0c78bde4d24070178971f
child 75851 654622f352f30ccb4f2520f2db0196e95da5df86
push id3
push userfelipc@gmail.com
push dateFri, 30 Sep 2011 20:09:13 +0000
reviewersmbrubeck
bugs678748
milestone9.0a1
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);
+  }
+});