browser_toolbox_options_disable_buttons.js (7911B)
1 /* Any copyright is dedicated to the Public Domain. 2 * http://creativecommons.org/publicdomain/zero/1.0/ */ 3 4 "use strict"; 5 6 let TEST_URL = 7 "data:text/html;charset=utf8,test for dynamically " + 8 "registering and unregistering tools"; 9 10 // The frames button is only shown if the page has at least one iframe so we 11 // need to add one to the test page. 12 TEST_URL += '<iframe src="data:text/plain,iframe"></iframe>'; 13 // The error count button is only shown if there are errors on the page 14 TEST_URL += '<script>console.error("err")</script>'; 15 16 var modifiedPrefs = []; 17 registerCleanupFunction(() => { 18 for (const pref of modifiedPrefs) { 19 Services.prefs.clearUserPref(pref); 20 } 21 }); 22 23 const TOGGLE_BUTTONS = [ 24 "command-button-measure", 25 "command-button-rulers", 26 "command-button-responsive", 27 "command-button-pick", 28 ]; 29 30 add_task(async function test() { 31 const tab = await addTab(TEST_URL); 32 let toolbox = await gDevTools.showToolboxForTab(tab); 33 const optionsPanelWin = await selectOptionsPanel(toolbox); 34 await testToggleToolboxButtons(toolbox, optionsPanelWin); 35 toolbox = await testPrefsAreRespectedWhenReopeningToolbox(); 36 await testButtonStateOnClick(toolbox); 37 38 await toolbox.destroy(); 39 }); 40 41 async function selectOptionsPanel(toolbox) { 42 info("Selecting the options panel"); 43 44 const onOptionsSelected = toolbox.once("options-selected"); 45 toolbox.selectTool("options"); 46 const optionsPanel = await onOptionsSelected; 47 ok(true, "Options panel selected via selectTool method"); 48 return optionsPanel.panelWin; 49 } 50 51 async function testToggleToolboxButtons(toolbox, optionsPanelWin) { 52 const checkNodes = [ 53 ...optionsPanelWin.document.querySelectorAll( 54 "#enabled-toolbox-buttons-box input[type=checkbox]" 55 ), 56 ]; 57 58 // Filter out all the buttons which are not supported on the current target. 59 // (DevTools Experimental Preferences etc...) 60 const toolbarButtons = toolbox.toolbarButtons.filter(tool => 61 tool.isToolSupported(toolbox) 62 ); 63 64 const visibleToolbarButtons = toolbarButtons.filter(tool => tool.isVisible); 65 66 const toolbarButtonNodes = [ 67 ...toolbox.doc.querySelectorAll(".command-button"), 68 ]; 69 70 is( 71 checkNodes.length, 72 toolbarButtons.length, 73 "All of the buttons are toggleable." 74 ); 75 is( 76 visibleToolbarButtons.length, 77 toolbarButtonNodes.length, 78 "All of the DOM buttons are toggleable." 79 ); 80 81 for (const tool of toolbarButtons) { 82 const id = tool.id; 83 const matchedCheckboxes = checkNodes.filter(node => node.id === id); 84 const matchedButtons = toolbarButtonNodes.filter( 85 button => button.id === id 86 ); 87 if (tool.isVisible) { 88 is( 89 matchedCheckboxes.length, 90 1, 91 "There should be a single toggle checkbox for: " + id 92 ); 93 is( 94 matchedCheckboxes[0].nextSibling.textContent, 95 tool.description, 96 "The label for checkbox matches the tool definition." 97 ); 98 is( 99 matchedButtons.length, 100 1, 101 "There should be a DOM button for the visible: " + id 102 ); 103 104 // The error count button title isn't its description 105 if (id !== "command-button-errorcount") { 106 is( 107 matchedButtons[0].getAttribute("title"), 108 tool.description, 109 "The tooltip for button matches the tool definition." 110 ); 111 } 112 113 if (TOGGLE_BUTTONS.includes(id)) { 114 is( 115 matchedButtons[0].getAttribute("aria-pressed"), 116 "false", 117 `The aria-pressed attribute is set to false for ${id} button` 118 ); 119 } else { 120 is( 121 matchedButtons[0].getAttribute("aria-pressed"), 122 null, 123 `The ${id} button does not have the aria-pressed attribute` 124 ); 125 } 126 } else { 127 is( 128 matchedButtons.length, 129 0, 130 "There should not be a DOM button for the invisible: " + id 131 ); 132 } 133 } 134 135 // Store modified pref names so that they can be cleared on error. 136 for (const tool of toolbarButtons) { 137 const pref = tool.visibilityswitch; 138 modifiedPrefs.push(pref); 139 } 140 141 // Try checking each checkbox, making sure that it changes the preference 142 for (const node of checkNodes) { 143 const tool = toolbarButtons.filter( 144 commandButton => commandButton.id === node.id 145 )[0]; 146 const isVisible = getBoolPref(tool.visibilityswitch); 147 148 testPreferenceAndUIStateIsConsistent(toolbox, optionsPanelWin); 149 node.click(); 150 testPreferenceAndUIStateIsConsistent(toolbox, optionsPanelWin); 151 152 const isVisibleAfterClick = getBoolPref(tool.visibilityswitch); 153 154 is( 155 isVisible, 156 !isVisibleAfterClick, 157 "Clicking on the node should have toggled visibility preference for " + 158 tool.visibilityswitch 159 ); 160 161 if (isVisibleAfterClick) { 162 const matchedButton = toolbox.doc.getElementById(tool.id); 163 if (TOGGLE_BUTTONS.includes(tool.id)) { 164 is( 165 matchedButton.getAttribute("aria-pressed"), 166 "false", 167 `The aria-pressed attribute is set to false for ${tool.id} button` 168 ); 169 } else { 170 is( 171 matchedButton.getAttribute("aria-pressed"), 172 null, 173 `The ${tool.id} button does not have the aria-pressed attribute` 174 ); 175 } 176 } 177 } 178 } 179 180 async function testPrefsAreRespectedWhenReopeningToolbox() { 181 info("Closing toolbox to test after reopening"); 182 await gDevTools.closeToolboxForTab(gBrowser.selectedTab); 183 184 const toolbox = await gDevTools.showToolboxForTab(gBrowser.selectedTab); 185 const optionsPanelWin = await selectOptionsPanel(toolbox); 186 187 info("Toolbox has been reopened. Checking UI state."); 188 await testPreferenceAndUIStateIsConsistent(toolbox, optionsPanelWin); 189 return toolbox; 190 } 191 192 function testPreferenceAndUIStateIsConsistent(toolbox, optionsPanelWin) { 193 const checkNodes = [ 194 ...optionsPanelWin.document.querySelectorAll( 195 "#enabled-toolbox-buttons-box input[type=checkbox]" 196 ), 197 ]; 198 const toolboxButtonNodes = [ 199 ...toolbox.doc.querySelectorAll(".command-button"), 200 ]; 201 202 for (const tool of toolbox.toolbarButtons) { 203 const isVisible = getBoolPref(tool.visibilityswitch); 204 205 const button = toolboxButtonNodes.find( 206 toolboxButton => toolboxButton.id === tool.id 207 ); 208 is(!!button, isVisible, "Button visibility matches pref for " + tool.id); 209 210 const check = checkNodes.filter(node => node.id === tool.id)[0]; 211 if (check) { 212 is( 213 check.checked, 214 isVisible, 215 "Checkbox should be selected based on current pref for " + tool.id 216 ); 217 } 218 } 219 } 220 221 async function testButtonStateOnClick(toolbox) { 222 const toolboxButtons = ["#command-button-rulers", "#command-button-measure"]; 223 for (const toolboxButton of toolboxButtons) { 224 const button = toolbox.doc.querySelector(toolboxButton); 225 if (!button) { 226 ok(false, `Couldn't find ${toolboxButton}`); 227 continue; 228 } 229 230 const isChecked = waitUntil(() => button.classList.contains("checked")); 231 is( 232 button.getAttribute("aria-pressed"), 233 "false", 234 `${toolboxButton} has aria-pressed set to false when it's off` 235 ); 236 237 button.click(); 238 await isChecked; 239 ok( 240 button.classList.contains("checked"), 241 `Button for ${toolboxButton} can be toggled on` 242 ); 243 is( 244 button.getAttribute("aria-pressed"), 245 "true", 246 `${toolboxButton} has aria-pressed set to true when it's on` 247 ); 248 249 const isUnchecked = waitUntil(() => !button.classList.contains("checked")); 250 button.click(); 251 await isUnchecked; 252 ok( 253 !button.classList.contains("checked"), 254 `Button for ${toolboxButton} can be toggled off` 255 ); 256 is( 257 button.getAttribute("aria-pressed"), 258 "false", 259 `aria-pressed is set back to false on ${toolboxButton} after it has been toggled off` 260 ); 261 } 262 } 263 264 function getBoolPref(key) { 265 try { 266 return Services.prefs.getBoolPref(key); 267 } catch (e) { 268 return false; 269 } 270 }