browser/base/content/test/general/contextmenu_common.js

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/browser/base/content/test/general/contextmenu_common.js	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,187 @@
     1.4 +var lastElement;
     1.5 +
     1.6 +function openContextMenuFor(element, shiftkey, waitForSpellCheck) {
     1.7 +    // Context menu should be closed before we open it again.
     1.8 +    is(SpecialPowers.wrap(contextMenu).state, "closed", "checking if popup is closed");
     1.9 +
    1.10 +    if (lastElement)
    1.11 +      lastElement.blur();
    1.12 +    element.focus();
    1.13 +
    1.14 +    // Some elements need time to focus and spellcheck before any tests are
    1.15 +    // run on them.
    1.16 +    function actuallyOpenContextMenuFor() {
    1.17 +      lastElement = element;
    1.18 +      var eventDetails = { type : "contextmenu", button : 2, shiftKey : shiftkey };
    1.19 +      synthesizeMouse(element, 2, 2, eventDetails, element.ownerDocument.defaultView);
    1.20 +    }
    1.21 +
    1.22 +    if (waitForSpellCheck)
    1.23 +      onSpellCheck(element, actuallyOpenContextMenuFor);
    1.24 +    else
    1.25 +      actuallyOpenContextMenuFor();
    1.26 +}
    1.27 +
    1.28 +function closeContextMenu() {
    1.29 +    contextMenu.hidePopup();
    1.30 +}
    1.31 +
    1.32 +function getVisibleMenuItems(aMenu, aData) {
    1.33 +    var items = [];
    1.34 +    var accessKeys = {};
    1.35 +    for (var i = 0; i < aMenu.childNodes.length; i++) {
    1.36 +        var item = aMenu.childNodes[i];
    1.37 +        if (item.hidden)
    1.38 +            continue;
    1.39 +
    1.40 +        var key = item.accessKey;
    1.41 +        if (key)
    1.42 +            key = key.toLowerCase();
    1.43 +
    1.44 +        var isGenerated = item.hasAttribute("generateditemid");
    1.45 +
    1.46 +        if (item.nodeName == "menuitem") {
    1.47 +            var isSpellSuggestion = item.className == "spell-suggestion";
    1.48 +            if (isSpellSuggestion) {
    1.49 +              is(item.id, "", "child menuitem #" + i + " is a spelling suggestion");
    1.50 +            } else if (isGenerated) {
    1.51 +              is(item.id, "", "child menuitem #" + i + " is a generated item");
    1.52 +            } else {
    1.53 +              ok(item.id, "child menuitem #" + i + " has an ID");
    1.54 +            }
    1.55 +            var label = item.getAttribute("label");
    1.56 +            ok(label.length, "menuitem " + item.id + " has a label");
    1.57 +            if (isSpellSuggestion) {
    1.58 +              is(key, "", "Spell suggestions shouldn't have an access key");
    1.59 +              items.push("*" + label);
    1.60 +            } else if (isGenerated) {
    1.61 +              items.push("+" + label);
    1.62 +            } else if (item.id.indexOf("spell-check-dictionary-") != 0 &&
    1.63 +                       item.id != "spell-no-suggestions" &&
    1.64 +                       item.id != "spell-add-dictionaries-main") {
    1.65 +              ok(key, "menuitem " + item.id + " has an access key");
    1.66 +              if (accessKeys[key])
    1.67 +                  ok(false, "menuitem " + item.id + " has same accesskey as " + accessKeys[key]);
    1.68 +              else
    1.69 +                  accessKeys[key] = item.id;
    1.70 +            }
    1.71 +            if (!isSpellSuggestion && !isGenerated) {
    1.72 +              items.push(item.id);
    1.73 +            }
    1.74 +            if (isGenerated) {
    1.75 +              var p = {};
    1.76 +              p.type = item.getAttribute("type");
    1.77 +              p.icon = item.getAttribute("image");
    1.78 +              p.checked = item.hasAttribute("checked");
    1.79 +              p.disabled = item.hasAttribute("disabled");
    1.80 +              items.push(p);
    1.81 +            } else {
    1.82 +              items.push(!item.disabled);
    1.83 +            }
    1.84 +        } else if (item.nodeName == "menuseparator") {
    1.85 +            ok(true, "--- seperator id is " + item.id);
    1.86 +            items.push("---");
    1.87 +            items.push(null);
    1.88 +        } else if (item.nodeName == "menu") {
    1.89 +            if (isGenerated) {
    1.90 +                item.id = "generated-submenu-" + aData.generatedSubmenuId++;
    1.91 +            }
    1.92 +            ok(item.id, "child menu #" + i + " has an ID");
    1.93 +            if (!isGenerated) {
    1.94 +                ok(key, "menu has an access key");
    1.95 +                if (accessKeys[key])
    1.96 +                    ok(false, "menu " + item.id + " has same accesskey as " + accessKeys[key]);
    1.97 +                else
    1.98 +                    accessKeys[key] = item.id;
    1.99 +            }
   1.100 +            items.push(item.id);
   1.101 +            items.push(!item.disabled);
   1.102 +            // Add a dummy item to that the indexes in checkMenu are the same
   1.103 +            // for expectedItems and actualItems.
   1.104 +            items.push([]);
   1.105 +            items.push(null);
   1.106 +        } else {
   1.107 +            ok(false, "child #" + i + " of menu ID " + aMenu.id +
   1.108 +                      " has an unknown type (" + item.nodeName + ")");
   1.109 +        }
   1.110 +    }
   1.111 +    return items;
   1.112 +}
   1.113 +
   1.114 +function checkContextMenu(expectedItems) {
   1.115 +    is(contextMenu.state, "open", "checking if popup is open");
   1.116 +    var data = { generatedSubmenuId: 1 };
   1.117 +    checkMenu(contextMenu, expectedItems, data);
   1.118 +}
   1.119 +
   1.120 +/*
   1.121 + * checkMenu - checks to see if the specified <menupopup> contains the
   1.122 + * expected items and state.
   1.123 + * expectedItems is a array of (1) item IDs and (2) a boolean specifying if
   1.124 + * the item is enabled or not (or null to ignore it). Submenus can be checked
   1.125 + * by providing a nested array entry after the expected <menu> ID.
   1.126 + * For example: ["blah", true,              // item enabled
   1.127 + *               "submenu", null,           // submenu
   1.128 + *                   ["sub1", true,         // submenu contents
   1.129 + *                    "sub2", false], null, // submenu contents
   1.130 + *               "lol", false]              // item disabled
   1.131 + *
   1.132 + */
   1.133 +function checkMenu(menu, expectedItems, data) {
   1.134 +    var actualItems = getVisibleMenuItems(menu, data);
   1.135 +    //ok(false, "Items are: " + actualItems);
   1.136 +    for (var i = 0; i < expectedItems.length; i+=2) {
   1.137 +        var actualItem   = actualItems[i];
   1.138 +        var actualEnabled = actualItems[i + 1];
   1.139 +        var expectedItem = expectedItems[i];
   1.140 +        var expectedEnabled = expectedItems[i + 1];
   1.141 +        if (expectedItem instanceof Array) {
   1.142 +            ok(true, "Checking submenu...");
   1.143 +            var menuID = expectedItems[i - 2]; // The last item was the menu ID.
   1.144 +            var submenu = menu.getElementsByAttribute("id", menuID)[0];
   1.145 +            ok(submenu, "got a submenu element of id='" + menuID + "'");
   1.146 +            if (submenu) {
   1.147 +              is(submenu.nodeName, "menu", "submenu element of id='" + menuID +
   1.148 +                                           "' has expected nodeName");
   1.149 +              checkMenu(submenu.menupopup, expectedItem, data);
   1.150 +            }
   1.151 +        } else {
   1.152 +            is(actualItem, expectedItem,
   1.153 +               "checking item #" + i/2 + " (" + expectedItem + ") name");
   1.154 +
   1.155 +            if (typeof expectedEnabled == "object" && expectedEnabled != null ||
   1.156 +                typeof actualEnabled == "object" && actualEnabled != null) {
   1.157 +
   1.158 +                ok(!(actualEnabled == null), "actualEnabled is not null");
   1.159 +                ok(!(expectedEnabled == null), "expectedEnabled is not null");
   1.160 +                is(typeof actualEnabled, typeof expectedEnabled, "checking types");
   1.161 +
   1.162 +                if (typeof actualEnabled != typeof expectedEnabled ||
   1.163 +                    actualEnabled == null || expectedEnabled == null)
   1.164 +                  continue;
   1.165 +
   1.166 +                is(actualEnabled.type, expectedEnabled.type,
   1.167 +                   "checking item #" + i/2 + " (" + expectedItem + ") type attr value");
   1.168 +                var icon = actualEnabled.icon;
   1.169 +                if (icon) {
   1.170 +                  var tmp = "";
   1.171 +                  var j = icon.length - 1;
   1.172 +                  while (j && icon[j] != "/") {
   1.173 +                    tmp = icon[j--] + tmp;
   1.174 +                  }
   1.175 +                  icon = tmp;
   1.176 +                }
   1.177 +                is(icon, expectedEnabled.icon,
   1.178 +                   "checking item #" + i/2 + " (" + expectedItem + ") icon attr value");
   1.179 +                is(actualEnabled.checked, expectedEnabled.checked,
   1.180 +                   "checking item #" + i/2 + " (" + expectedItem + ") has checked attr");
   1.181 +                is(actualEnabled.disabled, expectedEnabled.disabled,
   1.182 +                   "checking item #" + i/2 + " (" + expectedItem + ") has disabled attr");
   1.183 +            } else if (expectedEnabled != null)
   1.184 +                is(actualEnabled, expectedEnabled,
   1.185 +                   "checking item #" + i/2 + " (" + expectedItem + ") enabled state");
   1.186 +        }
   1.187 +    }
   1.188 +    // Could find unexpected extra items at the end...
   1.189 +    is(actualItems.length, expectedItems.length, "checking expected number of menu entries");
   1.190 +}

mercurial