Bug 712871. (Cv1) Update test after bug 702019 (generated submenu). r=neil.
authorSerge Gautherie <sgautherie.bz@free.fr>
Thu, 22 Dec 2011 17:34:19 +0100
changeset 10280 abb5e5bbbcd3e5bab55fb62ac1e01cb0fa0bf06c
parent 10279 8085035d9d83b2d336f1bcf8d1f3ed3f85e9f4c8
child 10281 24729d88b962d3b1f33e20df1ec7b60c87092ae5
push id402
push userbugzilla@standard8.plus.com
push dateTue, 13 Mar 2012 21:17:18 +0000
treeherdercomm-beta@d080a8ebf16a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersneil
bugs712871, 702019
Bug 712871. (Cv1) Update test after bug 702019 (generated submenu). r=neil.
suite/browser/test/mochitest/subtst_contextmenu.html
suite/browser/test/mochitest/test_contextmenu.html
--- a/suite/browser/test/mochitest/subtst_contextmenu.html
+++ b/suite/browser/test/mochitest/subtst_contextmenu.html
@@ -18,11 +18,45 @@ Browser context menu subtest.
 <video controls id="test-video-bad" src="bogus.duh" width="100" height="100" style="background-color: orange"></video>
 <video controls id="test-video-bad2" width="100" height="100" style="background-color: yellow">
   <source src="bogus.duh" type="video/durrrr;">
 </video>
 <iframe id="test-iframe" width="98"  height="98" style="border: 1px solid black"></iframe>
 <textarea id="test-textarea">chssseesbbbie</textarea> <!-- a weird word which generates only one suggestion -->
 <div id="test-contenteditable" contenteditable="true">chssseefsbbbie</div> <!-- a more weird word which generates no suggestions -->
 <input id="test-input-spellcheck" type="text" spellcheck="true" autofocus value="prodkjfgigrty"> <!-- this one also generates one suggestion -->
++<div contextmenu="myMenu">
+  <p id="test-pagemenu" hopeless="true">I've got a context menu!</p>
+  <menu id="myMenu" type="context">
+    <menuitem label="Plain item" onclick="document.getElementById('test-pagemenu').removeAttribute('hopeless');"></menuitem>
+    <menuitem label="Disabled item" disabled></menuitem>
+    <menu>
+      <menuitem type="checkbox" label="Checkbox" checked></menuitem>
+    </menu>
+    <menu>
+      <menuitem type="radio" label="Radio1" checked></menuitem>
+      <menuitem type="radio" label="Radio2"></menuitem>
+      <menuitem type="radio" label="Radio3"></menuitem>
+    </menu>
+    <menu>
+      <menuitem label="Item w/ icon" icon="favicon.ico"></menuitem>
+      <menuitem label="Item w/ bad icon" icon="data://www.mozilla.org/favicon.ico"></menuitem>
+    </menu>
+    <menu label="Submenu">
+      <menuitem type="radio" label="Radio1" radiogroup="rg"></menuitem>
+      <menuitem type="radio" label="Radio2" checked radiogroup="rg"></menuitem>
+      <menuitem type="radio" label="Radio3" radiogroup="rg"></menuitem>
+      <menu>
+        <menuitem type="checkbox" label="Checkbox"></menuitem>
+      </menu>
+    </menu>
+    <menu hidden>
+      <menuitem label="Bogus item"></menuitem>
+    </menu>
+    <menu>
+    </menu>
+    <menuitem label="Hidden item" hidden></menuitem>
+    <menuitem></menuitem>
+  </menu>
+</div>
 
 </body>
 </html>
--- a/suite/browser/test/mochitest/test_contextmenu.html
+++ b/suite/browser/test/mochitest/test_contextmenu.html
@@ -19,21 +19,21 @@ Browser context menu tests.
 
 /** Test for Login Manager: multiple login autocomplete. **/
 
 netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
 
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 
-function openContextMenuFor(element) {
+function openContextMenuFor(element, shiftkey) {
     // Context menu should be closed before we open it again.
     is(contextMenu.state, "closed", "checking if popup is closed");
 
-    var eventDetails = { type : "contextmenu", button : 2 };
+    var eventDetails = { type : "contextmenu", button : 2, shiftKey : shiftkey };
     synthesizeMouse(element, 2, 2, eventDetails, element.ownerDocument.defaultView);
 }
 
 function closeContextMenu() {
     contextMenu.hidePopup();
 }
 
 function executeCopyCommand(command, expectedValue)
@@ -45,113 +45,172 @@ function executeCopyCommand(command, exp
   // The easiest way to check the clipboard is to paste the contents into a
   // textbox
   input.focus();
   input.value = "";
   input.controllers.getControllerForCommand("cmd_paste").doCommand("cmd_paste");
   is(input.value, expectedValue, "paste for command " + command);
 }
 
-function getVisibleMenuItems(aMenu) {
+function invokeItemAction(generatedItemId)
+{
+  var item = contextMenu.getElementsByAttribute("generateditemid",
+                                                generatedItemId)[0];
+  ok(item, "Got generated XUL menu item");
+  item.doCommand();
+  is(pagemenu.hasAttribute("hopeless"), false, "attribute got removed");
+}
+
+function getVisibleMenuItems(aMenu, aData) {
     var items = [];
     var accessKeys = {};
     for (var i = 0; i < aMenu.childNodes.length; i++) {
         var item = aMenu.childNodes[i];
         if (item.hidden)
             continue;
 
         var key = item.accessKey;
         if (key)
             key = key.toLowerCase();
 
+        var isGenerated = item.hasAttribute("generateditemid");
+
         if (item.nodeName == "menuitem") {
             var isSpellSuggestion = item.className == "spell-suggestion";
             if (isSpellSuggestion) {
               is(item.id, "", "child menuitem #" + i + " is a spelling suggestion");
+            } else if (isGenerated) {
+              is(item.id, "", "child menuitem #" + i + " is a generated item");
             } else {
               ok(item.id, "child menuitem #" + i + " has an ID");
             }
             var label = item.getAttribute("label");
             ok(label.length, "menuitem " + item.id + " has a label");
             if (isSpellSuggestion) {
               is(key, "", "Spell suggestions shouldn't have an access key");
               items.push("*" + label);
+            } else if (isGenerated) {
+              items.push("+" + label);
             } else if (item.id.indexOf("spell-check-dictionary-") != 0 &&
                        item.id != "spell-no-suggestions") {
               ok(key, "menuitem " + item.id + " has an access key");
               if (accessKeys[key])
                   ok(false, "menuitem " + item.id + " has same accesskey as " + accessKeys[key]);
               else
                   accessKeys[key] = item.id;
             }
-            if (!isSpellSuggestion) {
+            if (!isSpellSuggestion && !isGenerated) {
               items.push(item.id);
             }
-            items.push(!item.disabled);
+            if (isGenerated) {
+              var p = {};
+              p.type = item.getAttribute("type");
+              p.icon = item.getAttribute("image");
+              p.checked = item.hasAttribute("checked");
+              p.disabled = item.hasAttribute("disabled");
+              items.push(p);
+            } else {
+              items.push(!item.disabled);
+            }
         } else if (item.nodeName == "menuseparator") {
             ok(true, "--- seperator id is " + item.id);
             items.push("---");
             items.push(null);
         } else if (item.nodeName == "menu") {
+            if (isGenerated) {
+                item.id = "generated-submenu-" + aData.generatedSubmenuId++;
+            }
             ok(item.id, "child menu #" + i + " has an ID");
-            ok(key, "menu has an access key");
-            if (accessKeys[key])
-                ok(false, "menu " + item.id + " has same accesskey as " + accessKeys[key]);
-            else
-                accessKeys[key] = item.id;
+            if (!isGenerated) {
+                ok(key, "menu has an access key");
+                if (accessKeys[key])
+                    ok(false, "menu " + item.id + " has same accesskey as " + accessKeys[key]);
+                else
+                    accessKeys[key] = item.id;
+            }
             items.push(item.id);
             items.push(!item.disabled);
             // Add a dummy item to that the indexes in checkMenu are the same
             // for expectedItems and actualItems.
             items.push([]);
             items.push(null);
         } else {
             ok(false, "child #" + i + " of menu ID " + aMenu.id +
                       " has an unknown type (" + item.nodeName + ")");
         }
     }
     return items;
 }
 
 function checkContextMenu(expectedItems) {
     is(contextMenu.state, "open", "checking if popup is open");
-    checkMenu(contextMenu, expectedItems);
+    var data = { generatedSubmenuId: 1 };
+    checkMenu(contextMenu, expectedItems, data);
 }
 
 /*
  * checkMenu - checks to see if the specified <menupopup> contains the
  * expected items and state.
  * expectedItems is a array of (1) item IDs and (2) a boolean specifying if
  * the item is enabled or not (or null to ignore it). Submenus can be checked
  * by providing a nested array entry after the expected <menu> ID.
  * For example: ["blah", true,              // item enabled
  *               "submenu", null,           // submenu
  *                   ["sub1", true,         // submenu contents
  *                    "sub2", false], null, // submenu contents
  *               "lol", false]              // item disabled
  * 
  */
-function checkMenu(menu, expectedItems) {
-    var actualItems = getVisibleMenuItems(menu);
+function checkMenu(menu, expectedItems, data) {
+    var actualItems = getVisibleMenuItems(menu, data);
     //ok(false, "Items are: " + actualItems);
     for (var i = 0; i < expectedItems.length; i+=2) {
         var actualItem   = actualItems[i];
         var actualEnabled = actualItems[i + 1];
         var expectedItem = expectedItems[i];
         var expectedEnabled = expectedItems[i + 1];
         if (expectedItem instanceof Array) {
             ok(true, "Checking submenu...");
             var menuID = expectedItems[i - 2]; // The last item was the menu ID.
             var submenu = menu.getElementsByAttribute("id", menuID)[0];
             ok(submenu && submenu.nodeName == "menu", "got expected submenu element");
-            checkMenu(submenu.menupopup, expectedItem);
+            checkMenu(submenu.menupopup, expectedItem, data);
         } else {
             is(actualItem, expectedItem,
                "checking item #" + i/2 + " (" + expectedItem + ") name");
-            if (expectedEnabled != null)
+
+            if (typeof expectedEnabled == "object" && expectedEnabled != null ||
+                typeof actualEnabled == "object" && actualEnabled != null) {
+
+                ok(!(actualEnabled == null), "actualEnabled is not null");
+                ok(!(expectedEnabled == null), "expectedEnabled is not null");
+                is(typeof actualEnabled, typeof expectedEnabled, "checking types");
+
+                if (typeof actualEnabled != typeof expectedEnabled ||
+                    actualEnabled == null || expectedEnabled == null)
+                  continue;
+
+                is(actualEnabled.type, expectedEnabled.type,
+                   "checking item #" + i/2 + " (" + expectedItem + ") type attr value");
+                var icon = actualEnabled.icon;
+                if (icon) {
+                  var tmp = "";
+                  var j = icon.length - 1;
+                  while (j && icon[j] != "/") {
+                    tmp = icon[j--] + tmp;
+                  }
+                  icon = tmp;
+                }
+                is(icon, expectedEnabled.icon,
+                   "checking item #" + i/2 + " (" + expectedItem + ") icon attr value");
+                is(actualEnabled.checked, expectedEnabled.checked,
+                   "checking item #" + i/2 + " (" + expectedItem + ") has checked attr");
+                is(actualEnabled.disabled, expectedEnabled.disabled,
+                   "checking item #" + i/2 + " (" + expectedItem + ") has disabled attr");
+            } else if (expectedEnabled != null)
                 is(actualEnabled, expectedEnabled,
                    "checking item #" + i/2 + " (" + expectedItem + ") enabled state");
         }
     }
     // Could find unexpected extra items at the end...
     is(actualItems.length, expectedItems.length, "checking expected number of menu entries");
 }
 
@@ -523,16 +582,81 @@ function runTest(testNum) {
 
         closeContextMenu();
         openContextMenuFor(link); // Invoke context menu for next test.
         break;
 
     case 17:
         executeCopyCommand("cmd_copyLink", "http://mozilla.com/");
         closeContextMenu();
+        openContextMenuFor(pagemenu); // Invoke context menu for next test.
+        break;
+
+    case 18:
+        // Context menu for element with assigned content context menu
+        checkContextMenu(["+Plain item",          {type: "", icon: "", checked: false, disabled: false},
+                          "+Disabled item",       {type: "", icon: "", checked: false, disabled: true},
+                          "---",                  null,
+                          "+Checkbox",            {type: "checkbox", icon: "", checked: true, disabled: false},
+                          "---",                  null,
+                          "+Radio1",              {type: "checkbox", icon: "", checked: true, disabled: false},
+                          "+Radio2",              {type: "checkbox", icon: "", checked: false, disabled: false},
+                          "+Radio3",              {type: "checkbox", icon: "", checked: false, disabled: false},
+                          "---",                  null,
+                          "+Item w/ icon",        {type: "", icon: "favicon.ico", checked: false, disabled: false},
+                          "+Item w/ bad icon",    {type: "", icon: "", checked: false, disabled: false},
+                          "---",                  null,
+                          "generated-submenu-1",  true,
+                              ["+Radio1",             {type: "checkbox", icon: "", checked: false, disabled: false},
+                               "+Radio2",             {type: "checkbox", icon: "", checked: true, disabled: false},
+                               "+Radio3",             {type: "checkbox", icon: "", checked: false, disabled: false},
+                               "---",                 null,
+                               "+Checkbox",           {type: "checkbox", icon: "", checked: false, disabled: false}], null,
+                          "---",                  null,
+                          "popupwindow-reject",   true,
+                          "---",                  null,
+                          "context-back",         false,
+                          "context-forward",      false,
+                          "context-reload",       true,
+                          "context-stop",         false,
+                          "---",                  null,
+                          "context-bookmarkpage", true,
+                          "context-savepage",     true,
+                          "context-sendpage",     true,
+                          "---",                  null,
+                          "context-viewbgimage",  false,
+                          "context-selectall",    true,
+                          "---",                  null,
+                          "context-viewsource",   true,
+                          "context-viewinfo",     true]);
+
+        invokeItemAction("0");
+        closeContextMenu();
+        openContextMenuFor(pagemenu, true); // Invoke context menu for next test.
+        break;
+
+    case 19:
+        // Context menu for element with assigned content context menu
+        // The shift key should bypass content context menu processing
+        checkContextMenu(["popupwindow-reject",   true,
+                          "---",                  null,
+                          "context-back",         false,
+                          "context-forward",      false,
+                          "context-reload",       true,
+                          "context-stop",         false,
+                          "---",                  null,
+                          "context-bookmarkpage", true,
+                          "context-savepage",     true,
+                          "context-sendpage",     true,
+                          "---",                  null,
+                          "context-viewbgimage",  false,
+                          "context-selectall",    true,
+                          "---",                  null,
+                          "context-viewsource",   true,
+                          "context-viewinfo",     true]);
 
         subwindow.close();
         SimpleTest.finish();
         return;
 
     /*
      * Other things that would be nice to test:
      *  - selected text
@@ -549,17 +673,18 @@ function runTest(testNum) {
   }
 
 }
 
 
 var testNum = 1;
 var subwindow, chromeWin, contextMenu;
 var text, link, mailto, input, img, img_link, img_mailto, canvas, video_ok,
-    video_bad, video_bad2, iframe, textarea, contenteditable, inputspell;
+    video_bad, video_bad2, iframe, textarea, contenteditable, inputspell,
+    pagemenu;
 
 function startTest() {
     netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
     chromeWin = subwindow
                     .QueryInterface(Ci.nsIInterfaceRequestor)
                     .getInterface(Ci.nsIWebNavigation)
                     .QueryInterface(Ci.nsIDocShellTreeItem)
                     .rootTreeItem
@@ -585,16 +710,17 @@ function startTest() {
     canvas     = subwindow.document.getElementById("test-canvas");
     video_ok   = subwindow.document.getElementById("test-video-ok");
     video_bad  = subwindow.document.getElementById("test-video-bad");
     video_bad2 = subwindow.document.getElementById("test-video-bad2");
     iframe     = subwindow.document.getElementById("test-iframe");
     textarea   = subwindow.document.getElementById("test-textarea");
     contenteditable = subwindow.document.getElementById("test-contenteditable");
     inputspell = subwindow.document.getElementById("test-input-spellcheck");
+    pagemenu = subwindow.document.getElementById("test-pagemenu");
 
     contextMenu.addEventListener("popupshown", function() { runTest(++testNum); }, false);
     runTest(1);
 }
 
 // We open this in a separate window, because the Mochitests run inside a frame.
 // The frame causes an extra menu item, and prevents running the test
 // standalone (ie, clicking the test name in the Mochitest window) to see