diff options
Diffstat (limited to '')
-rw-r--r-- | browser/components/customizableui/test/browser_panelUINotifications.js | 597 |
1 files changed, 597 insertions, 0 deletions
diff --git a/browser/components/customizableui/test/browser_panelUINotifications.js b/browser/components/customizableui/test/browser_panelUINotifications.js new file mode 100644 index 0000000000..818fcbad39 --- /dev/null +++ b/browser/components/customizableui/test/browser_panelUINotifications.js @@ -0,0 +1,597 @@ +"use strict"; + +const { AppMenuNotifications } = ChromeUtils.importESModule( + "resource://gre/modules/AppMenuNotifications.sys.mjs" +); + +/** + * Tests that when we click on the main call-to-action of the doorhanger, the provided + * action is called, and the doorhanger removed. + */ +add_task(async function testMainActionCalled() { + let options = { + gBrowser: window.gBrowser, + url: "about:blank", + }; + + await BrowserTestUtils.withNewTab(options, function (browser) { + is( + PanelUI.notificationPanel.state, + "closed", + "update-manual doorhanger is closed." + ); + let mainActionCalled = false; + let mainAction = { + callback: () => { + mainActionCalled = true; + }, + }; + AppMenuNotifications.showNotification("update-manual", mainAction); + + isnot( + PanelUI.notificationPanel.state, + "closed", + "update-manual doorhanger is showing." + ); + let notifications = [...PanelUI.notificationPanel.children].filter( + n => !n.hidden + ); + is( + notifications.length, + 1, + "PanelUI doorhanger is only displaying one notification." + ); + let doorhanger = notifications[0]; + is( + doorhanger.id, + "appMenu-update-manual-notification", + "PanelUI is displaying the update-manual notification." + ); + + let button = doorhanger.button; + button.click(); + + ok(mainActionCalled, "Main action callback was called"); + is( + PanelUI.notificationPanel.state, + "closed", + "update-manual doorhanger is closed." + ); + is( + PanelUI.menuButton.hasAttribute("badge-status"), + false, + "Should not have a badge status" + ); + }); +}); + +/** + * This tests that when we click the secondary action for a notification, + * it will display the badge for that notification on the PanelUI menu button. + * Once we click on this button, we should see an item in the menu which will + * call our main action. + */ +add_task(async function testSecondaryActionWorkflow() { + let options = { + gBrowser: window.gBrowser, + url: "about:blank", + }; + + await BrowserTestUtils.withNewTab(options, async function (browser) { + is( + PanelUI.notificationPanel.state, + "closed", + "update-manual doorhanger is closed." + ); + + let mainActionCalled = false; + let mainAction = { + callback: () => { + mainActionCalled = true; + }, + }; + AppMenuNotifications.showNotification("update-manual", mainAction); + + isnot( + PanelUI.notificationPanel.state, + "closed", + "update-manual doorhanger is showing." + ); + let notifications = [...PanelUI.notificationPanel.children].filter( + n => !n.hidden + ); + is( + notifications.length, + 1, + "PanelUI doorhanger is only displaying one notification." + ); + let doorhanger = notifications[0]; + is( + doorhanger.id, + "appMenu-update-manual-notification", + "PanelUI is displaying the update-manual notification." + ); + + let secondaryActionButton = doorhanger.secondaryButton; + secondaryActionButton.click(); + + is( + PanelUI.notificationPanel.state, + "closed", + "update-manual doorhanger is closed." + ); + + is( + PanelUI.menuButton.getAttribute("badge-status"), + "update-manual", + "Badge is displaying on PanelUI button." + ); + + await gCUITestUtils.openMainMenu(); + is( + PanelUI.menuButton.getAttribute("badge-status"), + "update-manual", + "Badge is displaying on PanelUI button." + ); + let menuItem = PanelUI.mainView.querySelector(".panel-banner-item"); + is( + menuItem.getAttribute("data-l10n-id"), + "appmenuitem-banner-update-manual", + "Showing correct label" + ); + is(menuItem.hidden, false, "update-manual menu item is showing."); + + await gCUITestUtils.hideMainMenu(); + is( + PanelUI.menuButton.getAttribute("badge-status"), + "update-manual", + "Badge is shown on PanelUI button." + ); + + await gCUITestUtils.openMainMenu(); + menuItem.click(); + ok(mainActionCalled, "Main action callback was called"); + + AppMenuNotifications.removeNotification(/.*/); + }); +}); + +/** + * This tests that the PanelUI update downloading badge and banner + * notification are correctly displayed and that clicking the banner + * item calls the main action. + */ +add_task(async function testDownloadingBadge() { + let options = { + gBrowser: window.gBrowser, + url: "about:blank", + }; + + await BrowserTestUtils.withNewTab(options, async function (browser) { + let mainActionCalled = false; + let mainAction = { + callback: () => { + mainActionCalled = true; + }, + }; + // The downloading notification is always displayed in a dismissed state. + AppMenuNotifications.showNotification( + "update-downloading", + mainAction, + undefined, + { dismissed: true } + ); + is(PanelUI.notificationPanel.state, "closed", "doorhanger is closed."); + + is( + PanelUI.menuButton.getAttribute("badge-status"), + "update-downloading", + "Downloading badge is displaying on PanelUI button." + ); + + await gCUITestUtils.openMainMenu(); + is( + PanelUI.menuButton.getAttribute("badge-status"), + "update-downloading", + "Downloading badge is displaying on PanelUI button." + ); + let menuItem = PanelUI.mainView.querySelector(".panel-banner-item"); + is( + menuItem.getAttribute("data-l10n-id"), + "appmenuitem-banner-update-downloading", + "Showing correct label (downloading)" + ); + is(menuItem.hidden, false, "update-downloading menu item is showing."); + + await gCUITestUtils.hideMainMenu(); + is( + PanelUI.menuButton.getAttribute("badge-status"), + "update-downloading", + "Downloading badge is shown on PanelUI button." + ); + + await gCUITestUtils.openMainMenu(); + menuItem.click(); + ok(mainActionCalled, "Main action callback was called"); + + AppMenuNotifications.removeNotification(/.*/); + }); +}); + +/** + * We want to ensure a few things with this: + * - Adding a doorhanger will make a badge disappear + * - once the notification for the doorhanger is resolved (removed, not just dismissed), + * then we display any other badges that are remaining. + */ +add_task(async function testInteractionWithBadges() { + await BrowserTestUtils.withNewTab("about:blank", async function (browser) { + // Remove the fxa toolbar button from the navbar to ensure the notification + // is displayed on the app menu button. + let { CustomizableUI } = ChromeUtils.importESModule( + "resource:///modules/CustomizableUI.sys.mjs" + ); + CustomizableUI.removeWidgetFromArea("fxa-toolbar-menu-button"); + + AppMenuNotifications.showBadgeOnlyNotification("fxa-needs-authentication"); + is( + PanelUI.menuButton.getAttribute("badge-status"), + "fxa-needs-authentication", + "Fxa badge is shown on PanelUI button." + ); + is( + PanelUI.notificationPanel.state, + "closed", + "update-manual doorhanger is closed." + ); + + let mainActionCalled = false; + let mainAction = { + callback: () => { + mainActionCalled = true; + }, + }; + AppMenuNotifications.showNotification("update-manual", mainAction); + + isnot( + PanelUI.menuButton.getAttribute("badge-status"), + "fxa-needs-authentication", + "Fxa badge is hidden on PanelUI button." + ); + isnot( + PanelUI.notificationPanel.state, + "closed", + "update-manual doorhanger is showing." + ); + let notifications = [...PanelUI.notificationPanel.children].filter( + n => !n.hidden + ); + is( + notifications.length, + 1, + "PanelUI doorhanger is only displaying one notification." + ); + let doorhanger = notifications[0]; + is( + doorhanger.id, + "appMenu-update-manual-notification", + "PanelUI is displaying the update-manual notification." + ); + + let secondaryActionButton = doorhanger.secondaryButton; + secondaryActionButton.click(); + + is( + PanelUI.notificationPanel.state, + "closed", + "update-manual doorhanger is closed." + ); + + is( + PanelUI.menuButton.getAttribute("badge-status"), + "update-manual", + "Badge is displaying on PanelUI button." + ); + + await gCUITestUtils.openMainMenu(); + is( + PanelUI.menuButton.getAttribute("badge-status"), + "update-manual", + "Badge is displaying on PanelUI button." + ); + let menuItem = PanelUI.mainView.querySelector(".panel-banner-item"); + is( + menuItem.getAttribute("data-l10n-id"), + "appmenuitem-banner-update-manual", + "Showing correct label" + ); + is(menuItem.hidden, false, "update-manual menu item is showing."); + + menuItem.click(); + ok(mainActionCalled, "Main action callback was called"); + + is( + PanelUI.menuButton.getAttribute("badge-status"), + "fxa-needs-authentication", + "Fxa badge is shown on PanelUI button." + ); + AppMenuNotifications.removeNotification(/.*/); + is( + PanelUI.menuButton.hasAttribute("badge-status"), + false, + "Should not have a badge status" + ); + }); +}); + +/** + * This tests that adding a badge will not dismiss any existing doorhangers. + */ +add_task(async function testAddingBadgeWhileDoorhangerIsShowing() { + await BrowserTestUtils.withNewTab("about:blank", function (browser) { + is( + PanelUI.notificationPanel.state, + "closed", + "update-manual doorhanger is closed." + ); + let mainActionCalled = false; + let mainAction = { + callback: () => { + mainActionCalled = true; + }, + }; + AppMenuNotifications.showNotification("update-manual", mainAction); + AppMenuNotifications.showBadgeOnlyNotification("fxa-needs-authentication"); + + isnot( + PanelUI.menuButton.getAttribute("badge-status"), + "fxa-needs-authentication", + "Fxa badge is hidden on PanelUI button." + ); + isnot( + PanelUI.notificationPanel.state, + "closed", + "update-manual doorhanger is showing." + ); + let notifications = [...PanelUI.notificationPanel.children].filter( + n => !n.hidden + ); + is( + notifications.length, + 1, + "PanelUI doorhanger is only displaying one notification." + ); + let doorhanger = notifications[0]; + is( + doorhanger.id, + "appMenu-update-manual-notification", + "PanelUI is displaying the update-manual notification." + ); + + let mainActionButton = doorhanger.button; + mainActionButton.click(); + + ok(mainActionCalled, "Main action callback was called"); + is( + PanelUI.notificationPanel.state, + "closed", + "update-manual doorhanger is closed." + ); + is( + PanelUI.menuButton.getAttribute("badge-status"), + "fxa-needs-authentication", + "Fxa badge is shown on PanelUI button." + ); + AppMenuNotifications.removeNotification(/.*/); + is( + PanelUI.menuButton.hasAttribute("badge-status"), + false, + "Should not have a badge status" + ); + }); +}); + +/** + * Tests that badges operate like a stack. + */ +add_task(async function testMultipleBadges() { + await BrowserTestUtils.withNewTab("about:blank", async function (browser) { + let doc = browser.ownerDocument; + let menuButton = doc.getElementById("PanelUI-menu-button"); + + is( + menuButton.hasAttribute("badge-status"), + false, + "Should not have a badge status" + ); + is( + menuButton.hasAttribute("badge"), + false, + "Should not have the badge attribute set" + ); + + AppMenuNotifications.showBadgeOnlyNotification("fxa-needs-authentication"); + is( + menuButton.getAttribute("badge-status"), + "fxa-needs-authentication", + "Should have fxa-needs-authentication badge status" + ); + + AppMenuNotifications.showBadgeOnlyNotification("update-succeeded"); + is( + menuButton.getAttribute("badge-status"), + "update-succeeded", + "Should have update-succeeded badge status (update > fxa)" + ); + + AppMenuNotifications.showBadgeOnlyNotification("update-failed"); + is( + menuButton.getAttribute("badge-status"), + "update-failed", + "Should have update-failed badge status" + ); + + AppMenuNotifications.removeNotification(/^update-/); + is( + menuButton.getAttribute("badge-status"), + "fxa-needs-authentication", + "Should have fxa-needs-authentication badge status" + ); + + AppMenuNotifications.removeNotification(/^fxa-/); + is( + menuButton.hasAttribute("badge-status"), + false, + "Should not have a badge status" + ); + + await gCUITestUtils.openMainMenu(); + is( + menuButton.hasAttribute("badge-status"), + false, + "Should not have a badge status (Hamburger menu opened)" + ); + await gCUITestUtils.hideMainMenu(); + + AppMenuNotifications.showBadgeOnlyNotification("fxa-needs-authentication"); + AppMenuNotifications.showBadgeOnlyNotification("update-succeeded"); + AppMenuNotifications.removeNotification(/.*/); + is( + menuButton.hasAttribute("badge-status"), + false, + "Should not have a badge status" + ); + }); +}); + +/** + * Tests that non-badges also operate like a stack. + */ +add_task(async function testMultipleNonBadges() { + await BrowserTestUtils.withNewTab("about:blank", async function (browser) { + is( + PanelUI.notificationPanel.state, + "closed", + "update-manual doorhanger is closed." + ); + + let updateManualAction = { + called: false, + callback: () => { + updateManualAction.called = true; + }, + }; + let updateRestartAction = { + called: false, + callback: () => { + updateRestartAction.called = true; + }, + }; + + AppMenuNotifications.showNotification("update-manual", updateManualAction); + + let notifications; + let doorhanger; + + isnot(PanelUI.notificationPanel.state, "closed", "Doorhanger is showing."); + notifications = [...PanelUI.notificationPanel.children].filter( + n => !n.hidden + ); + is( + notifications.length, + 1, + "PanelUI doorhanger is only displaying one notification." + ); + doorhanger = notifications[0]; + is( + doorhanger.id, + "appMenu-update-manual-notification", + "PanelUI is displaying the update-manual notification." + ); + + AppMenuNotifications.showNotification( + "update-restart", + updateRestartAction + ); + + isnot(PanelUI.notificationPanel.state, "closed", "Doorhanger is showing."); + notifications = [...PanelUI.notificationPanel.children].filter( + n => !n.hidden + ); + is( + notifications.length, + 1, + "PanelUI doorhanger is only displaying one notification." + ); + doorhanger = notifications[0]; + is( + doorhanger.id, + "appMenu-update-restart-notification", + "PanelUI is displaying the update-restart notification." + ); + + let secondaryActionButton = doorhanger.secondaryButton; + secondaryActionButton.click(); + + is( + PanelUI.notificationPanel.state, + "closed", + "update-manual doorhanger is closed." + ); + is( + PanelUI.menuButton.getAttribute("badge-status"), + "update-restart", + "update-restart badge is displaying on PanelUI button." + ); + + await gCUITestUtils.openMainMenu(); + is( + PanelUI.menuButton.getAttribute("badge-status"), + "update-restart", + "update-restart badge is displaying on PanelUI button." + ); + let menuItem = PanelUI.mainView.querySelector(".panel-banner-item"); + is( + menuItem.getAttribute("data-l10n-id"), + "appmenuitem-banner-update-restart", + "Showing correct label" + ); + is(menuItem.hidden, false, "update-restart menu item is showing."); + + menuItem.click(); + ok( + updateRestartAction.called, + "update-restart main action callback was called" + ); + + is( + PanelUI.notificationPanel.state, + "closed", + "update-manual doorhanger is closed." + ); + is( + PanelUI.menuButton.getAttribute("badge-status"), + "update-manual", + "update-manual badge is displaying on PanelUI button." + ); + + await gCUITestUtils.openMainMenu(); + is( + PanelUI.menuButton.getAttribute("badge-status"), + "update-manual", + "update-manual badge is displaying on PanelUI button." + ); + is( + menuItem.getAttribute("data-l10n-id"), + "appmenuitem-banner-update-manual", + "Showing correct label" + ); + is(menuItem.hidden, false, "update-manual menu item is showing."); + + menuItem.click(); + ok( + updateManualAction.called, + "update-manual main action callback was called" + ); + }); +}); |