browser_popupNotification.js (12344B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 // These are shared between test #4 to #5 6 var wrongBrowserNotificationObject = new BasicNotification("wrongBrowser"); 7 var wrongBrowserNotification; 8 9 function test() { 10 waitForExplicitFinish(); 11 12 ok(PopupNotifications, "PopupNotifications object exists"); 13 ok(PopupNotifications.panel, "PopupNotifications panel exists"); 14 15 setup(); 16 } 17 18 var tests = [ 19 { 20 id: "Test#1", 21 run() { 22 this.notifyObj = new BasicNotification(this.id); 23 showNotification(this.notifyObj); 24 }, 25 onShown(popup) { 26 checkPopup(popup, this.notifyObj); 27 triggerMainCommand(popup); 28 }, 29 onHidden() { 30 ok(this.notifyObj.mainActionClicked, "mainAction was clicked"); 31 ok( 32 !this.notifyObj.dismissalCallbackTriggered, 33 "dismissal callback wasn't triggered" 34 ); 35 ok(this.notifyObj.removedCallbackTriggered, "removed callback triggered"); 36 is( 37 this.notifyObj.mainActionSource, 38 "button", 39 "main action should have been triggered by button." 40 ); 41 is( 42 this.notifyObj.secondaryActionSource, 43 undefined, 44 "shouldn't have a secondary action source." 45 ); 46 }, 47 }, 48 { 49 id: "Test#2", 50 run() { 51 this.notifyObj = new BasicNotification(this.id); 52 showNotification(this.notifyObj); 53 }, 54 onShown(popup) { 55 checkPopup(popup, this.notifyObj); 56 triggerSecondaryCommand(popup, 0); 57 }, 58 onHidden() { 59 ok(this.notifyObj.secondaryActionClicked, "secondaryAction was clicked"); 60 ok( 61 !this.notifyObj.dismissalCallbackTriggered, 62 "dismissal callback wasn't triggered" 63 ); 64 ok(this.notifyObj.removedCallbackTriggered, "removed callback triggered"); 65 is( 66 this.notifyObj.mainActionSource, 67 undefined, 68 "shouldn't have a main action source." 69 ); 70 is( 71 this.notifyObj.secondaryActionSource, 72 "button", 73 "secondary action should have been triggered by button." 74 ); 75 }, 76 }, 77 { 78 id: "Test#2b", 79 run() { 80 this.notifyObj = new BasicNotification(this.id); 81 this.notifyObj.secondaryActions.push({ 82 label: "Extra Secondary Action", 83 accessKey: "E", 84 callback: () => (this.extraSecondaryActionClicked = true), 85 }); 86 showNotification(this.notifyObj); 87 }, 88 onShown(popup) { 89 checkPopup(popup, this.notifyObj); 90 triggerSecondaryCommand(popup, 1); 91 }, 92 onHidden() { 93 ok( 94 this.extraSecondaryActionClicked, 95 "extra secondary action was clicked" 96 ); 97 ok( 98 !this.notifyObj.dismissalCallbackTriggered, 99 "dismissal callback wasn't triggered" 100 ); 101 ok(this.notifyObj.removedCallbackTriggered, "removed callback triggered"); 102 }, 103 }, 104 { 105 id: "Test#2c", 106 run() { 107 this.notifyObj = new BasicNotification(this.id); 108 this.notifyObj.secondaryActions.push( 109 { 110 label: "Extra Secondary Action", 111 accessKey: "E", 112 callback: () => ok(false, "unexpected callback invocation"), 113 }, 114 { 115 label: "Other Extra Secondary Action", 116 accessKey: "O", 117 callback: () => (this.extraSecondaryActionClicked = true), 118 } 119 ); 120 showNotification(this.notifyObj); 121 }, 122 onShown(popup) { 123 checkPopup(popup, this.notifyObj); 124 triggerSecondaryCommand(popup, 2); 125 }, 126 onHidden() { 127 ok( 128 this.extraSecondaryActionClicked, 129 "extra secondary action was clicked" 130 ); 131 ok( 132 !this.notifyObj.dismissalCallbackTriggered, 133 "dismissal callback wasn't triggered" 134 ); 135 ok(this.notifyObj.removedCallbackTriggered, "removed callback triggered"); 136 }, 137 }, 138 { 139 id: "Test#3", 140 run() { 141 this.notifyObj = new BasicNotification(this.id); 142 this.notification = showNotification(this.notifyObj); 143 }, 144 onShown(popup) { 145 checkPopup(popup, this.notifyObj); 146 dismissNotification(popup); 147 }, 148 onHidden() { 149 ok( 150 this.notifyObj.dismissalCallbackTriggered, 151 "dismissal callback triggered" 152 ); 153 this.notification.remove(); 154 ok(this.notifyObj.removedCallbackTriggered, "removed callback triggered"); 155 }, 156 }, 157 // test opening a notification for a background browser 158 // Note: test 4 to 6 share a tab. 159 { 160 id: "Test#4", 161 async run() { 162 // eslint-disable-next-line @microsoft/sdl/no-insecure-url 163 let tab = BrowserTestUtils.addTab(gBrowser, "http://example.com/"); 164 await BrowserTestUtils.browserLoaded(tab.linkedBrowser); 165 isnot(gBrowser.selectedTab, tab, "new tab isn't selected"); 166 wrongBrowserNotificationObject.browser = gBrowser.getBrowserForTab(tab); 167 let promiseTopic = TestUtils.topicObserved( 168 "PopupNotifications-backgroundShow" 169 ); 170 wrongBrowserNotification = showNotification( 171 wrongBrowserNotificationObject 172 ); 173 await promiseTopic; 174 is(PopupNotifications.isPanelOpen, false, "panel isn't open"); 175 ok( 176 !wrongBrowserNotificationObject.mainActionClicked, 177 "main action wasn't clicked" 178 ); 179 ok( 180 !wrongBrowserNotificationObject.secondaryActionClicked, 181 "secondary action wasn't clicked" 182 ); 183 ok( 184 !wrongBrowserNotificationObject.dismissalCallbackTriggered, 185 "dismissal callback wasn't called" 186 ); 187 goNext(); 188 }, 189 }, 190 // now select that browser and test to see that the notification appeared 191 { 192 id: "Test#5", 193 run() { 194 this.oldSelectedTab = gBrowser.selectedTab; 195 gBrowser.selectedTab = gBrowser.tabs[gBrowser.tabs.length - 1]; 196 }, 197 onShown(popup) { 198 checkPopup(popup, wrongBrowserNotificationObject); 199 is( 200 PopupNotifications.isPanelOpen, 201 true, 202 "isPanelOpen getter doesn't lie" 203 ); 204 205 // switch back to the old browser 206 gBrowser.selectedTab = this.oldSelectedTab; 207 }, 208 onHidden() { 209 // actually remove the notification to prevent it from reappearing 210 ok( 211 wrongBrowserNotificationObject.dismissalCallbackTriggered, 212 "dismissal callback triggered due to tab switch" 213 ); 214 wrongBrowserNotification.remove(); 215 ok( 216 wrongBrowserNotificationObject.removedCallbackTriggered, 217 "removed callback triggered" 218 ); 219 wrongBrowserNotification = null; 220 }, 221 }, 222 // test that the removed notification isn't shown on browser re-select 223 { 224 id: "Test#6", 225 async run() { 226 let promiseTopic = TestUtils.topicObserved( 227 "PopupNotifications-updateNotShowing" 228 ); 229 gBrowser.selectedTab = gBrowser.tabs[gBrowser.tabs.length - 1]; 230 await promiseTopic; 231 is(PopupNotifications.isPanelOpen, false, "panel isn't open"); 232 gBrowser.removeTab(gBrowser.selectedTab); 233 goNext(); 234 }, 235 }, 236 // Test that two notifications with the same ID result in a single displayed 237 // notification. 238 { 239 id: "Test#7", 240 run() { 241 this.notifyObj = new BasicNotification(this.id); 242 // Show the same notification twice 243 this.notification1 = showNotification(this.notifyObj); 244 this.notification2 = showNotification(this.notifyObj); 245 }, 246 onShown(popup) { 247 checkPopup(popup, this.notifyObj); 248 this.notification2.remove(); 249 }, 250 onHidden() { 251 ok( 252 !this.notifyObj.dismissalCallbackTriggered, 253 "dismissal callback wasn't triggered" 254 ); 255 ok(this.notifyObj.removedCallbackTriggered, "removed callback triggered"); 256 }, 257 }, 258 // Test that two notifications with different IDs are displayed 259 { 260 id: "Test#8", 261 run() { 262 this.testNotif1 = new BasicNotification(this.id); 263 this.testNotif1.message += " 1"; 264 showNotification(this.testNotif1); 265 this.testNotif2 = new BasicNotification(this.id); 266 this.testNotif2.message += " 2"; 267 this.testNotif2.id += "-2"; 268 showNotification(this.testNotif2); 269 }, 270 onShown(popup) { 271 is(popup.children.length, 2, "two notifications are shown"); 272 // Trigger the main command for the first notification, and the secondary 273 // for the second. Need to do mainCommand first since the secondaryCommand 274 // triggering is async. 275 triggerMainCommand(popup); 276 is(popup.children.length, 1, "only one notification left"); 277 triggerSecondaryCommand(popup, 0); 278 }, 279 onHidden() { 280 ok(this.testNotif1.mainActionClicked, "main action #1 was clicked"); 281 ok( 282 !this.testNotif1.secondaryActionClicked, 283 "secondary action #1 wasn't clicked" 284 ); 285 ok( 286 !this.testNotif1.dismissalCallbackTriggered, 287 "dismissal callback #1 wasn't called" 288 ); 289 290 ok(!this.testNotif2.mainActionClicked, "main action #2 wasn't clicked"); 291 ok( 292 this.testNotif2.secondaryActionClicked, 293 "secondary action #2 was clicked" 294 ); 295 ok( 296 !this.testNotif2.dismissalCallbackTriggered, 297 "dismissal callback #2 wasn't called" 298 ); 299 }, 300 }, 301 // Test notification without mainAction or secondaryActions, it should fall back 302 // to a default button that dismisses the notification in place of the main action. 303 { 304 id: "Test#9", 305 run() { 306 this.notifyObj = new BasicNotification(this.id); 307 this.notifyObj.mainAction = null; 308 this.notifyObj.secondaryActions = null; 309 this.notification = showNotification(this.notifyObj); 310 }, 311 onShown(popup) { 312 let notification = popup.children[0]; 313 ok( 314 notification.hasAttribute("buttonhighlight"), 315 "default action is highlighted" 316 ); 317 triggerMainCommand(popup); 318 }, 319 onHidden() { 320 ok(!this.notifyObj.mainActionClicked, "mainAction was not clicked"); 321 ok( 322 !this.notifyObj.dismissalCallbackTriggered, 323 "dismissal callback wasn't triggered" 324 ); 325 ok(this.notifyObj.removedCallbackTriggered, "removed callback triggered"); 326 }, 327 }, 328 // Test notification without mainAction but with secondaryActions, it should fall back 329 // to a default button that dismisses the notification in place of the main action 330 // and ignore the passed secondaryActions. 331 { 332 id: "Test#10", 333 run() { 334 this.notifyObj = new BasicNotification(this.id); 335 this.notifyObj.mainAction = null; 336 this.notification = showNotification(this.notifyObj); 337 }, 338 onShown(popup) { 339 let notification = popup.children[0]; 340 ok( 341 notification.hasAttribute("secondarybuttonhidden"), 342 "secondary button is hidden" 343 ); 344 ok( 345 notification.hasAttribute("buttonhighlight"), 346 "default action is highlighted" 347 ); 348 triggerMainCommand(popup); 349 }, 350 onHidden() { 351 ok(!this.notifyObj.mainActionClicked, "mainAction was not clicked"); 352 ok( 353 !this.notifyObj.dismissalCallbackTriggered, 354 "dismissal callback wasn't triggered" 355 ); 356 ok(this.notifyObj.removedCallbackTriggered, "removed callback triggered"); 357 }, 358 }, 359 // Test two notifications with different anchors 360 { 361 id: "Test#11", 362 run() { 363 this.notifyObj = new BasicNotification(this.id); 364 this.firstNotification = showNotification(this.notifyObj); 365 this.notifyObj2 = new BasicNotification(this.id); 366 this.notifyObj2.id += "-2"; 367 this.notifyObj2.anchorID = "addons-notification-icon"; 368 // Second showNotification() overrides the first 369 this.secondNotification = showNotification(this.notifyObj2); 370 }, 371 onShown(popup) { 372 // This also checks that only one element is shown. 373 checkPopup(popup, this.notifyObj2); 374 is( 375 document.getElementById("geo-notification-icon").getBoundingClientRect() 376 .width, 377 0, 378 "geo anchor shouldn't be visible" 379 ); 380 dismissNotification(popup); 381 }, 382 onHidden() { 383 // Remove the notifications 384 this.firstNotification.remove(); 385 this.secondNotification.remove(); 386 ok(this.notifyObj.removedCallbackTriggered, "removed callback triggered"); 387 ok( 388 this.notifyObj2.removedCallbackTriggered, 389 "removed callback triggered" 390 ); 391 }, 392 }, 393 ];