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 +}