browser_fullscreen_permissions_prompt.js (8345B)
1 /* Any copyright is dedicated to the Public Domain. 2 http://creativecommons.org/publicdomain/zero/1.0/ */ 3 4 "use strict"; 5 6 const { PromiseTestUtils } = ChromeUtils.importESModule( 7 "resource://testing-common/PromiseTestUtils.sys.mjs" 8 ); 9 PromiseTestUtils.allowMatchingRejectionsGlobally(/Not in fullscreen mode/); 10 11 SimpleTest.requestCompleteLog(); 12 13 async function requestNotificationPermission(browser) { 14 return SpecialPowers.spawn(browser, [], () => { 15 return content.Notification.requestPermission(); 16 }); 17 } 18 19 async function requestCameraPermission(browser) { 20 return SpecialPowers.spawn(browser, [], () => 21 content.navigator.mediaDevices 22 .getUserMedia({ video: true, fake: true }) 23 .then( 24 () => true, 25 () => false 26 ) 27 ); 28 } 29 30 add_task(async function test_fullscreen_closes_permissionui_prompt() { 31 await SpecialPowers.pushPrefEnv({ 32 set: [ 33 ["dom.webnotifications.requireuserinteraction", false], 34 ["permissions.fullscreen.allowed", false], 35 ], 36 }); 37 38 let tab = await BrowserTestUtils.openNewForegroundTab( 39 gBrowser, 40 "https://example.com" 41 ); 42 let browser = tab.linkedBrowser; 43 44 let popupShown, requestResult, popupHidden; 45 46 popupShown = BrowserTestUtils.waitForEvent( 47 window.PopupNotifications.panel, 48 "popupshown" 49 ); 50 51 info("Requesting notification permission"); 52 requestResult = requestNotificationPermission(browser); 53 await popupShown; 54 55 info("Entering DOM full-screen"); 56 popupHidden = BrowserTestUtils.waitForEvent( 57 window.PopupNotifications.panel, 58 "popuphidden" 59 ); 60 61 await DOMFullscreenTestUtils.changeFullscreen(browser, true); 62 63 await popupHidden; 64 65 is( 66 await requestResult, 67 "default", 68 "Expect permission request to be cancelled" 69 ); 70 71 await DOMFullscreenTestUtils.changeFullscreen(browser, false); 72 73 BrowserTestUtils.removeTab(tab); 74 await SpecialPowers.popPrefEnv(); 75 }); 76 77 add_task(async function test_fullscreen_closes_webrtc_permission_prompt() { 78 await SpecialPowers.pushPrefEnv({ 79 set: [ 80 ["media.navigator.permission.fake", true], 81 ["media.navigator.permission.force", true], 82 ["permissions.fullscreen.allowed", false], 83 ], 84 }); 85 86 let tab = await BrowserTestUtils.openNewForegroundTab( 87 gBrowser, 88 "https://example.com" 89 ); 90 let browser = tab.linkedBrowser; 91 let popupShown, requestResult, popupHidden; 92 93 popupShown = BrowserTestUtils.waitForEvent( 94 window.PopupNotifications.panel, 95 "popupshown" 96 ); 97 98 info("Requesting camera permission"); 99 requestResult = requestCameraPermission(browser); 100 101 await popupShown; 102 103 info("Entering DOM full-screen"); 104 popupHidden = BrowserTestUtils.waitForEvent( 105 window.PopupNotifications.panel, 106 "popuphidden" 107 ); 108 await DOMFullscreenTestUtils.changeFullscreen(browser, true); 109 110 await popupHidden; 111 112 is( 113 await requestResult, 114 false, 115 "Expect webrtc permission request to be cancelled" 116 ); 117 118 await DOMFullscreenTestUtils.changeFullscreen(browser, false); 119 120 BrowserTestUtils.removeTab(tab); 121 await SpecialPowers.popPrefEnv(); 122 }); 123 124 add_task(async function test_permission_prompt_closes_fullscreen() { 125 await SpecialPowers.pushPrefEnv({ 126 set: [ 127 ["dom.webnotifications.requireuserinteraction", false], 128 ["permissions.fullscreen.allowed", false], 129 ], 130 }); 131 132 let tab = await BrowserTestUtils.openNewForegroundTab( 133 gBrowser, 134 "https://example.com" 135 ); 136 let browser = tab.linkedBrowser; 137 info("Entering DOM full-screen"); 138 await DOMFullscreenTestUtils.changeFullscreen(browser, true); 139 140 let popupShown = BrowserTestUtils.waitForEvent( 141 window.PopupNotifications.panel, 142 "popupshown" 143 ); 144 let fullScreenExit = DOMFullscreenTestUtils.waitForFullScreenState( 145 browser, 146 false 147 ); 148 149 info("Requesting notification permission"); 150 requestNotificationPermission(browser).catch(() => {}); 151 await popupShown; 152 153 info("Waiting for full-screen exit"); 154 await fullScreenExit; 155 156 BrowserTestUtils.removeTab(tab); 157 await SpecialPowers.popPrefEnv(); 158 }); 159 160 function triggerMainCommand(popup) { 161 let notifications = popup.childNodes; 162 ok(!!notifications.length, "at least one notification displayed"); 163 let notification = notifications[0]; 164 info("Triggering main command for notification " + notification.id); 165 EventUtils.synthesizeMouseAtCenter(notification.button, {}); 166 } 167 168 add_task( 169 async function test_permission_prompt_closes_fullscreen_and_extends_security_delay() { 170 const TEST_SECURITY_DELAY = 500; 171 await SpecialPowers.pushPrefEnv({ 172 set: [ 173 ["dom.webnotifications.requireuserinteraction", false], 174 ["permissions.fullscreen.allowed", false], 175 ["security.notification_enable_delay", TEST_SECURITY_DELAY], 176 // macOS is not affected by the sec delay bug because it uses the native 177 // macOS full screen API. Revert back to legacy behavior so we can also 178 // test on macOS. If this pref is removed in the future we can consider 179 // skipping the testcase for macOS altogether. 180 ["full-screen-api.macos-native-full-screen", false], 181 ], 182 }); 183 184 let tab = await BrowserTestUtils.openNewForegroundTab( 185 gBrowser, 186 "https://example.com" 187 ); 188 let browser = tab.linkedBrowser; 189 info("Entering DOM full-screen"); 190 await DOMFullscreenTestUtils.changeFullscreen(browser, true); 191 192 let popupShown = BrowserTestUtils.waitForPopupEvent( 193 window.PopupNotifications.panel, 194 "shown" 195 ); 196 let fullScreenExit = DOMFullscreenTestUtils.waitForFullScreenState( 197 browser, 198 false 199 ); 200 201 info("Requesting notification permission"); 202 requestNotificationPermission(browser).catch(() => {}); 203 await popupShown; 204 205 let notificationHiddenPromise = BrowserTestUtils.waitForPopupEvent( 206 window.PopupNotifications.panel, 207 "hidden" 208 ); 209 210 info("Waiting for full-screen exit"); 211 await fullScreenExit; 212 213 info("Wait for original security delay to expire."); 214 SimpleTest.requestFlakyTimeout( 215 "Wait for original security delay to expire." 216 ); 217 // eslint-disable-next-line mozilla/no-arbitrary-setTimeout 218 await new Promise(resolve => setTimeout(resolve, TEST_SECURITY_DELAY)); 219 220 info( 221 "Trigger main action via button click during the extended security delay" 222 ); 223 triggerMainCommand(PopupNotifications.panel); 224 225 let notification = PopupNotifications.getNotification( 226 "web-notifications", 227 gBrowser.selectedBrowser 228 ); 229 230 // Linux in CI seems to skip the full screen animation, which means its not 231 // affected by the bug and we can't test extension of the sec delay here. 232 if (Services.appinfo.OS == "Linux") { 233 // skip this, intermittent passing on Ubuntu 24.04 234 } else { 235 ok( 236 notification && 237 !notification.dismissed && 238 BrowserTestUtils.isVisible(PopupNotifications.panel.firstChild), 239 "Notification should still be open because we clicked during the security delay." 240 ); 241 } 242 243 // If the notification is no longer shown (test failure) skip the remaining 244 // checks. 245 if (!notification) { 246 // Cleanup 247 BrowserTestUtils.removeTab(tab); 248 await SpecialPowers.popPrefEnv(); 249 // Remove the granted notification permission. 250 Services.perms.removeAll(); 251 return; 252 } 253 254 Assert.greater( 255 notification.timeShown, 256 performance.now(), 257 "Notification timeShown property should be in the future, because the security delay was extended." 258 ); 259 260 // Ensure that once the security delay has passed the notification can be 261 // closed again. 262 let fakeTimeShown = TEST_SECURITY_DELAY + 500; 263 info(`Manually set timeShown to ${fakeTimeShown}ms in the past.`); 264 notification.timeShown = performance.now() - fakeTimeShown; 265 266 info("Trigger main action via button click outside security delay"); 267 triggerMainCommand(PopupNotifications.panel); 268 269 info("Wait for panel to be hidden."); 270 await notificationHiddenPromise; 271 272 ok( 273 !PopupNotifications.getNotification( 274 "web-notifications", 275 gBrowser.selectedBrowser 276 ), 277 "Should not longer see the notification." 278 ); 279 280 // Cleanup 281 BrowserTestUtils.removeTab(tab); 282 await SpecialPowers.popPrefEnv(); 283 // Remove the granted notification permission. 284 Services.perms.removeAll(); 285 } 286 );