From 6bf0a5cb5034a7e684dcc3500e841785237ce2dd Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 19:32:43 +0200 Subject: Adding upstream version 1:115.7.0. Signed-off-by: Daniel Baumann --- .../browser_popupNotification_keyboard.js | 273 +++++++++++++++++++++ 1 file changed, 273 insertions(+) create mode 100644 browser/base/content/test/popupNotifications/browser_popupNotification_keyboard.js (limited to 'browser/base/content/test/popupNotifications/browser_popupNotification_keyboard.js') diff --git a/browser/base/content/test/popupNotifications/browser_popupNotification_keyboard.js b/browser/base/content/test/popupNotifications/browser_popupNotification_keyboard.js new file mode 100644 index 0000000000..5c20751c3f --- /dev/null +++ b/browser/base/content/test/popupNotifications/browser_popupNotification_keyboard.js @@ -0,0 +1,273 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +function test() { + waitForExplicitFinish(); + + ok(PopupNotifications, "PopupNotifications object exists"); + ok(PopupNotifications.panel, "PopupNotifications panel exists"); + + // Force tabfocus for all elements on OSX. + SpecialPowers.pushPrefEnv({ set: [["accessibility.tabfocus", 7]] }).then( + setup + ); +} + +// Focusing on notification icon buttons is handled by the ToolbarKeyboardNavigator +// component and arrow keys (see browser/base/content/browser-toolbarKeyNav.js). +function focusNotificationAnchor(anchor) { + let urlbarContainer = anchor.closest("#urlbar-container"); + urlbarContainer.querySelector("toolbartabstop").focus(); + const trackingProtectionIconContainer = urlbarContainer.querySelector( + "#tracking-protection-icon-container" + ); + is( + document.activeElement, + trackingProtectionIconContainer, + "tracking protection icon container is focused." + ); + while (document.activeElement !== anchor) { + EventUtils.synthesizeKey("ArrowRight"); + } +} + +var tests = [ + // Test that for persistent notifications, + // the secondary action is triggered by pressing the escape key. + { + id: "Test#1", + run() { + this.notifyObj = new BasicNotification(this.id); + this.notifyObj.options.persistent = true; + showNotification(this.notifyObj); + }, + onShown(popup) { + checkPopup(popup, this.notifyObj); + EventUtils.synthesizeKey("KEY_Escape"); + }, + onHidden(popup) { + ok(!this.notifyObj.mainActionClicked, "mainAction was not clicked"); + ok(this.notifyObj.secondaryActionClicked, "secondaryAction was clicked"); + ok( + !this.notifyObj.dismissalCallbackTriggered, + "dismissal callback wasn't triggered" + ); + ok(this.notifyObj.removedCallbackTriggered, "removed callback triggered"); + is( + this.notifyObj.mainActionSource, + undefined, + "shouldn't have a main action source." + ); + is( + this.notifyObj.secondaryActionSource, + "esc-press", + "secondary action should be from ESC key press" + ); + }, + }, + // Test that for non-persistent notifications, the escape key dismisses the notification. + { + id: "Test#2", + run() { + this.notifyObj = new BasicNotification(this.id); + this.notification = showNotification(this.notifyObj); + }, + onShown(popup) { + checkPopup(popup, this.notifyObj); + EventUtils.synthesizeKey("KEY_Escape"); + }, + onHidden(popup) { + ok(!this.notifyObj.mainActionClicked, "mainAction was not clicked"); + ok( + !this.notifyObj.secondaryActionClicked, + "secondaryAction was not clicked" + ); + ok( + this.notifyObj.dismissalCallbackTriggered, + "dismissal callback triggered" + ); + ok( + !this.notifyObj.removedCallbackTriggered, + "removed callback was not triggered" + ); + is( + this.notifyObj.mainActionSource, + undefined, + "shouldn't have a main action source." + ); + is( + this.notifyObj.secondaryActionSource, + undefined, + "shouldn't have a secondary action source." + ); + this.notification.remove(); + }, + }, + // Test that the space key on an anchor element focuses an active notification + { + id: "Test#3", + run() { + this.notifyObj = new BasicNotification(this.id); + this.notifyObj.anchorID = "geo-notification-icon"; + this.notifyObj.addOptions({ + persistent: true, + }); + this.notification = showNotification(this.notifyObj); + }, + onShown(popup) { + checkPopup(popup, this.notifyObj); + let anchor = document.getElementById(this.notifyObj.anchorID); + focusNotificationAnchor(anchor); + EventUtils.sendString(" "); + is(document.activeElement, popup.children[0].closebutton); + this.notification.remove(); + }, + onHidden(popup) {}, + }, + // Test that you can switch between active notifications with the space key + // and that the notification is focused on selection. + { + id: "Test#4", + async run() { + let notifyObj1 = new BasicNotification(this.id); + notifyObj1.id += "_1"; + notifyObj1.anchorID = "default-notification-icon"; + notifyObj1.addOptions({ + hideClose: true, + checkbox: { + label: "Test that elements inside the panel can be focused", + }, + persistent: true, + }); + let opened = waitForNotificationPanel(); + let notification1 = showNotification(notifyObj1); + await opened; + + let notifyObj2 = new BasicNotification(this.id); + notifyObj2.id += "_2"; + notifyObj2.anchorID = "geo-notification-icon"; + notifyObj2.addOptions({ + persistent: true, + }); + opened = waitForNotificationPanel(); + let notification2 = showNotification(notifyObj2); + let popup = await opened; + + // Make sure notification 2 is visible + checkPopup(popup, notifyObj2); + + // Activate the anchor for notification 1 and wait until it's shown. + let anchor = document.getElementById(notifyObj1.anchorID); + focusNotificationAnchor(anchor); + is(document.activeElement, anchor); + opened = waitForNotificationPanel(); + EventUtils.sendString(" "); + popup = await opened; + checkPopup(popup, notifyObj1); + + is(document.activeElement, popup.children[0].checkbox); + + // Activate the anchor for notification 2 and wait until it's shown. + anchor = document.getElementById(notifyObj2.anchorID); + focusNotificationAnchor(anchor); + is(document.activeElement, anchor); + opened = waitForNotificationPanel(); + EventUtils.sendString(" "); + popup = await opened; + checkPopup(popup, notifyObj2); + + is(document.activeElement, popup.children[0].closebutton); + + notification1.remove(); + notification2.remove(); + goNext(); + }, + }, + // Test that passing the autofocus option will focus an opened notification. + { + id: "Test#5", + run() { + this.notifyObj = new BasicNotification(this.id); + this.notifyObj.anchorID = "geo-notification-icon"; + this.notifyObj.addOptions({ + autofocus: true, + }); + this.notification = showNotification(this.notifyObj); + }, + onShown(popup) { + checkPopup(popup, this.notifyObj); + + // Initial focus on open is null because a panel itself + // can not be focused, next tab focus will be inside the panel. + is(Services.focus.focusedElement, null); + + EventUtils.synthesizeKey("KEY_Tab"); + is(Services.focus.focusedElement, popup.children[0].closebutton); + dismissNotification(popup); + }, + async onHidden() { + // Focus the urlbar to check that it stays focused. + gURLBar.focus(); + + // Show another notification and make sure it's not autofocused. + let notifyObj = new BasicNotification(this.id); + notifyObj.id += "_2"; + notifyObj.anchorID = "default-notification-icon"; + + let opened = waitForNotificationPanel(); + let notification = showNotification(notifyObj); + let popup = await opened; + checkPopup(popup, notifyObj); + + // Check that the urlbar is still focused. + is(Services.focus.focusedElement, gURLBar.inputField); + + this.notification.remove(); + notification.remove(); + }, + }, + // Test that focus is not moved out of a content element if autofocus is not set. + { + id: "Test#6", + async run() { + let id = this.id; + await BrowserTestUtils.withNewTab( + "data:text/html,", + async function (browser) { + let notifyObj = new BasicNotification(id); + await SpecialPowers.spawn(browser, [], function () { + content.document.getElementById("test-input").focus(); + }); + + let opened = waitForNotificationPanel(); + let notification = showNotification(notifyObj); + await opened; + + // Check that the focused element in the chrome window + // is either the browser in case we're running on e10s + // or the input field in case of non-e10s. + if (gMultiProcessBrowser) { + is(Services.focus.focusedElement, browser); + } else { + is( + Services.focus.focusedElement, + browser.contentDocument.getElementById("test-input") + ); + } + + // Check that the input field is still focused inside the browser. + await SpecialPowers.spawn(browser, [], function () { + is( + content.document.activeElement, + content.document.getElementById("test-input") + ); + }); + + notification.remove(); + } + ); + goNext(); + }, + }, +]; -- cgit v1.2.3