browser_fullscreen_exit_on_external_protocol.js (6800B)
1 /* Any copyright is dedicated to the Public Domain. 2 http://creativecommons.org/publicdomain/zero/1.0/ */ 3 "use strict"; 4 5 SimpleTest.requestCompleteLog(); 6 7 requestLongerTimeout(2); 8 9 // Import helpers 10 Services.scriptloader.loadSubScript( 11 "chrome://mochitests/content/browser/dom/base/test/fullscreen/fullscreen_helpers.js", 12 this 13 ); 14 15 add_setup(async function () { 16 await pushPrefs( 17 ["test.wait300msAfterTabSwitch", true], 18 ["full-screen-api.transition-duration.enter", "0 0"], 19 ["full-screen-api.transition-duration.leave", "0 0"], 20 ["full-screen-api.allow-trusted-requests-only", false] 21 ); 22 }); 23 24 const { HandlerServiceTestUtils } = ChromeUtils.importESModule( 25 "resource://testing-common/HandlerServiceTestUtils.sys.mjs" 26 ); 27 28 const gHandlerSvc = Cc["@mozilla.org/uriloader/handler-service;1"].getService( 29 Ci.nsIHandlerService 30 ); 31 32 const CONTENT = `data:text/html, 33 <!DOCTYPE html> 34 <html> 35 <body> 36 <button> 37 <a href="mailto:test@example.com"></a> 38 </button> 39 </body> 40 </html> 41 `; 42 43 function setupMailHandler() { 44 let mailHandlerInfo = HandlerServiceTestUtils.getHandlerInfo("mailto"); 45 let gOldMailHandlers = []; 46 47 // Remove extant web handlers because they have icons that 48 // we fetch from the web, which isn't allowed in tests. 49 let handlers = mailHandlerInfo.possibleApplicationHandlers; 50 for (let i = handlers.Count() - 1; i >= 0; i--) { 51 try { 52 let handler = handlers.queryElementAt(i, Ci.nsIWebHandlerApp); 53 gOldMailHandlers.push(handler); 54 // If we get here, this is a web handler app. Remove it: 55 handlers.removeElementAt(i); 56 } catch (ex) {} 57 } 58 59 let previousHandling = mailHandlerInfo.alwaysAskBeforeHandling; 60 mailHandlerInfo.alwaysAskBeforeHandling = true; 61 62 // Create a dummy web mail handler so we always know the mailto: protocol. 63 // Without this, the test fails on VMs without a default mailto: handler, 64 // because no dialog is ever shown, as we ignore subframe navigations to 65 // protocols that cannot be handled. 66 let dummy = Cc["@mozilla.org/uriloader/web-handler-app;1"].createInstance( 67 Ci.nsIWebHandlerApp 68 ); 69 dummy.name = "Handler 1"; 70 dummy.uriTemplate = "https://example.com/first/%s"; 71 mailHandlerInfo.possibleApplicationHandlers.appendElement(dummy); 72 73 gHandlerSvc.store(mailHandlerInfo); 74 registerCleanupFunction(() => { 75 // Re-add the original protocol handlers: 76 let mailHandlers = mailHandlerInfo.possibleApplicationHandlers; 77 for (let i = handlers.Count() - 1; i >= 0; i--) { 78 try { 79 // See if this is a web handler. If it is, it'll throw, otherwise, 80 // we will remove it. 81 mailHandlers.queryElementAt(i, Ci.nsIWebHandlerApp); 82 mailHandlers.removeElementAt(i); 83 } catch (ex) {} 84 } 85 for (let h of gOldMailHandlers) { 86 mailHandlers.appendElement(h); 87 } 88 mailHandlerInfo.alwaysAskBeforeHandling = previousHandling; 89 gHandlerSvc.store(mailHandlerInfo); 90 }); 91 } 92 93 add_task(setupMailHandler); 94 95 // Fullscreen is canceled during fullscreen transition 96 add_task(async function OpenExternalProtocolOnPendingLaterFullscreen() { 97 for (const useClick of [true, false]) { 98 await BrowserTestUtils.withNewTab(CONTENT, async browser => { 99 const leavelFullscreen = waitForFullscreenState(document, false, true); 100 await SpecialPowers.spawn( 101 browser, 102 [useClick], 103 async function (shouldClick) { 104 const button = content.document.querySelector("button"); 105 106 const clickDone = new Promise(r => { 107 button.addEventListener( 108 "click", 109 function () { 110 content.document.documentElement.requestFullscreen(); 111 // When anchor.click() is called, the fullscreen request 112 // is probably still pending. 113 content.setTimeout(() => { 114 if (shouldClick) { 115 content.document.querySelector("a").click(); 116 } else { 117 content.document.location = "mailto:test@example.com"; 118 } 119 r(); 120 }, 0); 121 }, 122 { once: true } 123 ); 124 }); 125 button.click(); 126 await clickDone; 127 } 128 ); 129 130 await leavelFullscreen; 131 ok(true, "Fullscreen should be exited"); 132 }); 133 } 134 }); 135 136 // Fullscreen is canceled immediately. 137 add_task(async function OpenExternalProtocolOnPendingFullscreen() { 138 for (const useClick of [true, false]) { 139 await BrowserTestUtils.withNewTab(CONTENT, async browser => { 140 await SpecialPowers.spawn( 141 browser, 142 [useClick], 143 async function (shouldClick) { 144 const button = content.document.querySelector("button"); 145 146 const clickDone = new Promise(r => { 147 button.addEventListener( 148 "click", 149 function () { 150 content.document.documentElement 151 .requestFullscreen() 152 .then(() => { 153 ok(false, "Don't enter fullscreen"); 154 }) 155 .catch(() => { 156 ok(true, "Cancel entering fullscreen"); 157 r(); 158 }); 159 // When anchor.click() is called, the fullscreen request 160 // is probably still pending. 161 if (shouldClick) { 162 content.document.querySelector("a").click(); 163 } else { 164 content.document.location = "mailto:test@example.com"; 165 } 166 }, 167 { once: true } 168 ); 169 }); 170 button.click(); 171 await clickDone; 172 } 173 ); 174 175 ok(true, "Fullscreen should be exited"); 176 }); 177 } 178 }); 179 180 add_task(async function OpenExternalProtocolOnFullscreen() { 181 for (const useClick of [true, false]) { 182 await BrowserTestUtils.withNewTab(CONTENT, async browser => { 183 const leavelFullscreen = waitForFullscreenState(document, false, true); 184 await SpecialPowers.spawn( 185 browser, 186 [useClick], 187 async function (shouldClick) { 188 let button = content.document.querySelector("button"); 189 button.addEventListener("click", function () { 190 content.document.documentElement.requestFullscreen(); 191 }); 192 button.click(); 193 194 await new Promise(r => { 195 content.document.addEventListener("fullscreenchange", r); 196 }); 197 198 if (shouldClick) { 199 content.document.querySelector("a").click(); 200 } else { 201 content.document.location = "mailto:test@example.com"; 202 } 203 } 204 ); 205 206 await leavelFullscreen; 207 ok(true, "Fullscreen should be exited"); 208 }); 209 } 210 });