browser_popupNotification_3.js (11967B)
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 /* eslint-disable mozilla/no-arbitrary-setTimeout */ 5 6 function test() { 7 waitForExplicitFinish(); 8 9 ok(PopupNotifications, "PopupNotifications object exists"); 10 ok(PopupNotifications.panel, "PopupNotifications panel exists"); 11 12 setup(); 13 } 14 15 var tests = [ 16 // Test notification is removed when dismissed if removeOnDismissal is true 17 { 18 id: "Test#1", 19 run() { 20 this.notifyObj = new BasicNotification(this.id); 21 this.notifyObj.addOptions({ 22 removeOnDismissal: true, 23 }); 24 this.notification = showNotification(this.notifyObj); 25 }, 26 onShown(popup) { 27 checkPopup(popup, this.notifyObj); 28 dismissNotification(popup); 29 }, 30 onHidden() { 31 ok( 32 !this.notifyObj.dismissalCallbackTriggered, 33 "dismissal callback wasn't triggered" 34 ); 35 ok(this.notifyObj.removedCallbackTriggered, "removed callback triggered"); 36 }, 37 }, 38 // Test multiple notification icons are shown 39 { 40 id: "Test#2", 41 run() { 42 this.notifyObj1 = new BasicNotification(this.id); 43 this.notifyObj1.id += "_1"; 44 this.notifyObj1.anchorID = "default-notification-icon"; 45 this.notification1 = showNotification(this.notifyObj1); 46 47 this.notifyObj2 = new BasicNotification(this.id); 48 this.notifyObj2.id += "_2"; 49 this.notifyObj2.anchorID = "geo-notification-icon"; 50 this.notification2 = showNotification(this.notifyObj2); 51 }, 52 onShown(popup) { 53 checkPopup(popup, this.notifyObj2); 54 55 // check notifyObj1 anchor icon is showing 56 isnot( 57 document 58 .getElementById("default-notification-icon") 59 .getBoundingClientRect().width, 60 0, 61 "default anchor should be visible" 62 ); 63 // check notifyObj2 anchor icon is showing 64 isnot( 65 document.getElementById("geo-notification-icon").getBoundingClientRect() 66 .width, 67 0, 68 "geo anchor should be visible" 69 ); 70 71 dismissNotification(popup); 72 }, 73 onHidden() { 74 this.notification1.remove(); 75 ok( 76 this.notifyObj1.removedCallbackTriggered, 77 "removed callback triggered" 78 ); 79 80 this.notification2.remove(); 81 ok( 82 this.notifyObj2.removedCallbackTriggered, 83 "removed callback triggered" 84 ); 85 }, 86 }, 87 // Test that multiple notification icons are removed when switching tabs 88 { 89 id: "Test#3", 90 async run() { 91 // show the notification on old tab. 92 this.notifyObjOld = new BasicNotification(this.id); 93 this.notifyObjOld.anchorID = "default-notification-icon"; 94 this.notificationOld = showNotification(this.notifyObjOld); 95 96 // switch tab 97 this.oldSelectedTab = gBrowser.selectedTab; 98 await BrowserTestUtils.openNewForegroundTab( 99 gBrowser, 100 // eslint-disable-next-line @microsoft/sdl/no-insecure-url 101 "http://example.com/" 102 ); 103 104 // show the notification on new tab. 105 this.notifyObjNew = new BasicNotification(this.id); 106 this.notifyObjNew.anchorID = "geo-notification-icon"; 107 this.notificationNew = showNotification(this.notifyObjNew); 108 }, 109 onShown(popup) { 110 checkPopup(popup, this.notifyObjNew); 111 112 // check notifyObjOld anchor icon is removed 113 is( 114 document 115 .getElementById("default-notification-icon") 116 .getBoundingClientRect().width, 117 0, 118 "default anchor shouldn't be visible" 119 ); 120 // check notifyObjNew anchor icon is showing 121 isnot( 122 document.getElementById("geo-notification-icon").getBoundingClientRect() 123 .width, 124 0, 125 "geo anchor should be visible" 126 ); 127 128 dismissNotification(popup); 129 }, 130 onHidden() { 131 this.notificationNew.remove(); 132 gBrowser.removeTab(gBrowser.selectedTab); 133 134 gBrowser.selectedTab = this.oldSelectedTab; 135 this.notificationOld.remove(); 136 }, 137 }, 138 // test security delay - too early 139 { 140 id: "Test#4", 141 async run() { 142 // Set the security delay to 100s 143 await SpecialPowers.pushPrefEnv({ 144 set: [["security.notification_enable_delay", 100000]], 145 }); 146 147 this.notifyObj = new BasicNotification(this.id); 148 showNotification(this.notifyObj); 149 }, 150 onShown(popup) { 151 checkPopup(popup, this.notifyObj); 152 triggerMainCommand(popup); 153 154 // Wait to see if the main command worked 155 executeSoon(function delayedDismissal() { 156 dismissNotification(popup); 157 }); 158 }, 159 onHidden() { 160 ok( 161 !this.notifyObj.mainActionClicked, 162 "mainAction was not clicked because it was too soon" 163 ); 164 ok( 165 this.notifyObj.dismissalCallbackTriggered, 166 "dismissal callback was triggered" 167 ); 168 }, 169 }, 170 // test security delay - after delay 171 { 172 id: "Test#5", 173 async run() { 174 // Set the security delay to 10ms 175 176 await SpecialPowers.pushPrefEnv({ 177 set: [["security.notification_enable_delay", 10]], 178 }); 179 180 this.notifyObj = new BasicNotification(this.id); 181 showNotification(this.notifyObj); 182 }, 183 onShown(popup) { 184 checkPopup(popup, this.notifyObj); 185 186 // Wait until after the delay to trigger the main action 187 setTimeout(function delayedDismissal() { 188 triggerMainCommand(popup); 189 }, 500); 190 }, 191 onHidden() { 192 ok( 193 this.notifyObj.mainActionClicked, 194 "mainAction was clicked after the delay" 195 ); 196 ok( 197 !this.notifyObj.dismissalCallbackTriggered, 198 "dismissal callback was not triggered" 199 ); 200 }, 201 }, 202 // reload removes notification 203 { 204 id: "Test#6", 205 async run() { 206 await BrowserTestUtils.loadURIString({ 207 browser: gBrowser.selectedTab.linkedBrowser, 208 // eslint-disable-next-line @microsoft/sdl/no-insecure-url 209 uriString: "http://example.com/", 210 }); 211 let notifyObj = new BasicNotification(this.id); 212 notifyObj.options.eventCallback = function (eventName) { 213 if (eventName == "removed") { 214 ok(true, "Notification removed in background tab after reloading"); 215 goNext(); 216 } 217 }; 218 showNotification(notifyObj); 219 executeSoon(function () { 220 gBrowser.selectedBrowser.reload(); 221 }); 222 }, 223 }, 224 // location change in background tab removes notification 225 { 226 id: "Test#7", 227 async run() { 228 let oldSelectedTab = gBrowser.selectedTab; 229 let newTab = await BrowserTestUtils.openNewForegroundTab( 230 gBrowser, 231 // eslint-disable-next-line @microsoft/sdl/no-insecure-url 232 "http://example.com/" 233 ); 234 gBrowser.selectedTab = oldSelectedTab; 235 let browser = gBrowser.getBrowserForTab(newTab); 236 237 let notifyObj = new BasicNotification(this.id); 238 notifyObj.browser = browser; 239 notifyObj.options.eventCallback = function (eventName) { 240 if (eventName == "removed") { 241 ok(true, "Notification removed in background tab after reloading"); 242 executeSoon(function () { 243 gBrowser.removeTab(newTab); 244 goNext(); 245 }); 246 } 247 }; 248 showNotification(notifyObj); 249 executeSoon(function () { 250 browser.reload(); 251 }); 252 }, 253 }, 254 // Popup notification anchor shouldn't disappear when a notification with the same ID is re-added in a background tab 255 { 256 id: "Test#8", 257 async run() { 258 await BrowserTestUtils.loadURIString({ 259 browser: gBrowser.selectedTab.linkedBrowser, 260 // eslint-disable-next-line @microsoft/sdl/no-insecure-url 261 uriString: "http://example.com/", 262 }); 263 let originalTab = gBrowser.selectedTab; 264 let bgTab = await BrowserTestUtils.openNewForegroundTab( 265 gBrowser, 266 // eslint-disable-next-line @microsoft/sdl/no-insecure-url 267 "http://example.com/" 268 ); 269 let anchor = document.createXULElement("box"); 270 anchor.id = "test26-anchor"; 271 anchor.className = "notification-anchor-icon"; 272 PopupNotifications.iconBox.appendChild(anchor); 273 274 gBrowser.selectedTab = originalTab; 275 276 let fgNotifyObj = new BasicNotification(this.id); 277 fgNotifyObj.anchorID = anchor.id; 278 fgNotifyObj.options.dismissed = true; 279 let fgNotification = showNotification(fgNotifyObj); 280 281 let bgNotifyObj = new BasicNotification(this.id); 282 bgNotifyObj.anchorID = anchor.id; 283 bgNotifyObj.browser = gBrowser.getBrowserForTab(bgTab); 284 // show the notification in the background tab ... 285 let bgNotification = showNotification(bgNotifyObj); 286 // ... and re-show it 287 bgNotification = showNotification(bgNotifyObj); 288 289 ok(fgNotification.id, "notification has id"); 290 is(fgNotification.id, bgNotification.id, "notification ids are the same"); 291 is(anchor.getAttribute("showing"), "true", "anchor still showing"); 292 293 fgNotification.remove(); 294 gBrowser.removeTab(bgTab); 295 goNext(); 296 }, 297 }, 298 // location change in an embedded frame should not remove a notification 299 { 300 id: "Test#9", 301 async run() { 302 await BrowserTestUtils.loadURIString({ 303 browser: gBrowser.selectedTab.linkedBrowser, 304 uriString: 305 "data:text/html;charset=utf8,<iframe%20id='iframe'%20src='http://example.com/'>", 306 }); 307 this.notifyObj = new BasicNotification(this.id); 308 this.notifyObj.options.eventCallback = function (eventName) { 309 if (eventName == "removed") { 310 ok( 311 false, 312 "Notification removed from browser when subframe navigated" 313 ); 314 } 315 }; 316 showNotification(this.notifyObj); 317 }, 318 async onShown() { 319 info("Adding observer and performing navigation"); 320 321 await Promise.all([ 322 BrowserUtils.promiseObserved("window-global-created", wgp => 323 // eslint-disable-next-line @microsoft/sdl/no-insecure-url 324 wgp.documentURI.spec.startsWith("http://example.org/") 325 ), 326 SpecialPowers.spawn(gBrowser.selectedBrowser, [], function () { 327 content.document 328 .getElementById("iframe") 329 // eslint-disable-next-line @microsoft/sdl/no-insecure-url 330 .setAttribute("src", "http://example.org/"); 331 }), 332 ]); 333 334 executeSoon(() => { 335 let notification = PopupNotifications.getNotification( 336 this.notifyObj.id, 337 this.notifyObj.browser 338 ); 339 Assert.notEqual( 340 notification, 341 null, 342 "Notification remained when subframe navigated" 343 ); 344 this.notifyObj.options.eventCallback = undefined; 345 346 notification.remove(); 347 }); 348 }, 349 onHidden() {}, 350 }, 351 // Popup Notifications should catch exceptions from callbacks 352 { 353 id: "Test#10", 354 run() { 355 this.testNotif1 = new BasicNotification(this.id); 356 this.testNotif1.message += " 1"; 357 this.notification1 = showNotification(this.testNotif1); 358 this.testNotif1.options.eventCallback = function (eventName) { 359 info("notifyObj1.options.eventCallback: " + eventName); 360 if (eventName == "dismissed") { 361 throw new Error("Oops 1!"); 362 } 363 }; 364 365 this.testNotif2 = new BasicNotification(this.id); 366 this.testNotif2.message += " 2"; 367 this.testNotif2.id += "-2"; 368 this.testNotif2.options.eventCallback = function (eventName) { 369 info("notifyObj2.options.eventCallback: " + eventName); 370 if (eventName == "dismissed") { 371 throw new Error("Oops 2!"); 372 } 373 }; 374 this.notification2 = showNotification(this.testNotif2); 375 }, 376 onShown(popup) { 377 is(popup.children.length, 2, "two notifications are shown"); 378 dismissNotification(popup); 379 }, 380 onHidden() { 381 this.notification1.remove(); 382 this.notification2.remove(); 383 }, 384 }, 385 ];