test_bug1699721.html (3741B)
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <script src="/tests/SimpleTest/SimpleTest.js"></script> 5 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> 6 </head> 7 <body> 8 <pre id="test"> 9 <script type="text/javascript"> 10 add_task(async function() { 11 // Induce a process switching behavior for example.com 12 // with isolateHighValue isolation strategy 13 // (because we test specifically process switching behavior here) 14 await SpecialPowers.pushPermissions([ 15 { 16 type: "highValueCOOP", 17 allow: SpecialPowers.Ci.nsIPermissionManager.ALLOW_ACTION, 18 context: "https://example.com", 19 } 20 ]); 21 22 let popup = window.open("blank.html"); 23 24 info("opened popup"); 25 await new Promise(resolve => { 26 popup.addEventListener("load", resolve, { once: true }); 27 }); 28 29 info("popup blank.html loaded"); 30 let tell_opener = new URL("file_tell_opener.html", location.href); 31 // eslint-disable-next-line @microsoft/sdl/no-insecure-url 32 let xorigin_url = new URL(tell_opener.pathname, "https://example.com"); 33 34 let resolveStartedUnload; 35 let startedUnload = new Promise(resolve => { 36 resolveStartedUnload = resolve; 37 }); 38 let didFinishUnload = false; 39 40 let finishUnload = false; 41 popup.addEventListener("unload", function() { 42 resolveStartedUnload(); 43 try { 44 // Spin a nested event loop in unload until we set `finishUnload`. 45 SpecialPowers.Services.tm.spinEventLoopUntil( 46 "Test(test_switch_back_nested.html)", () => finishUnload); 47 } finally { 48 info("exiting from unload nested event loop..."); 49 didFinishUnload = true; 50 } 51 }); 52 53 info("wait for message from popup"); 54 let messagePromise = new Promise(resolve => { 55 addEventListener("message", () => { 56 resolve(); 57 }, { once: true }); 58 }); 59 popup.location = xorigin_url.href; 60 await messagePromise; 61 62 info("popup loaded, ensuring we're in unload"); 63 await startedUnload; 64 is(didFinishUnload, false, "unload shouldn't have finished"); 65 66 let switchStarted = SpecialPowers.spawnChrome([], async () => { 67 await new Promise(resolve => { 68 async function observer(subject, topic) { 69 is(topic, "http-on-examine-response"); 70 71 let uri = subject.QueryInterface(Ci.nsIChannel).URI; 72 if (!uri.filePath.endsWith("file_tell_opener.html")) { 73 return; 74 } 75 76 Services.obs.removeObserver(observer, "http-on-examine-response"); 77 78 // spin the event loop a few times to ensure we resolve after the process switch 79 for (let i = 0; i < 10; ++i) { 80 await new Promise(res => Services.tm.dispatchToMainThread(res)); 81 } 82 83 info("resolving!"); 84 resolve(); 85 } 86 Services.obs.addObserver(observer, "http-on-examine-response"); 87 }); 88 }); 89 90 info("Navigating back to the current process"); 91 await SpecialPowers.spawn(popup, [tell_opener.href], (href) => { 92 content.location.href = href; 93 }); 94 95 let messagePromise2 = new Promise(resolve => { 96 addEventListener("message", () => { 97 resolve(); 98 }, { once: true }); 99 }); 100 101 info("Waiting for the process switch to start"); 102 await switchStarted; 103 104 // Finish unloading, and wait for the unload to complete 105 is(didFinishUnload, false, "unload shouldn't be finished"); 106 finishUnload = true; 107 await new Promise(resolve => setTimeout(resolve, 0)); 108 is(didFinishUnload, true, "unload should be finished"); 109 110 info("waiting for navigation to complete"); 111 await messagePromise2; 112 113 info("closing popup"); 114 popup.close(); 115 116 ok(true, "Didn't crash"); 117 }); 118 </script> 119 </pre> 120 </body> 121 </html>