/* 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/. */ // These are shared between test #4 to #5 var wrongBrowserNotificationObject = new BasicNotification("wrongBrowser"); var wrongBrowserNotification; function test() { waitForExplicitFinish(); ok(PopupNotifications, "PopupNotifications object exists"); ok(PopupNotifications.panel, "PopupNotifications panel exists"); setup(); } var tests = [ { id: "Test#1", run() { this.notifyObj = new BasicNotification(this.id); showNotification(this.notifyObj); }, onShown(popup) { checkPopup(popup, this.notifyObj); triggerMainCommand(popup); }, onHidden(popup) { ok(this.notifyObj.mainActionClicked, "mainAction was clicked"); ok( !this.notifyObj.dismissalCallbackTriggered, "dismissal callback wasn't triggered" ); ok(this.notifyObj.removedCallbackTriggered, "removed callback triggered"); is( this.notifyObj.mainActionSource, "button", "main action should have been triggered by button." ); is( this.notifyObj.secondaryActionSource, undefined, "shouldn't have a secondary action source." ); }, }, { id: "Test#2", run() { this.notifyObj = new BasicNotification(this.id); showNotification(this.notifyObj); }, onShown(popup) { checkPopup(popup, this.notifyObj); triggerSecondaryCommand(popup, 0); }, onHidden(popup) { 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, "button", "secondary action should have been triggered by button." ); }, }, { id: "Test#2b", run() { this.notifyObj = new BasicNotification(this.id); this.notifyObj.secondaryActions.push({ label: "Extra Secondary Action", accessKey: "E", callback: () => (this.extraSecondaryActionClicked = true), }); showNotification(this.notifyObj); }, onShown(popup) { checkPopup(popup, this.notifyObj); triggerSecondaryCommand(popup, 1); }, onHidden(popup) { ok( this.extraSecondaryActionClicked, "extra secondary action was clicked" ); ok( !this.notifyObj.dismissalCallbackTriggered, "dismissal callback wasn't triggered" ); ok(this.notifyObj.removedCallbackTriggered, "removed callback triggered"); }, }, { id: "Test#2c", run() { this.notifyObj = new BasicNotification(this.id); this.notifyObj.secondaryActions.push( { label: "Extra Secondary Action", accessKey: "E", callback: () => ok(false, "unexpected callback invocation"), }, { label: "Other Extra Secondary Action", accessKey: "O", callback: () => (this.extraSecondaryActionClicked = true), } ); showNotification(this.notifyObj); }, onShown(popup) { checkPopup(popup, this.notifyObj); triggerSecondaryCommand(popup, 2); }, onHidden(popup) { ok( this.extraSecondaryActionClicked, "extra secondary action was clicked" ); ok( !this.notifyObj.dismissalCallbackTriggered, "dismissal callback wasn't triggered" ); ok(this.notifyObj.removedCallbackTriggered, "removed callback triggered"); }, }, { id: "Test#3", run() { this.notifyObj = new BasicNotification(this.id); this.notification = showNotification(this.notifyObj); }, onShown(popup) { checkPopup(popup, this.notifyObj); dismissNotification(popup); }, onHidden(popup) { ok( this.notifyObj.dismissalCallbackTriggered, "dismissal callback triggered" ); this.notification.remove(); ok(this.notifyObj.removedCallbackTriggered, "removed callback triggered"); }, }, // test opening a notification for a background browser // Note: test 4 to 6 share a tab. { id: "Test#4", async run() { // eslint-disable-next-line @microsoft/sdl/no-insecure-url let tab = BrowserTestUtils.addTab(gBrowser, "http://example.com/"); await BrowserTestUtils.browserLoaded(tab.linkedBrowser); isnot(gBrowser.selectedTab, tab, "new tab isn't selected"); wrongBrowserNotificationObject.browser = gBrowser.getBrowserForTab(tab); let promiseTopic = TestUtils.topicObserved( "PopupNotifications-backgroundShow" ); wrongBrowserNotification = showNotification( wrongBrowserNotificationObject ); await promiseTopic; is(PopupNotifications.isPanelOpen, false, "panel isn't open"); ok( !wrongBrowserNotificationObject.mainActionClicked, "main action wasn't clicked" ); ok( !wrongBrowserNotificationObject.secondaryActionClicked, "secondary action wasn't clicked" ); ok( !wrongBrowserNotificationObject.dismissalCallbackTriggered, "dismissal callback wasn't called" ); goNext(); }, }, // now select that browser and test to see that the notification appeared { id: "Test#5", run() { this.oldSelectedTab = gBrowser.selectedTab; gBrowser.selectedTab = gBrowser.tabs[gBrowser.tabs.length - 1]; }, onShown(popup) { checkPopup(popup, wrongBrowserNotificationObject); is( PopupNotifications.isPanelOpen, true, "isPanelOpen getter doesn't lie" ); // switch back to the old browser gBrowser.selectedTab = this.oldSelectedTab; }, onHidden(popup) { // actually remove the notification to prevent it from reappearing ok( wrongBrowserNotificationObject.dismissalCallbackTriggered, "dismissal callback triggered due to tab switch" ); wrongBrowserNotification.remove(); ok( wrongBrowserNotificationObject.removedCallbackTriggered, "removed callback triggered" ); wrongBrowserNotification = null; }, }, // test that the removed notification isn't shown on browser re-select { id: "Test#6", async run() { let promiseTopic = TestUtils.topicObserved( "PopupNotifications-updateNotShowing" ); gBrowser.selectedTab = gBrowser.tabs[gBrowser.tabs.length - 1]; await promiseTopic; is(PopupNotifications.isPanelOpen, false, "panel isn't open"); gBrowser.removeTab(gBrowser.selectedTab); goNext(); }, }, // Test that two notifications with the same ID result in a single displayed // notification. { id: "Test#7", run() { this.notifyObj = new BasicNotification(this.id); // Show the same notification twice this.notification1 = showNotification(this.notifyObj); this.notification2 = showNotification(this.notifyObj); }, onShown(popup) { checkPopup(popup, this.notifyObj); this.notification2.remove(); }, onHidden(popup) { ok( !this.notifyObj.dismissalCallbackTriggered, "dismissal callback wasn't triggered" ); ok(this.notifyObj.removedCallbackTriggered, "removed callback triggered"); }, }, // Test that two notifications with different IDs are displayed { id: "Test#8", run() { this.testNotif1 = new BasicNotification(this.id); this.testNotif1.message += " 1"; showNotification(this.testNotif1); this.testNotif2 = new BasicNotification(this.id); this.testNotif2.message += " 2"; this.testNotif2.id += "-2"; showNotification(this.testNotif2); }, onShown(popup) { is(popup.children.length, 2, "two notifications are shown"); // Trigger the main command for the first notification, and the secondary // for the second. Need to do mainCommand first since the secondaryCommand // triggering is async. triggerMainCommand(popup); is(popup.children.length, 1, "only one notification left"); triggerSecondaryCommand(popup, 0); }, onHidden(popup) { ok(this.testNotif1.mainActionClicked, "main action #1 was clicked"); ok( !this.testNotif1.secondaryActionClicked, "secondary action #1 wasn't clicked" ); ok( !this.testNotif1.dismissalCallbackTriggered, "dismissal callback #1 wasn't called" ); ok(!this.testNotif2.mainActionClicked, "main action #2 wasn't clicked"); ok( this.testNotif2.secondaryActionClicked, "secondary action #2 was clicked" ); ok( !this.testNotif2.dismissalCallbackTriggered, "dismissal callback #2 wasn't called" ); }, }, // Test notification without mainAction or secondaryActions, it should fall back // to a default button that dismisses the notification in place of the main action. { id: "Test#9", run() { this.notifyObj = new BasicNotification(this.id); this.notifyObj.mainAction = null; this.notifyObj.secondaryActions = null; this.notification = showNotification(this.notifyObj); }, onShown(popup) { let notification = popup.children[0]; ok( notification.hasAttribute("buttonhighlight"), "default action is highlighted" ); triggerMainCommand(popup); }, onHidden(popup) { ok(!this.notifyObj.mainActionClicked, "mainAction was not clicked"); ok( !this.notifyObj.dismissalCallbackTriggered, "dismissal callback wasn't triggered" ); ok(this.notifyObj.removedCallbackTriggered, "removed callback triggered"); }, }, // Test notification without mainAction but with secondaryActions, it should fall back // to a default button that dismisses the notification in place of the main action // and ignore the passed secondaryActions. { id: "Test#10", run() { this.notifyObj = new BasicNotification(this.id); this.notifyObj.mainAction = null; this.notification = showNotification(this.notifyObj); }, onShown(popup) { let notification = popup.children[0]; is( notification.getAttribute("secondarybuttonhidden"), "true", "secondary button is hidden" ); ok( notification.hasAttribute("buttonhighlight"), "default action is highlighted" ); triggerMainCommand(popup); }, onHidden(popup) { ok(!this.notifyObj.mainActionClicked, "mainAction was not clicked"); ok( !this.notifyObj.dismissalCallbackTriggered, "dismissal callback wasn't triggered" ); ok(this.notifyObj.removedCallbackTriggered, "removed callback triggered"); }, }, // Test two notifications with different anchors { id: "Test#11", run() { this.notifyObj = new BasicNotification(this.id); this.firstNotification = showNotification(this.notifyObj); this.notifyObj2 = new BasicNotification(this.id); this.notifyObj2.id += "-2"; this.notifyObj2.anchorID = "addons-notification-icon"; // Second showNotification() overrides the first this.secondNotification = showNotification(this.notifyObj2); }, onShown(popup) { // This also checks that only one element is shown. checkPopup(popup, this.notifyObj2); is( document.getElementById("geo-notification-icon").getBoundingClientRect() .width, 0, "geo anchor shouldn't be visible" ); dismissNotification(popup); }, onHidden(popup) { // Remove the notifications this.firstNotification.remove(); this.secondNotification.remove(); ok(this.notifyObj.removedCallbackTriggered, "removed callback triggered"); ok( this.notifyObj2.removedCallbackTriggered, "removed callback triggered" ); }, }, ];