browser_toolbarButtonKeyPress.js (13123B)
1 /* Any copyright is dedicated to the Public Domain. 2 * http://creativecommons.org/publicdomain/zero/1.0/ */ 3 4 "use strict"; 5 6 const kDevPanelID = "PanelUI-developer-tools"; 7 8 /** 9 * Test the behavior of key presses on various toolbar buttons. 10 */ 11 12 function waitForLocationChange() { 13 let promise = new Promise(resolve => { 14 let wpl = { 15 onLocationChange() { 16 gBrowser.removeProgressListener(wpl); 17 resolve(); 18 }, 19 }; 20 gBrowser.addProgressListener(wpl); 21 }); 22 return promise; 23 } 24 25 add_task(async function setPref() { 26 await SpecialPowers.pushPrefEnv({ 27 set: [ 28 ["test.wait300msAfterTabSwitch", true], 29 ["browser.toolbars.keyboard_navigation", true], 30 ], 31 }); 32 }); 33 34 // Test activation of the app menu button from the keyboard. 35 // The app menu should appear and focus should move inside it. 36 add_task(async function testAppMenuButtonPress() { 37 let button = document.getElementById("PanelUI-menu-button"); 38 let focused = BrowserTestUtils.waitForEvent( 39 window.PanelUI.mainView, 40 "focus", 41 true 42 ); 43 await focusAndActivateElement(button, () => EventUtils.synthesizeKey(" ")); 44 await focused; 45 ok(true, "Focus inside app menu after toolbar button pressed"); 46 let hidden = BrowserTestUtils.waitForEvent( 47 window.PanelUI.panel, 48 "popuphidden" 49 ); 50 EventUtils.synthesizeKey("KEY_Escape"); 51 await hidden; 52 }); 53 54 // Test that the app menu doesn't open when a key other than space or enter is 55 // pressed . 56 add_task(async function testAppMenuButtonWrongKey() { 57 let button = document.getElementById("PanelUI-menu-button"); 58 await focusAndActivateElement(button, () => 59 EventUtils.synthesizeKey("KEY_Tab") 60 ); 61 await TestUtils.waitForTick(); 62 is(window.PanelUI.panel.state, "closed", "App menu is closed after tab"); 63 }); 64 65 // Test activation of the Library button from the keyboard. 66 // The Library menu should appear and focus should move inside it. 67 add_task(async function testLibraryButtonPress() { 68 CustomizableUI.addWidgetToArea("library-button", "nav-bar"); 69 let button = document.getElementById("library-button"); 70 await focusAndActivateElement(button, () => EventUtils.synthesizeKey(" ")); 71 let view = document.getElementById("appMenu-libraryView"); 72 let focused = BrowserTestUtils.waitForEvent(view, "focus", true); 73 await focused; 74 ok(true, "Focus inside Library menu after toolbar button pressed"); 75 let hidden = BrowserTestUtils.waitForEvent(document, "popuphidden", true); 76 view.closest("panel").hidePopup(); 77 await hidden; 78 CustomizableUI.removeWidgetFromArea("library-button"); 79 }); 80 81 // Test activation of the Developer button from the keyboard. 82 // This is a customizable widget of type "view". 83 // The Developer menu should appear and focus should move inside it. 84 add_task(async function testDeveloperButtonPress() { 85 CustomizableUI.addWidgetToArea( 86 "developer-button", 87 CustomizableUI.AREA_NAVBAR 88 ); 89 let button = document.getElementById("developer-button"); 90 await focusAndActivateElement(button, () => EventUtils.synthesizeKey(" ")); 91 let view = document.getElementById(kDevPanelID); 92 let focused = BrowserTestUtils.waitForEvent(view, "focus", true); 93 await focused; 94 ok(true, "Focus inside Developer menu after toolbar button pressed"); 95 let hidden = BrowserTestUtils.waitForEvent(document, "popuphidden", true); 96 view.closest("panel").hidePopup(); 97 await hidden; 98 CustomizableUI.reset(); 99 }); 100 101 // Test that the Developer menu doesn't open when a key other than space or 102 // enter is pressed . 103 add_task(async function testDeveloperButtonWrongKey() { 104 CustomizableUI.addWidgetToArea( 105 "developer-button", 106 CustomizableUI.AREA_NAVBAR 107 ); 108 let button = document.getElementById("developer-button"); 109 await focusAndActivateElement(button, () => 110 EventUtils.synthesizeKey("KEY_Tab") 111 ); 112 await TestUtils.waitForTick(); 113 let panel = document.getElementById(kDevPanelID).closest("panel"); 114 ok(!panel || panel.state == "closed", "Developer menu not open after tab"); 115 CustomizableUI.reset(); 116 }); 117 118 // Test activation of the Page actions button from the keyboard. 119 // The Page Actions menu should appear and focus should move inside it. 120 add_task(async function testPageActionsButtonPress() { 121 // The page actions button is not normally visible, so we must 122 // unhide it. 123 BrowserPageActions.mainButtonNode.style.display = "flex"; 124 registerCleanupFunction(() => { 125 BrowserPageActions.mainButtonNode.style.removeProperty("display"); 126 }); 127 await BrowserTestUtils.withNewTab("https://example.com", async function () { 128 let button = document.getElementById("pageActionButton"); 129 await focusAndActivateElement(button, () => EventUtils.synthesizeKey(" ")); 130 let view = document.getElementById("pageActionPanelMainView"); 131 let focused = BrowserTestUtils.waitForEvent(view, "focus", true); 132 await focused; 133 ok(true, "Focus inside Page Actions menu after toolbar button pressed"); 134 let hidden = BrowserTestUtils.waitForEvent(document, "popuphidden", true); 135 view.closest("panel").hidePopup(); 136 await hidden; 137 }); 138 }); 139 140 // Test activation of the Back and Forward buttons from the keyboard. 141 add_task(async function testBackForwardButtonPress() { 142 await BrowserTestUtils.withNewTab( 143 "https://example.com/1", 144 async function (aBrowser) { 145 BrowserTestUtils.startLoadingURIString(aBrowser, "https://example.com/2"); 146 147 await BrowserTestUtils.browserLoaded(aBrowser); 148 let backButton = document.getElementById("back-button"); 149 let onLocationChange = waitForLocationChange(); 150 await focusAndActivateElement(backButton, () => 151 EventUtils.synthesizeKey(" ") 152 ); 153 await onLocationChange; 154 ok(true, "Location changed after back button pressed"); 155 156 let forwardButton = document.getElementById("forward-button"); 157 onLocationChange = waitForLocationChange(); 158 await focusAndActivateElement(forwardButton, () => 159 EventUtils.synthesizeKey(" ") 160 ); 161 await onLocationChange; 162 ok(true, "Location changed after forward button pressed"); 163 } 164 ); 165 }); 166 167 // Test activation of the Reload button from the keyboard. 168 // This is a toolbarbutton with a click handler and no command handler, but 169 // the toolbar keyboard navigation code should handle keyboard activation. 170 add_task(async function testReloadButtonPress() { 171 await BrowserTestUtils.withNewTab( 172 "https://example.com/1", 173 async function (aBrowser) { 174 info("Waiting for button to be enabled."); 175 let button = document.getElementById("reload-button"); 176 await TestUtils.waitForCondition(() => !button.disabled); 177 let loaded = BrowserTestUtils.browserLoaded(aBrowser); 178 info("Focusing button"); 179 await focusAndActivateElement(button, () => { 180 info("Pressing space on the button"); 181 EventUtils.synthesizeKey(" "); 182 }); 183 info("Waiting for load."); 184 await loaded; 185 ok(true, "Page loaded after Reload button pressed"); 186 } 187 ); 188 }); 189 190 // Test activation of the Sidebars button from the keyboard. 191 // This is a toolbarbutton with a command handler. 192 add_task(async function testSidebarsButtonPress() { 193 const { SidebarController } = window; 194 let sidebarRevampEnabled = Services.prefs.getBoolPref( 195 "sidebar.revamp", 196 false 197 ); 198 let sidebar, sidebarBox; 199 if (!sidebarRevampEnabled) { 200 CustomizableUI.addWidgetToArea("sidebar-button", "nav-bar"); 201 } else { 202 // Expanded is only available with vertical tabs enabled 203 await SpecialPowers.pushPrefEnv({ 204 set: [["sidebar.verticalTabs", true]], 205 }); 206 await SidebarController.initializeUIState({ launcherExpanded: false }); 207 } 208 let button = document.getElementById("sidebar-button"); 209 ok(!button.checked, "Sidebars button not checked at start of test"); 210 if (!sidebarRevampEnabled) { 211 sidebarBox = document.getElementById("sidebar-box"); 212 ok(sidebarBox.hidden, "Sidebar hidden at start of test"); 213 } else { 214 sidebar = document.querySelector("sidebar-main"); 215 ok(!sidebar.expanded, "Sidebar collapsed at start of test"); 216 } 217 await focusAndActivateElement(button, () => EventUtils.synthesizeKey(" ")); 218 if (!sidebarRevampEnabled) { 219 await TestUtils.waitForCondition(() => button.checked); 220 ok(true, "Sidebars button checked after press"); 221 ok(!sidebarBox.hidden, "Sidebar visible after press"); 222 } else { 223 await TestUtils.waitForCondition( 224 () => sidebar.expanded, 225 "Sidebar expanded after press" 226 ); 227 ok(sidebar.expanded, "Sidebar expanded after press"); 228 } 229 // Make sure the sidebar is fully loaded before we hide it. 230 // Otherwise, the unload event might call JS which isn't loaded yet. 231 // We can't use BrowserTestUtils.browserLoaded because it fails on non-tab 232 // docs. Instead, wait for something in the JS script. 233 if (!sidebarRevampEnabled) { 234 let sidebarWin = document.getElementById("sidebar").contentWindow; 235 await TestUtils.waitForCondition(() => sidebarWin.PlacesUIUtils); 236 } else { 237 await sidebar.updateComplete; 238 } 239 await focusAndActivateElement(button, () => EventUtils.synthesizeKey(" ")); 240 if (!sidebarRevampEnabled) { 241 await TestUtils.waitForCondition(() => !button.checked); 242 ok(true, "Sidebars button not checked after press"); 243 ok(sidebarBox.hidden, "Sidebar hidden after press"); 244 CustomizableUI.removeWidgetFromArea("sidebar-button"); 245 } else { 246 await TestUtils.waitForCondition( 247 () => !sidebar.expanded, 248 "Sidebar not expanded after press" 249 ); 250 ok(!sidebar.expanded, "Sidebar not expanded after press"); 251 await SpecialPowers.popPrefEnv(); 252 } 253 }); 254 255 // Test activation of the Bookmark this page button from the keyboard. 256 // This is an image with a click handler on its parent and no command handler, 257 // but the toolbar keyboard navigation code should handle keyboard activation. 258 add_task(async function testBookmarkButtonPress() { 259 await BrowserTestUtils.withNewTab("https://example.com", async function () { 260 let button = document.getElementById("star-button-box"); 261 StarUI._createPanelIfNeeded(); 262 let panel = document.getElementById("editBookmarkPanel"); 263 let focused = BrowserTestUtils.waitForEvent(panel, "focus", true); 264 // The button ignores activation while the bookmarked status is being 265 // updated. So, wait for it to finish updating. 266 await TestUtils.waitForCondition( 267 () => BookmarkingUI.status != BookmarkingUI.STATUS_UPDATING 268 ); 269 await focusAndActivateElement(button, () => EventUtils.synthesizeKey(" ")); 270 await focused; 271 ok(true, "Focus inside edit bookmark panel after Bookmark button pressed"); 272 let hidden = BrowserTestUtils.waitForEvent(panel, "popuphidden"); 273 EventUtils.synthesizeKey("KEY_Escape"); 274 await hidden; 275 }); 276 }); 277 278 // Test activation of the Bookmarks Menu button from the keyboard. 279 // This is a button with type="menu". 280 // The Bookmarks Menu should appear. 281 add_task(async function testBookmarksmenuButtonPress() { 282 CustomizableUI.addWidgetToArea( 283 "bookmarks-menu-button", 284 CustomizableUI.AREA_NAVBAR 285 ); 286 let button = document.getElementById("bookmarks-menu-button"); 287 let menu = document.getElementById("BMB_bookmarksPopup"); 288 let shown = BrowserTestUtils.waitForEvent(menu, "popupshown"); 289 await focusAndActivateElement(button, () => EventUtils.synthesizeKey(" ")); 290 await shown; 291 ok(true, "Bookmarks Menu shown after toolbar button pressed"); 292 let hidden = BrowserTestUtils.waitForEvent(menu, "popuphidden"); 293 menu.hidePopup(); 294 await hidden; 295 CustomizableUI.reset(); 296 }); 297 298 // Test activation of the overflow button from the keyboard. 299 // The overflow menu should appear and focus should move inside it. 300 add_task(async function testOverflowButtonPress() { 301 // Move something to the overflow menu to make the button appear. 302 CustomizableUI.addWidgetToArea( 303 "developer-button", 304 CustomizableUI.AREA_FIXED_OVERFLOW_PANEL 305 ); 306 let button = document.getElementById("nav-bar-overflow-button"); 307 let view = document.getElementById("widget-overflow-mainView"); 308 let focused = BrowserTestUtils.waitForEvent(view, "focus", true); 309 await focusAndActivateElement(button, () => EventUtils.synthesizeKey(" ")); 310 await focused; 311 ok(true, "Focus inside overflow menu after toolbar button pressed"); 312 let panel = document.getElementById("widget-overflow"); 313 let hidden = BrowserTestUtils.waitForEvent(panel, "popuphidden"); 314 panel.hidePopup(); 315 await hidden; 316 CustomizableUI.reset(); 317 }); 318 319 // Test activation of the Downloads button from the keyboard. 320 // The Downloads panel should appear and focus should move inside it. 321 add_task(async function testDownloadsButtonPress() { 322 DownloadsButton.unhide(); 323 let button = document.getElementById("downloads-button"); 324 let panel = document.getElementById("downloadsPanel"); 325 let focused = BrowserTestUtils.waitForEvent(panel, "focus", true); 326 await focusAndActivateElement(button, () => EventUtils.synthesizeKey(" ")); 327 await focused; 328 ok(true, "Focus inside Downloads panel after toolbar button pressed"); 329 let hidden = BrowserTestUtils.waitForEvent(panel, "popuphidden"); 330 panel.hidePopup(); 331 await hidden; 332 DownloadsButton.hide(); 333 });