diff options
Diffstat (limited to '')
-rw-r--r-- | docshell/test/navigation/test_bug1699721.html | 121 |
1 files changed, 121 insertions, 0 deletions
diff --git a/docshell/test/navigation/test_bug1699721.html b/docshell/test/navigation/test_bug1699721.html new file mode 100644 index 0000000000..c6ae8e88d3 --- /dev/null +++ b/docshell/test/navigation/test_bug1699721.html @@ -0,0 +1,121 @@ +<!DOCTYPE html> +<html> +<head> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<pre id="test"> +<script type="text/javascript"> + add_task(async function() { + // Induce a process switching behavior for example.com + // with isolateHighValue isolation strategy + // (because we test specifically process switching behavior here) + await SpecialPowers.pushPermissions([ + { + type: "highValueCOOP", + allow: SpecialPowers.Ci.nsIPermissionManager.ALLOW_ACTION, + context: "https://example.com", + } + ]); + + let popup = window.open("blank.html"); + + info("opened popup"); + await new Promise(resolve => { + popup.addEventListener("load", resolve, { once: true }); + }); + + info("popup blank.html loaded"); + let tell_opener = new URL("file_tell_opener.html", location.href); + // eslint-disable-next-line @microsoft/sdl/no-insecure-url + let xorigin_url = new URL(tell_opener.pathname, "https://example.com"); + + let resolveStartedUnload; + let startedUnload = new Promise(resolve => { + resolveStartedUnload = resolve; + }); + let didFinishUnload = false; + + let finishUnload = false; + popup.addEventListener("unload", function() { + resolveStartedUnload(); + try { + // Spin a nested event loop in unload until we set `finishUnload`. + SpecialPowers.Services.tm.spinEventLoopUntil( + "Test(test_switch_back_nested.html)", () => finishUnload); + } finally { + info("exiting from unload nested event loop..."); + didFinishUnload = true; + } + }); + + info("wait for message from popup"); + let messagePromise = new Promise(resolve => { + addEventListener("message", evt => { + resolve(); + }, { once: true }); + }); + popup.location = xorigin_url.href; + await messagePromise; + + info("popup loaded, ensuring we're in unload"); + await startedUnload; + is(didFinishUnload, false, "unload shouldn't have finished"); + + let switchStarted = SpecialPowers.spawnChrome([], async () => { + await new Promise(resolve => { + async function observer(subject, topic) { + is(topic, "http-on-examine-response"); + + let uri = subject.QueryInterface(Ci.nsIChannel).URI; + if (!uri.filePath.endsWith("file_tell_opener.html")) { + return; + } + + Services.obs.removeObserver(observer, "http-on-examine-response"); + + // spin the event loop a few times to ensure we resolve after the process switch + for (let i = 0; i < 10; ++i) { + await new Promise(res => Services.tm.dispatchToMainThread(res)); + } + + info("resolving!"); + resolve(); + } + Services.obs.addObserver(observer, "http-on-examine-response"); + }); + }); + + info("Navigating back to the current process"); + await SpecialPowers.spawn(popup, [tell_opener.href], (href) => { + content.location.href = href; + }); + + let messagePromise2 = new Promise(resolve => { + addEventListener("message", evt => { + resolve(); + }, { once: true }); + }); + + info("Waiting for the process switch to start"); + await switchStarted; + + // Finish unloading, and wait for the unload to complete + is(didFinishUnload, false, "unload shouldn't be finished"); + finishUnload = true; + await new Promise(resolve => setTimeout(resolve, 0)); + is(didFinishUnload, true, "unload should be finished"); + + info("waiting for navigation to complete"); + await messagePromise2; + + info("closing popup"); + popup.close(); + + ok(true, "Didn't crash"); + }); +</script> +</pre> +</body> +</html> |