diff options
Diffstat (limited to 'docshell/test/mochitest')
154 files changed, 6709 insertions, 0 deletions
diff --git a/docshell/test/mochitest/bug1422334_redirect.html b/docshell/test/mochitest/bug1422334_redirect.html new file mode 100644 index 0000000000..eec7fda2c7 --- /dev/null +++ b/docshell/test/mochitest/bug1422334_redirect.html @@ -0,0 +1,3 @@ +<html> + <body>You should never see this</body> +</html> diff --git a/docshell/test/mochitest/bug1422334_redirect.html^headers^ b/docshell/test/mochitest/bug1422334_redirect.html^headers^ new file mode 100644 index 0000000000..fbf2d1b745 --- /dev/null +++ b/docshell/test/mochitest/bug1422334_redirect.html^headers^ @@ -0,0 +1,2 @@ +HTTP 302 Moved Temporarily +Location: ../navigation/blank.html?x=y diff --git a/docshell/test/mochitest/bug404548-subframe.html b/docshell/test/mochitest/bug404548-subframe.html new file mode 100644 index 0000000000..9a248b40b3 --- /dev/null +++ b/docshell/test/mochitest/bug404548-subframe.html @@ -0,0 +1,7 @@ +<!DOCTYPE html> +<html> +<body onload="setTimeout(function() { window.location = 'bug404548-subframe_window.html'; }, 10)"> +<iframe srcdoc="<body onpagehide='var p = window.parent.opener; var e = window.frameElement; e.parentNode.removeChild(e); if (e.parentNode == null && e.contentWindow == null) { p.firstRemoved = true; }'>"> +</iframe> +<iframe srcdoc="<body onpagehide='window.parent.opener.secondHidden = true;'>"> +</iframe> diff --git a/docshell/test/mochitest/bug404548-subframe_window.html b/docshell/test/mochitest/bug404548-subframe_window.html new file mode 100644 index 0000000000..82ea73ea83 --- /dev/null +++ b/docshell/test/mochitest/bug404548-subframe_window.html @@ -0,0 +1 @@ +<body onload='window.opener.finishTest()'> diff --git a/docshell/test/mochitest/bug413310-post.sjs b/docshell/test/mochitest/bug413310-post.sjs new file mode 100644 index 0000000000..f87937ab56 --- /dev/null +++ b/docshell/test/mochitest/bug413310-post.sjs @@ -0,0 +1,10 @@ +function handleRequest(request, response) { + response.setHeader("Content-Type", "text/html"); + response.write( + "<body onload='window.parent.onloadCount++'>" + + request.method + + " " + + Date.now() + + "</body>" + ); +} diff --git a/docshell/test/mochitest/bug413310-subframe.html b/docshell/test/mochitest/bug413310-subframe.html new file mode 100644 index 0000000000..bcff1886fd --- /dev/null +++ b/docshell/test/mochitest/bug413310-subframe.html @@ -0,0 +1,7 @@ +<!DOCTYPE html> +<html> + <body onload="window.parent.onloadCount++"> + <form action="bug413310-post.sjs" method="POST"> + </form> + </body> +</html> diff --git a/docshell/test/mochitest/bug529119-window.html b/docshell/test/mochitest/bug529119-window.html new file mode 100644 index 0000000000..f1908835a7 --- /dev/null +++ b/docshell/test/mochitest/bug529119-window.html @@ -0,0 +1,7 @@ +<!DOCTYPE HTML> +<html> +<head> +<title>Test bug 529119, sub-window</title> +<body onload="window.opener.windowLoaded();"> +</body> +</html> diff --git a/docshell/test/mochitest/bug530396-noref.sjs b/docshell/test/mochitest/bug530396-noref.sjs new file mode 100644 index 0000000000..6a65882160 --- /dev/null +++ b/docshell/test/mochitest/bug530396-noref.sjs @@ -0,0 +1,22 @@ +function handleRequest(request, response) { + response.setHeader("Content-Type", "text/html"); + response.setHeader("Cache-Control", "no-cache"); + response.write("<body onload='"); + + if (!request.hasHeader("Referer")) { + response.write("window.parent.onloadCount++;"); + } + + if (request.queryString == "newwindow") { + response.write( + "if (window.opener) { window.opener.parent.onloadCount++; window.opener.parent.doNextStep(); }" + ); + response.write("if (!window.opener) window.close();"); + response.write("'>"); + } else { + response.write("window.parent.doNextStep();'>"); + } + + response.write(request.method + " " + Date.now()); + response.write("</body>"); +} diff --git a/docshell/test/mochitest/bug530396-subframe.html b/docshell/test/mochitest/bug530396-subframe.html new file mode 100644 index 0000000000..be81b9f144 --- /dev/null +++ b/docshell/test/mochitest/bug530396-subframe.html @@ -0,0 +1,7 @@ +<!DOCTYPE html> +<html> + <body onload="window.parent.onloadCount++"> + <a href="bug530396-noref.sjs" rel="noreferrer foo" id="target1">bug530396-noref.sjs</a> + <a href="bug530396-noref.sjs?newwindow" rel="nofollow noreferrer" id="target2" target="newwindow">bug530396-noref.sjs with new window</a> + </body> +</html> diff --git a/docshell/test/mochitest/bug570341_recordevents.html b/docshell/test/mochitest/bug570341_recordevents.html new file mode 100644 index 0000000000..45b04866ec --- /dev/null +++ b/docshell/test/mochitest/bug570341_recordevents.html @@ -0,0 +1,21 @@ +<html> +<head> +<script> + var start = Date.now(); + window._testing_js_start = Date.now(); + window["_testing_js_after_" + document.readyState] = start; + document.addEventListener("DOMContentLoaded", + function() { + window._testing_evt_DOMContentLoaded = Date.now(); + }, true); + document.addEventListener("readystatechange", function() { + window["_testing_evt_DOM_" + document.readyState] = Date.now(); + }, true); + function recordLoad() { + window._testing_evt_load = Date.now(); + } +</script> +</head> +<body onload="recordLoad()">This document collects time +for events related to the page load progress.</body> +</html> diff --git a/docshell/test/mochitest/bug668513_redirect.html b/docshell/test/mochitest/bug668513_redirect.html new file mode 100644 index 0000000000..1b8f66c631 --- /dev/null +++ b/docshell/test/mochitest/bug668513_redirect.html @@ -0,0 +1 @@ +<html><body>This document is redirected to a blank document.</body></html> diff --git a/docshell/test/mochitest/bug668513_redirect.html^headers^ b/docshell/test/mochitest/bug668513_redirect.html^headers^ new file mode 100644 index 0000000000..0e785833c6 --- /dev/null +++ b/docshell/test/mochitest/bug668513_redirect.html^headers^ @@ -0,0 +1,2 @@ +HTTP 302 Moved Temporarily +Location: navigation/blank.html diff --git a/docshell/test/mochitest/bug691547_frame.html b/docshell/test/mochitest/bug691547_frame.html new file mode 100644 index 0000000000..00172f7119 --- /dev/null +++ b/docshell/test/mochitest/bug691547_frame.html @@ -0,0 +1,12 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=691547 +--> +<head> + <title>Test for Bug 691547</title> +</head> +<body> +<iframe style="width:95%"></iframe> +</body> +</html> diff --git a/docshell/test/mochitest/clicker.html b/docshell/test/mochitest/clicker.html new file mode 100644 index 0000000000..b655e27ea5 --- /dev/null +++ b/docshell/test/mochitest/clicker.html @@ -0,0 +1,7 @@ +<!doctype html> +<script> + "use strict"; + let target = window.opener ? window.opener : window.parent; + + onmessage = ({data}) => target.postMessage({}, "*"); +</script> diff --git a/docshell/test/mochitest/double_submit.sjs b/docshell/test/mochitest/double_submit.sjs new file mode 100644 index 0000000000..4ca088173c --- /dev/null +++ b/docshell/test/mochitest/double_submit.sjs @@ -0,0 +1,78 @@ +"use strict"; + +let self = this; + +let { setTimeout } = ChromeUtils.importESModule( + "resource://gre/modules/Timer.sys.mjs" +); + +const CC = Components.Constructor; +const BinaryInputStream = CC( + "@mozilla.org/binaryinputstream;1", + "nsIBinaryInputStream", + "setInputStream" +); + +function log(str) { + // dump(`LOG: ${str}\n`); +} + +function readStream(inputStream) { + let available = 0; + let result = []; + while ((available = inputStream.available()) > 0) { + result.push(inputStream.readBytes(available)); + } + + return result.join(""); +} + +function now() { + return Date.now(); +} + +async function handleRequest(request, response) { + log("Get query parameters"); + let params = new URLSearchParams(request.queryString); + + let start = now(); + let delay = parseInt(params.get("delay")) || 0; + log(`Delay for ${delay}`); + + let message = "good"; + if (request.method !== "POST") { + message = "bad"; + } else { + log("Read POST body"); + let body = new URLSearchParams( + readStream(new BinaryInputStream(request.bodyInputStream)) + ); + message = body.get("token") || "bad"; + log(`The result was ${message}`); + } + + let body = `<!doctype html> + <script> + "use strict"; + let target = (opener || parent); + target.postMessage(${JSON.stringify(message)}, '*'); + </script>`; + + // Sieze power from the response to allow manually transmitting data at any + // rate we want, so we can delay transmitting headers. + response.seizePower(); + + log(`Writing HTTP status line at ${now() - start}`); + response.write("HTTP/1.1 200 OK\r\n"); + + await new Promise(resolve => setTimeout(() => resolve(), delay)); + + log(`Delay completed at ${now() - start}`); + response.write("Content-Type: text/html\r\n"); + response.write(`Content-Length: ${body.length}\r\n`); + response.write("\r\n"); + response.write(body); + response.finish(); + + log("Finished"); +} diff --git a/docshell/test/mochitest/dummy_page.html b/docshell/test/mochitest/dummy_page.html new file mode 100644 index 0000000000..59bf2a5f8f --- /dev/null +++ b/docshell/test/mochitest/dummy_page.html @@ -0,0 +1,6 @@ +<html> +<head> <meta charset="utf-8"> </head> + <body> + just a dummy html file + </body> +</html> diff --git a/docshell/test/mochitest/file_anchor_scroll_after_document_open.html b/docshell/test/mochitest/file_anchor_scroll_after_document_open.html new file mode 100644 index 0000000000..7903380eac --- /dev/null +++ b/docshell/test/mochitest/file_anchor_scroll_after_document_open.html @@ -0,0 +1,15 @@ +<!DOCTYPE html> +<script> + if (location.hash == "#target") { + parent.postMessage("haveHash", "*"); + } else { + document.addEventListener("DOMContentLoaded", function() { + document.open(); + document.write("<!DOCTYPE html><html style='height: 100%'><body style='height: 100%'><div style='height: 200%'></div><div id='target'></div></body></html>"); + document.close(); + // Notify parent via postMessage, since otherwise exceptions will not get + // caught by its onerror handler. + parent.postMessage("doTest", "*"); + }); + } +</script> diff --git a/docshell/test/mochitest/file_bfcache_plus_hash_1.html b/docshell/test/mochitest/file_bfcache_plus_hash_1.html new file mode 100644 index 0000000000..199f6003e0 --- /dev/null +++ b/docshell/test/mochitest/file_bfcache_plus_hash_1.html @@ -0,0 +1,24 @@ +<html><body> + Popup 1 + <script type="application/javascript"> + var bc = new BroadcastChannel("bug646641_1"); + window.onload = () => { + bc.postMessage({ message: "childLoad", num: 1 }) + } + + window.onpageshow = () => { + bc.postMessage({ message: "childPageshow", num: 1 }) + } + bc.onmessage = (msgEvent) => { + var msg = msgEvent.data; + if (msg == "pushState") { + history.pushState("", "", ""); + location = "file_bfcache_plus_hash_2.html"; + } else if (msg == "close") { + bc.postMessage({ message: "closed" }); + bc.close(); + window.close(); + } + } + </script> +</body></html> diff --git a/docshell/test/mochitest/file_bfcache_plus_hash_2.html b/docshell/test/mochitest/file_bfcache_plus_hash_2.html new file mode 100644 index 0000000000..c27d4eaa3b --- /dev/null +++ b/docshell/test/mochitest/file_bfcache_plus_hash_2.html @@ -0,0 +1,17 @@ +<html><body> + Popup 2 + <script type="application/javascript"> + var bc = new BroadcastChannel("bug646641_2"); + window.onload = () => { + bc.postMessage({ message: "childLoad", num: 2 }) + requestAnimationFrame(() => bc.postMessage({message: "childPageshow", num: 2})); + } + bc.onmessage = (msgEvent) => { + var msg = msgEvent.data; + if (msg == "go-2") { + history.go(-2); + bc.close(); + } + } + </script> +</body></html> diff --git a/docshell/test/mochitest/file_bug1121701_1.html b/docshell/test/mochitest/file_bug1121701_1.html new file mode 100644 index 0000000000..3701bf2cad --- /dev/null +++ b/docshell/test/mochitest/file_bug1121701_1.html @@ -0,0 +1,27 @@ +<script> + var bc = new BroadcastChannel("file_bug1121701_1"); + var pageHideAsserts = undefined; + bc.onmessage = (msgEvent) => { + var msg = msgEvent.data; + var command = msg.command; + if (command == "setInnerHTML") { + document.body.innerHTML = "modified"; + window.onpagehide = function(event) { + window.onpagehide = null; + pageHideAsserts = {}; + pageHideAsserts.persisted = event.persisted; + pageHideAsserts.innerHTML = window.document.body.innerHTML; + }; + window.location.href = msg.testUrl2; + } else if (command == "close") { + bc.postMessage({command: "closed"}); + bc.close(); + window.close(); + } + } + window.onpageshow = function(e) { + var msg = {command: "child1PageShow", persisted: e.persisted, pageHideAsserts}; + msg.innerHTML = window.document.body.innerHTML; + bc.postMessage(msg); + }; +</script> diff --git a/docshell/test/mochitest/file_bug1121701_2.html b/docshell/test/mochitest/file_bug1121701_2.html new file mode 100644 index 0000000000..6cec88cd5d --- /dev/null +++ b/docshell/test/mochitest/file_bug1121701_2.html @@ -0,0 +1,23 @@ +<script> + var bc = new BroadcastChannel("file_bug1121701_2"); + bc.onmessage = (msgEvent) => { + var msg = msgEvent.data; + var command = msg.command; + if (command == "setInnerHTML") { + window.document.body.innerHTML = "<img>"; + window.onmessage = function() { + bc.postMessage({command: "onmessage"}); + window.document.body.firstChild.src = msg.location; + bc.close(); + }; + window.onbeforeunload = function() { + window.postMessage("foo", "*"); + }; + + history.back(); + } + } + window.onpageshow = function(e) { + bc.postMessage({command: "child2PageShow", persisted: e.persisted}); + }; +</script> diff --git a/docshell/test/mochitest/file_bug1151421.html b/docshell/test/mochitest/file_bug1151421.html new file mode 100644 index 0000000000..7bb8c8f363 --- /dev/null +++ b/docshell/test/mochitest/file_bug1151421.html @@ -0,0 +1,19 @@ +<html> +<head> +<style> +body, html { + height: 100%; +} +.spacer { + height: 80%; +} +</style> +</head> +<body onload='(parent || opener).childLoad()'> + +<div class="spacer"></div> +<div id="content">content</div> +<div class="spacer"></div> + +</body> +</html> diff --git a/docshell/test/mochitest/file_bug1186774.html b/docshell/test/mochitest/file_bug1186774.html new file mode 100644 index 0000000000..9af95b09bd --- /dev/null +++ b/docshell/test/mochitest/file_bug1186774.html @@ -0,0 +1 @@ +<div style='height: 9000px;'></div> diff --git a/docshell/test/mochitest/file_bug1450164.html b/docshell/test/mochitest/file_bug1450164.html new file mode 100644 index 0000000000..55e32ce93d --- /dev/null +++ b/docshell/test/mochitest/file_bug1450164.html @@ -0,0 +1,16 @@ +<html> + <head> + <script> + function go() { + var a = window.history.state; + window.history.replaceState(a, "", "1"); + var ok = opener.ok; + var SimpleTest = opener.SimpleTest; + ok("Addition of history in unload did not crash browser"); + SimpleTest.finish(); + } + </script> + </head> + <body onunload="go()"> + </body> +</html> diff --git a/docshell/test/mochitest/file_bug1729662.html b/docshell/test/mochitest/file_bug1729662.html new file mode 100644 index 0000000000..f5710e1c49 --- /dev/null +++ b/docshell/test/mochitest/file_bug1729662.html @@ -0,0 +1,8 @@ +<script> +addEventListener("load", () => { + (new BroadcastChannel("bug1729662")).postMessage("load"); + history.pushState(1, null, location.href); + history.back(); + history.forward(); +}); +</script> diff --git a/docshell/test/mochitest/file_bug1740516_1.html b/docshell/test/mochitest/file_bug1740516_1.html new file mode 100644 index 0000000000..ac8ca71d93 --- /dev/null +++ b/docshell/test/mochitest/file_bug1740516_1.html @@ -0,0 +1,29 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <script> + window.addEventListener("pageshow", ({ persisted }) => { + let bc = new BroadcastChannel("bug1740516_1"); + bc.addEventListener("message", ({ data }) => { + bc.close(); + switch (data) { + case "block_bfcache_and_navigate": + window.blockBFCache = new RTCPeerConnection(); + // Fall through + case "navigate": + document.location = "file_bug1740516_2.html"; + break; + case "close": + window.close(); + break; + } + }); + bc.postMessage(persisted); + }); + </script> +</head> +<body> + <iframe src="file_bug1740516_1_inner.html"></iframe> +</body> +</html> diff --git a/docshell/test/mochitest/file_bug1740516_1_inner.html b/docshell/test/mochitest/file_bug1740516_1_inner.html new file mode 100644 index 0000000000..159c6bde5a --- /dev/null +++ b/docshell/test/mochitest/file_bug1740516_1_inner.html @@ -0,0 +1,15 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <script> + window.addEventListener("pageshow", ({ persisted }) => { + let bc = new BroadcastChannel("bug1740516_1_inner"); + bc.postMessage(persisted); + bc.close(); + }); + </script> +</head> +<body> +</body> +</html> diff --git a/docshell/test/mochitest/file_bug1740516_2.html b/docshell/test/mochitest/file_bug1740516_2.html new file mode 100644 index 0000000000..2dc714feef --- /dev/null +++ b/docshell/test/mochitest/file_bug1740516_2.html @@ -0,0 +1,11 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <script> + addEventListener("pageshow", () => { history.back(); }); + </script> +</head> +<body> +</body> +</html> diff --git a/docshell/test/mochitest/file_bug1741132.html b/docshell/test/mochitest/file_bug1741132.html new file mode 100644 index 0000000000..d863b9f015 --- /dev/null +++ b/docshell/test/mochitest/file_bug1741132.html @@ -0,0 +1,29 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <script> + window.addEventListener("pageshow", ({ persisted }) => { + let bc = new BroadcastChannel("bug1741132"); + bc.addEventListener("message", ({ data: { cmd, arg } }) => { + bc.close(); + switch (cmd) { + case "load": + document.location = arg; + break; + case "go": + window.blockBFCache = new RTCPeerConnection(); + history.go(arg); + break; + case "close": + window.close(); + break; + } + }); + bc.postMessage(persisted); + }); + </script> +</head> +<body> +</body> +</html> diff --git a/docshell/test/mochitest/file_bug1742865.sjs b/docshell/test/mochitest/file_bug1742865.sjs new file mode 100644 index 0000000000..d97526f281 --- /dev/null +++ b/docshell/test/mochitest/file_bug1742865.sjs @@ -0,0 +1,75 @@ +function handleRequest(request, response) { + if (request.queryString == "reset") { + setState("index", "0"); + response.setStatusLine(request.httpVersion, 200, "Ok"); + response.write("Reset"); + return; + } + + let refresh = ""; + let index = Number(getState("index")); + // index == 0 First load, returns first meta refresh + // index == 1 Second load, caused by first meta refresh, returns second meta refresh + // index == 2 Third load, caused by second meta refresh, doesn't return a meta refresh + let query = new URLSearchParams(request.queryString); + if (index < 2) { + refresh = query.get("seconds"); + if (query.get("crossOrigin") == "true") { + const hosts = ["example.org", "example.com"]; + + let url = `${request.scheme}://${hosts[index]}${request.path}?${request.queryString}`; + refresh += `; url=${url}`; + } + refresh = `<meta http-equiv="Refresh" content="${refresh}">`; + } + // We want to scroll for the first load, and check that the meta refreshes keep the same + // scroll position. + let scroll = index == 0 ? `scrollTo(0, ${query.get("scrollTo")});` : ""; + + setState("index", String(index + 1)); + + response.write( + `<!DOCTYPE html> +<html> +<head> + <meta charset="utf-8"> + <meta http-equiv="Cache-Control" content="no-cache"> + ${refresh} + <script> + window.addEventListener("pageshow", () => { + ${scroll} + window.top.opener.postMessage({ + commandType: "pageShow", + commandData: { + inputValue: document.getElementById("input").value, + scrollPosition: window.scrollY, + }, + }, "*"); + }); + window.addEventListener("message", ({ data }) => { + if (data == "changeInputValue") { + document.getElementById("input").value = "1234"; + window.top.opener.postMessage({ + commandType: "onChangedInputValue", + commandData: { + historyLength: history.length, + inputValue: document.getElementById("input").value, + }, + }, "*"); + } else if (data == "loadNext") { + location.href += "&loadnext=1"; + } else if (data == "back") { + history.back(); + } + }); + </script> +</head> +<body> +<input type="text" id="input" value="initial"></input> +<div style='height: 9000px;'></div> +<p> +</p> +</body> +</html>` + ); +} diff --git a/docshell/test/mochitest/file_bug1742865_outer.sjs b/docshell/test/mochitest/file_bug1742865_outer.sjs new file mode 100644 index 0000000000..f5e689a526 --- /dev/null +++ b/docshell/test/mochitest/file_bug1742865_outer.sjs @@ -0,0 +1,23 @@ +function handleRequest(request, response) { + response.write( + `<!DOCTYPE html> +<html> +<head> + <meta charset="utf-8"> + <script> + window.addEventListener("message", ({ data }) => { + if (data == "loadNext") { + location.href += "&loadnext=1"; + return; + } + // Forward other messages to the frame. + document.getElementById("frame").contentWindow.postMessage(data, "*"); + }); + </script> +</head> +<body> + <iframe src="file_bug1742865.sjs?${request.queryString}" id="frame"></iframe> +</body> +</html>` + ); +} diff --git a/docshell/test/mochitest/file_bug1743353.html b/docshell/test/mochitest/file_bug1743353.html new file mode 100644 index 0000000000..c08f8d143f --- /dev/null +++ b/docshell/test/mochitest/file_bug1743353.html @@ -0,0 +1,37 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <script> + window.addEventListener("pageshow", () => { + let bc = new BroadcastChannel("bug1743353"); + bc.addEventListener("message", ({ data: cmd }) => { + switch (cmd) { + case "load": + bc.close(); + document.location += "?1"; + break; + case "back": + window.blockBFCache = new RTCPeerConnection(); + window.addEventListener("pagehide", () => { + bc.postMessage("pagehide"); + }); + window.addEventListener("unload", () => { + bc.postMessage("unload"); + bc.close(); + }); + history.back(); + break; + case "close": + bc.close(); + window.close(); + break; + } + }); + bc.postMessage("pageshow"); + }); + </script> +</head> +<body> +</body> +</html> diff --git a/docshell/test/mochitest/file_bug1747033.sjs b/docshell/test/mochitest/file_bug1747033.sjs new file mode 100644 index 0000000000..14401101b2 --- /dev/null +++ b/docshell/test/mochitest/file_bug1747033.sjs @@ -0,0 +1,110 @@ +"use strict"; + +const BOUNDARY = "BOUNDARY"; + +// waitForPageShow should be false if this is for multipart/x-mixed-replace +// and it's not the last part, Gecko doesn't fire pageshow for those parts. +function documentString(waitForPageShow = true) { + return `<html> + <head> + <script> + let bc = new BroadcastChannel("bug1747033"); + bc.addEventListener("message", ({ data: { cmd, arg = undefined } }) => { + switch (cmd) { + case "load": + location.href = arg; + break; + case "replaceState": + history.replaceState({}, "Replaced state", arg); + bc.postMessage({ "historyLength": history.length, "location": location.href }); + break; + case "back": + history.back(); + break; + case "close": + close(); + break; + } + }); + + function reply() { + bc.postMessage({ "historyLength": history.length, "location": location.href }); + } + + ${waitForPageShow ? `addEventListener("pageshow", reply);` : "reply();"} + </script> + </head> + <body></body> +</html> +`; +} + +function boundary(last = false) { + let b = `--${BOUNDARY}`; + if (last) { + b += "--"; + } + return b + "\n"; +} + +function sendMultipart(response, last = false) { + setState("sendMore", ""); + + response.write(`Content-Type: text/html + +${documentString(last)} +`); + response.write(boundary(last)); +} + +function shouldSendMore() { + return new Promise(resolve => { + let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); + timer.initWithCallback( + () => { + let sendMore = getState("sendMore"); + if (sendMore !== "") { + timer.cancel(); + resolve(sendMore); + } + }, + 100, + Ci.nsITimer.TYPE_REPEATING_SLACK + ); + }); +} + +async function handleRequest(request, response) { + if (request.queryString == "") { + // This is for non-multipart/x-mixed-replace loads. + response.write(documentString()); + return; + } + + if (request.queryString == "sendNextPart") { + setState("sendMore", "next"); + return; + } + + if (request.queryString == "sendLastPart") { + setState("sendMore", "last"); + return; + } + + response.processAsync(); + + response.setHeader( + "Content-Type", + `multipart/x-mixed-replace; boundary=${BOUNDARY}`, + false + ); + response.setStatusLine(request.httpVersion, 200, "OK"); + + response.write(boundary()); + sendMultipart(response); + while ((await shouldSendMore("sendMore")) !== "last") { + sendMultipart(response); + } + sendMultipart(response, true); + response.finish(); +} diff --git a/docshell/test/mochitest/file_bug1773192_1.html b/docshell/test/mochitest/file_bug1773192_1.html new file mode 100644 index 0000000000..42d5b3fced --- /dev/null +++ b/docshell/test/mochitest/file_bug1773192_1.html @@ -0,0 +1,13 @@ +<script> + let bc = new BroadcastChannel("bug1743353"); + bc.addEventListener("message", ({ data }) => { + if (data == "next") { + location = "file_bug1773192_2.html"; + } else if (data == "close") { + window.close(); + } + }); + window.addEventListener("pageshow", () => { + bc.postMessage({ location: location.href, referrer: document.referrer }); + }); +</script> diff --git a/docshell/test/mochitest/file_bug1773192_2.html b/docshell/test/mochitest/file_bug1773192_2.html new file mode 100644 index 0000000000..c310ec66f5 --- /dev/null +++ b/docshell/test/mochitest/file_bug1773192_2.html @@ -0,0 +1,19 @@ +<html> + <head> + <meta http-equiv="Cache-Control" content="no-cache, no-store"> + <meta name="referrer" content="same-origin"> + </head> + <body> + <form method="POST" action="file_bug1773192_3.sjs"></form> + <script> + history.replaceState({}, "", document.referrer); + setTimeout(() => { + // The test relies on this page not going into the BFCache, so that + // when we come back to it we load the URL from the replaceState + // instead. + window.blockBFCache = new RTCPeerConnection(); + document.forms[0].submit(); + }, 0); + </script> + </body> +</html> diff --git a/docshell/test/mochitest/file_bug1773192_3.sjs b/docshell/test/mochitest/file_bug1773192_3.sjs new file mode 100644 index 0000000000..ce889c7035 --- /dev/null +++ b/docshell/test/mochitest/file_bug1773192_3.sjs @@ -0,0 +1,3 @@ +function handleRequest(request, response) { + response.write("<script>history.back();</script>"); +} diff --git a/docshell/test/mochitest/file_bug1850335_1.html b/docshell/test/mochitest/file_bug1850335_1.html new file mode 100644 index 0000000000..f317d2197a --- /dev/null +++ b/docshell/test/mochitest/file_bug1850335_1.html @@ -0,0 +1,23 @@ +<script> +addEventListener("load", ({ persisted }) => { + document.getElementById("input1").value = ""; +}); +addEventListener("pageshow", ({ persisted }) => { + let bc = new BroadcastChannel("bug1850335"); + + bc.addEventListener("message", ({ data: { cmd, arg } }) => { + if (cmd == "setValue") { + document.getElementById("input1").value = arg; + bc.postMessage({ value: document.getElementById("input1").value }); + } else if (cmd == "load") { + bc.close(); + location = arg; + } else if (cmd == "close") { + close(); + } + }); + + bc.postMessage({ persisted, value: document.getElementById("input1").value }); +}); +</script> +<input type="text" id="input1"></input> diff --git a/docshell/test/mochitest/file_bug1850335_2.html b/docshell/test/mochitest/file_bug1850335_2.html new file mode 100644 index 0000000000..e2c55a6a04 --- /dev/null +++ b/docshell/test/mochitest/file_bug1850335_2.html @@ -0,0 +1,18 @@ +<script> +addEventListener("pageshow", ({ persisted }) => { + window.blockBFCache = new RTCPeerConnection(); + + let bc = new BroadcastChannel("bug1850335"); + + bc.addEventListener("message", ({ data: { cmd, arg } }) => { + bc.close(); + if (cmd == "load") { + location = arg; + } else if (cmd == "back") { + history.back(); + } + }, { once: true }); + + bc.postMessage({ persisted }); +}); +</script> diff --git a/docshell/test/mochitest/file_bug1850335_3.html b/docshell/test/mochitest/file_bug1850335_3.html new file mode 100644 index 0000000000..bd9ef0af7e --- /dev/null +++ b/docshell/test/mochitest/file_bug1850335_3.html @@ -0,0 +1,7 @@ +<script> +addEventListener("pageshow", () => { + setTimeout(() => { + history.back(); + }, 0); +}); +</script> diff --git a/docshell/test/mochitest/file_bug385434_1.html b/docshell/test/mochitest/file_bug385434_1.html new file mode 100644 index 0000000000..5c951f1fa6 --- /dev/null +++ b/docshell/test/mochitest/file_bug385434_1.html @@ -0,0 +1,29 @@ +<!-- +Inner frame for test of bug 385434. +https://bugzilla.mozilla.org/show_bug.cgi?id=385434 +--> +<html> +<head> + <script type="application/javascript"> + function hashchange() { + parent.onIframeHashchange(); + } + + function load() { + parent.onIframeLoad(); + } + + function scroll() { + parent.onIframeScroll(); + } + </script> +</head> + +<body onscroll="scroll()" onload="load()" onhashchange="hashchange()"> +<a href="#link1" id="link1">link1</a> +<!-- Our parent loads us in an iframe with height 100px, so this spacer ensures + that switching between #link1 and #link2 causes us to scroll --> +<div style="height:200px;"></div> +<a href="#link2" id="link2">link2</a> +</body> +</html> diff --git a/docshell/test/mochitest/file_bug385434_2.html b/docshell/test/mochitest/file_bug385434_2.html new file mode 100644 index 0000000000..4aa5ef82b8 --- /dev/null +++ b/docshell/test/mochitest/file_bug385434_2.html @@ -0,0 +1,26 @@ +<!-- +Inner frame for test of bug 385434. +https://bugzilla.mozilla.org/show_bug.cgi?id=385434 +--> +<html> +<head> + <script type="application/javascript"> + function hashchange(e) { + // pass the event back to the parent so it can check its properties. + parent.gSampleEvent = e; + + parent.statusMsg("Hashchange in 2."); + parent.onIframeHashchange(); + } + + function load() { + parent.statusMsg("Loading 2."); + parent.onIframeLoad(); + } + </script> +</head> + +<frameset onload="load()" onhashchange="hashchange(event)"> + <frame src="about:blank" /> +</frameset> +</html> diff --git a/docshell/test/mochitest/file_bug385434_3.html b/docshell/test/mochitest/file_bug385434_3.html new file mode 100644 index 0000000000..34dd68ef45 --- /dev/null +++ b/docshell/test/mochitest/file_bug385434_3.html @@ -0,0 +1,22 @@ +<!-- +Inner frame for test of bug 385434. +https://bugzilla.mozilla.org/show_bug.cgi?id=385434 +--> +<html> +<head> + <script type="application/javascript"> + // Notify our parent if we have a hashchange and once we're done loading. + window.addEventListener("hashchange", parent.onIframeHashchange); + + window.addEventListener("DOMContentLoaded", function() { + // This also should trigger a hashchange, becuase the readystate is + // "interactive", not "complete" during DOMContentLoaded. + window.location.hash = "2"; + }); + + </script> +</head> + +<body> +</body> +</html> diff --git a/docshell/test/mochitest/file_bug475636.sjs b/docshell/test/mochitest/file_bug475636.sjs new file mode 100644 index 0000000000..cba9a968d6 --- /dev/null +++ b/docshell/test/mochitest/file_bug475636.sjs @@ -0,0 +1,97 @@ +let jsURL = + "javascript:" + + escape( + 'window.parent.postMessage("JS uri ran", "*");\ +return \'\ +<script>\ +window.parent.postMessage("Able to access private: " +\ + window.parent.private, "*");\ +</script>\'' + ); +let dataURL = + "data:text/html," + + escape( + '<!DOCTYPE HTML>\ +<script>\ +try {\ + window.parent.postMessage("Able to access private: " +\ + window.parent.private, "*");\ +}\ +catch (e) {\ + window.parent.postMessage("pass", "*");\ +}\ +</script>' + ); + +let tests = [ + // Plain document should work as normal + '<!DOCTYPE HTML>\ +<script>\ +try {\ + window.parent.private;\ + window.parent.postMessage("pass", "*");\ +}\ +catch (e) {\ + window.parent.postMessage("Unble to access private", "*");\ +}\ +</script>', + + // refresh to plain doc + { refresh: "file_bug475636.sjs?1", doc: "<!DOCTYPE HTML>" }, + + // meta-refresh to plain doc + '<!DOCTYPE HTML>\ +<head>\ + <meta http-equiv="refresh" content="0; url=file_bug475636.sjs?1">\ +</head>', + + // refresh to data url + { refresh: dataURL, doc: "<!DOCTYPE HTML>" }, + + // meta-refresh to data url + '<!DOCTYPE HTML>\ +<head>\ + <meta http-equiv="refresh" content="0; url=' + + dataURL + + '">\ +</head>', + + // refresh to js url should not be followed + { + refresh: jsURL, + doc: '<!DOCTYPE HTML>\ +<script>\ +setTimeout(function() {\ + window.parent.postMessage("pass", "*");\ +}, 2000);\ +</script>', + }, + + // meta refresh to js url should not be followed + '<!DOCTYPE HTML>\ +<head>\ + <meta http-equiv="refresh" content="0; url=' + + jsURL + + '">\ +</head>\ +<script>\ +setTimeout(function() {\ + window.parent.postMessage("pass", "*");\ +}, 2000);\ +</script>', +]; + +function handleRequest(request, response) { + dump("@@@@@@@@@hi there: " + request.queryString + "\n"); + let test = tests[parseInt(request.queryString, 10) - 1]; + response.setHeader("Content-Type", "text/html"); + + if (!test) { + response.write('<script>parent.postMessage("done", "*");</script>'); + } else if (typeof test == "string") { + response.write(test); + } else if (test.refresh) { + response.setHeader("Refresh", "0; url=" + test.refresh); + response.write(test.doc); + } +} diff --git a/docshell/test/mochitest/file_bug509055.html b/docshell/test/mochitest/file_bug509055.html new file mode 100644 index 0000000000..ac30876bbf --- /dev/null +++ b/docshell/test/mochitest/file_bug509055.html @@ -0,0 +1,9 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test inner frame for bug 509055</title> +</head> +<body onhashchange="hashchangeCallback()"> + file_bug509055.html +</body> +</html> diff --git a/docshell/test/mochitest/file_bug511449.html b/docshell/test/mochitest/file_bug511449.html new file mode 100644 index 0000000000..637732dbbf --- /dev/null +++ b/docshell/test/mochitest/file_bug511449.html @@ -0,0 +1,6 @@ +<!DOCTYPE HTML> +<title>Used in test for bug 511449</title> +<input type="text" id="input"> +<script type="text/javascript"> + document.getElementById("input").focus(); +</script> diff --git a/docshell/test/mochitest/file_bug540462.html b/docshell/test/mochitest/file_bug540462.html new file mode 100644 index 0000000000..ab8c07eba5 --- /dev/null +++ b/docshell/test/mochitest/file_bug540462.html @@ -0,0 +1,25 @@ +<html> + <head> + <script> + // <!-- + function test() { + document.open(); + document.write( + `<html> + <body onload='opener.documentWriteLoad(); rel();'> + <a href='foo.html'>foo</a> + <script> + function rel() { setTimeout('location.reload()', 0); } + <\/script> + </body> + </html>` + ); + document.close(); + } + // --> + </script> + </head> + <body onload="setTimeout('test()', 0)"> + Test for bug 540462 + </body> +</html> diff --git a/docshell/test/mochitest/file_bug580069_1.html b/docshell/test/mochitest/file_bug580069_1.html new file mode 100644 index 0000000000..7ab4610334 --- /dev/null +++ b/docshell/test/mochitest/file_bug580069_1.html @@ -0,0 +1,8 @@ +<html> +<body onload='parent.page1Load();'> +file_bug580069_1.html + +<form id='form' action='file_bug580069_2.sjs' method='POST'></form> + +</body> +</html> diff --git a/docshell/test/mochitest/file_bug580069_2.sjs b/docshell/test/mochitest/file_bug580069_2.sjs new file mode 100644 index 0000000000..ff03c74e68 --- /dev/null +++ b/docshell/test/mochitest/file_bug580069_2.sjs @@ -0,0 +1,8 @@ +function handleRequest(request, response) { + response.setHeader("Content-Type", "text/html", false); + response.write( + "<html><body onload='parent.page2Load(\"" + + request.method + + "\")'>file_bug580069_2.sjs</body></html>" + ); +} diff --git a/docshell/test/mochitest/file_bug590573_1.html b/docshell/test/mochitest/file_bug590573_1.html new file mode 100644 index 0000000000..b859ca7469 --- /dev/null +++ b/docshell/test/mochitest/file_bug590573_1.html @@ -0,0 +1,7 @@ +<html> +<body onload='opener.page1Load();' onpageshow='opener.page1PageShow();'> + +<div style='height:10000px' id='div1'>This is a very tall div.</div> + +</body> +</html> diff --git a/docshell/test/mochitest/file_bug590573_2.html b/docshell/test/mochitest/file_bug590573_2.html new file mode 100644 index 0000000000..5f9ca22be4 --- /dev/null +++ b/docshell/test/mochitest/file_bug590573_2.html @@ -0,0 +1,8 @@ +<html> +<body onpopstate='opener.page2Popstate();' onload='opener.page2Load();' + onpageshow='opener.page2PageShow();'> + +<div style='height:300%' id='div2'>The second page also has a big div.</div> + +</body> +</html> diff --git a/docshell/test/mochitest/file_bug598895_1.html b/docshell/test/mochitest/file_bug598895_1.html new file mode 100644 index 0000000000..d21f2b4a5d --- /dev/null +++ b/docshell/test/mochitest/file_bug598895_1.html @@ -0,0 +1 @@ +<script>window.onload = function() { opener.postMessage("loaded", "*"); };</script><body>Should show</body> diff --git a/docshell/test/mochitest/file_bug598895_2.html b/docshell/test/mochitest/file_bug598895_2.html new file mode 100644 index 0000000000..680c9bf22b --- /dev/null +++ b/docshell/test/mochitest/file_bug598895_2.html @@ -0,0 +1 @@ +<script>window.onload = function() { opener.postMessage("loaded", "*"); };</script><body></body> diff --git a/docshell/test/mochitest/file_bug634834.html b/docshell/test/mochitest/file_bug634834.html new file mode 100644 index 0000000000..3ff0897451 --- /dev/null +++ b/docshell/test/mochitest/file_bug634834.html @@ -0,0 +1,5 @@ +<html> +<body> +Nothing to see here; just an empty page. +</body> +</html> diff --git a/docshell/test/mochitest/file_bug637644_1.html b/docshell/test/mochitest/file_bug637644_1.html new file mode 100644 index 0000000000..d21f2b4a5d --- /dev/null +++ b/docshell/test/mochitest/file_bug637644_1.html @@ -0,0 +1 @@ +<script>window.onload = function() { opener.postMessage("loaded", "*"); };</script><body>Should show</body> diff --git a/docshell/test/mochitest/file_bug637644_2.html b/docshell/test/mochitest/file_bug637644_2.html new file mode 100644 index 0000000000..680c9bf22b --- /dev/null +++ b/docshell/test/mochitest/file_bug637644_2.html @@ -0,0 +1 @@ +<script>window.onload = function() { opener.postMessage("loaded", "*"); };</script><body></body> diff --git a/docshell/test/mochitest/file_bug640387.html b/docshell/test/mochitest/file_bug640387.html new file mode 100644 index 0000000000..3a939fb41e --- /dev/null +++ b/docshell/test/mochitest/file_bug640387.html @@ -0,0 +1,26 @@ +<html> +<body onhashchange='hashchange()' onload='load()' onpopstate='popstate()'> + +<script> +function hashchange() { + var f = (opener || parent).childHashchange; + if (f) + f(); +} + +function load() { + var f = (opener || parent).childLoad; + if (f) + f(); +} + +function popstate() { + var f = (opener || parent).childPopstate; + if (f) + f(); +} +</script> + +Not much to see here... +</body> +</html> diff --git a/docshell/test/mochitest/file_bug653741.html b/docshell/test/mochitest/file_bug653741.html new file mode 100644 index 0000000000..3202b52573 --- /dev/null +++ b/docshell/test/mochitest/file_bug653741.html @@ -0,0 +1,13 @@ +<html> +<body onload='(parent || opener).childLoad()'> + +<div style='height:500px; background:yellow'> +<a id='#top'>Top of the page</a> +</div> + +<div id='bottom'> +<a id='#bottom'>Bottom of the page</a> +</div> + +</body> +</html> diff --git a/docshell/test/mochitest/file_bug660404 b/docshell/test/mochitest/file_bug660404 new file mode 100644 index 0000000000..ed773420ef --- /dev/null +++ b/docshell/test/mochitest/file_bug660404 @@ -0,0 +1,13 @@ +--testingtesting +Content-Type: text/html + +<script> + var bc = new BroadcastChannel("bug660404_multipart"); + bc.postMessage({command: "finishTest", + textContent: window.document.documentElement.textContent, + innerHTML: window.document.documentElement.innerHTML + }); + bc.close(); + window.close(); +</script> +--testingtesting-- diff --git a/docshell/test/mochitest/file_bug660404-1.html b/docshell/test/mochitest/file_bug660404-1.html new file mode 100644 index 0000000000..878bd80426 --- /dev/null +++ b/docshell/test/mochitest/file_bug660404-1.html @@ -0,0 +1,12 @@ +<script> + var bc = new BroadcastChannel("bug660404"); + window.onload = function() { + setTimeout(() => { + window.onpagehide = function(ev) { + bc.postMessage({command: "pagehide", persisted: ev.persisted}); + bc.close(); + }; + window.location.href = "file_bug660404"; + }, 0); + }; +</script> diff --git a/docshell/test/mochitest/file_bug660404^headers^ b/docshell/test/mochitest/file_bug660404^headers^ new file mode 100644 index 0000000000..5c821f3f48 --- /dev/null +++ b/docshell/test/mochitest/file_bug660404^headers^ @@ -0,0 +1 @@ +Content-Type: multipart/x-mixed-replace; boundary="testingtesting" diff --git a/docshell/test/mochitest/file_bug662170.html b/docshell/test/mochitest/file_bug662170.html new file mode 100644 index 0000000000..3202b52573 --- /dev/null +++ b/docshell/test/mochitest/file_bug662170.html @@ -0,0 +1,13 @@ +<html> +<body onload='(parent || opener).childLoad()'> + +<div style='height:500px; background:yellow'> +<a id='#top'>Top of the page</a> +</div> + +<div id='bottom'> +<a id='#bottom'>Bottom of the page</a> +</div> + +</body> +</html> diff --git a/docshell/test/mochitest/file_bug668513.html b/docshell/test/mochitest/file_bug668513.html new file mode 100644 index 0000000000..ae417a35bd --- /dev/null +++ b/docshell/test/mochitest/file_bug668513.html @@ -0,0 +1,101 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test file for Bug 668513</title> +<script> + var SimpleTest = opener.SimpleTest; + var ok = opener.ok; + var is = opener.is; + + function finish() { + SimpleTest.finish(); + close(); + } + + function onload_test() { + var win = frames[0]; + ok(win.performance, "Window.performance should be defined"); + ok(win.performance.navigation, "Window.performance.navigation should be defined"); + var navigation = win.performance && win.performance.navigation; + if (navigation === undefined) { + // avoid script errors + finish(); + return; + } + + // do this with a timeout to see the visuals of the navigations. + setTimeout(nav_frame, 100); + } + + var step = 1; + function nav_frame() { + var navigation_frame = frames[0]; + var navigation = navigation_frame.performance.navigation; + switch (step) { + case 1: + { + navigation_frame.location.href = "bug570341_recordevents.html"; + step++; + break; + } + case 2: + { + is(navigation.type, navigation.TYPE_NAVIGATE, + "Expected window.performance.navigation.type == TYPE_NAVIGATE"); + navigation_frame.history.back(); + step++; + break; + } + case 3: + { + is(navigation.type, navigation.TYPE_BACK_FORWARD, + "Expected window.performance.navigation.type == TYPE_BACK_FORWARD"); + step++; + navigation_frame.history.forward(); + break; + } + case 4: + { + is(navigation.type, navigation.TYPE_BACK_FORWARD, + "Expected window.performance.navigation.type == TYPE_BACK_FORWARD"); + navigation_frame.location.href = "bug668513_redirect.html"; + step++; + break; + } + case 5: + { + is(navigation.type, navigation.TYPE_NAVIGATE, + "Expected timing.navigation.type as TYPE_NAVIGATE"); + is(navigation.redirectCount, 1, + "Expected navigation.redirectCount == 1 on an server redirected navigation"); + + var timing = navigation_frame.performance && navigation_frame.performance.timing; + if (timing === undefined) { + // avoid script errors + finish(); + break; + } + ok(timing.navigationStart > 0, "navigationStart should be > 0"); + var sequence = ["navigationStart", "redirectStart", "redirectEnd", "fetchStart"]; + for (var j = 1; j < sequence.length; ++j) { + var prop = sequence[j]; + var prevProp = sequence[j - 1]; + ok(timing[prevProp] <= timing[prop], + ["Expected ", prevProp, " to happen before ", prop, + ", got ", prevProp, " = ", timing[prevProp], + ", ", prop, " = ", timing[prop]].join("")); + } + step++; + finish(); + break; + } + } + } +</script> +</head> +<body> +<div id="frames"> +<iframe name="child0" onload="onload_test();" src="navigation/blank.html"></iframe> +</div> +</body> +</html> diff --git a/docshell/test/mochitest/file_bug669671.sjs b/docshell/test/mochitest/file_bug669671.sjs new file mode 100644 index 0000000000..5871419de8 --- /dev/null +++ b/docshell/test/mochitest/file_bug669671.sjs @@ -0,0 +1,17 @@ +function handleRequest(request, response) { + var count = parseInt(getState("count")); + if (!count || request.queryString == "countreset") { + count = 0; + } + + setState("count", count + 1 + ""); + + response.setHeader("Content-Type", "text/html", false); + response.setHeader("Cache-Control", "max-age=0"); + response.write( + '<html><body onload="opener.onChildLoad()" ' + + "onunload=\"parseInt('0')\">" + + count + + "</body></html>" + ); +} diff --git a/docshell/test/mochitest/file_bug675587.html b/docshell/test/mochitest/file_bug675587.html new file mode 100644 index 0000000000..842ab9ae79 --- /dev/null +++ b/docshell/test/mochitest/file_bug675587.html @@ -0,0 +1 @@ +<script>location.hash = "";</script> diff --git a/docshell/test/mochitest/file_bug680257.html b/docshell/test/mochitest/file_bug680257.html new file mode 100644 index 0000000000..ff480e96a5 --- /dev/null +++ b/docshell/test/mochitest/file_bug680257.html @@ -0,0 +1,16 @@ +<!DOCTYPE HTML> +<html> +<head> + <style type='text/css'> + a { color: black; } + a:target { color: red; } + </style> +</head> + +<body onload='(opener || parent).popupLoaded()'> + +<a id='a' href='#a'>link</a> +<a id='b' href='#b'>link2</a> + +</body> +</html> diff --git a/docshell/test/mochitest/file_bug703855.html b/docshell/test/mochitest/file_bug703855.html new file mode 100644 index 0000000000..fe15b6e3df --- /dev/null +++ b/docshell/test/mochitest/file_bug703855.html @@ -0,0 +1,2 @@ +<!DOCTYPE html> +<!-- Just need an empty file here, as long as it's served over HTTP --> diff --git a/docshell/test/mochitest/file_bug728939.html b/docshell/test/mochitest/file_bug728939.html new file mode 100644 index 0000000000..1cd52a44e1 --- /dev/null +++ b/docshell/test/mochitest/file_bug728939.html @@ -0,0 +1,3 @@ +<html> +<body onload="opener.popupLoaded()">file_bug728939</body> +</html> diff --git a/docshell/test/mochitest/file_close_onpagehide1.html b/docshell/test/mochitest/file_close_onpagehide1.html new file mode 100644 index 0000000000..ccf3b625a1 --- /dev/null +++ b/docshell/test/mochitest/file_close_onpagehide1.html @@ -0,0 +1,5 @@ +<script> + window.onload = () => { + opener.postMessage("initial", "*"); + }; +</script> diff --git a/docshell/test/mochitest/file_close_onpagehide2.html b/docshell/test/mochitest/file_close_onpagehide2.html new file mode 100644 index 0000000000..a8e9479f47 --- /dev/null +++ b/docshell/test/mochitest/file_close_onpagehide2.html @@ -0,0 +1,5 @@ +<script> + window.onload = () => { + opener.postMessage("second", "*"); + }; +</script>; diff --git a/docshell/test/mochitest/file_compressed_multipart b/docshell/test/mochitest/file_compressed_multipart Binary files differnew file mode 100644 index 0000000000..3c56226951 --- /dev/null +++ b/docshell/test/mochitest/file_compressed_multipart diff --git a/docshell/test/mochitest/file_compressed_multipart^headers^ b/docshell/test/mochitest/file_compressed_multipart^headers^ new file mode 100644 index 0000000000..9376927812 --- /dev/null +++ b/docshell/test/mochitest/file_compressed_multipart^headers^ @@ -0,0 +1,2 @@ +Content-Type: multipart/x-mixed-replace; boundary="testingtesting" +Content-Encoding: gzip diff --git a/docshell/test/mochitest/file_content_javascript_loads_frame.html b/docshell/test/mochitest/file_content_javascript_loads_frame.html new file mode 100644 index 0000000000..9e2851aa8b --- /dev/null +++ b/docshell/test/mochitest/file_content_javascript_loads_frame.html @@ -0,0 +1,17 @@ +<!DOCTYPE html> +<html lang="en"> +<head> +<meta charset="utf-8"> +<script type="application/javascript"> +"use strict"; + +addEventListener("message", event => { + if ("ping" in event.data) { + event.source.postMessage({ pong: event.data.ping }, event.origin); + } +}); +</script> +</head> +<body> +</body> +</html> diff --git a/docshell/test/mochitest/file_content_javascript_loads_root.html b/docshell/test/mochitest/file_content_javascript_loads_root.html new file mode 100644 index 0000000000..b9f2c1faa7 --- /dev/null +++ b/docshell/test/mochitest/file_content_javascript_loads_root.html @@ -0,0 +1,42 @@ +<!DOCTYPE html> +<html lang="en"> +<head> +<meta charset="utf-8"> +<script type="application/javascript"> +"use strict"; + +window.onload = () => { + opener.postMessage("ready", "*"); +}; + +// eslint-disable-next-line no-shadow +function promiseMessage(source, filter = event => true) { + return new Promise(resolve => { + function listener(event) { + if (event.source == source && filter(event)) { + removeEventListener("message", listener); + resolve(event); + } + } + addEventListener("message", listener); + }); +} + +// Sends a message to the given target window and waits for the response. +function ping(target) { + let msg = { ping: Math.random() }; + target.postMessage(msg, "*"); + return promiseMessage( + target, + event => event.data && event.data.pong == msg.ping + ); +} + +function setFrameLocation(name, uri) { + window[name].location = uri; +} +</script> +</head> +<body> +</body> +</html> diff --git a/docshell/test/mochitest/file_form_restoration_no_store.html b/docshell/test/mochitest/file_form_restoration_no_store.html new file mode 100644 index 0000000000..6e8756a693 --- /dev/null +++ b/docshell/test/mochitest/file_form_restoration_no_store.html @@ -0,0 +1,38 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <script> + window.addEventListener("pageshow", ({ persisted }) => { + let bc = new BroadcastChannel("form_restoration"); + bc.addEventListener("message", ({ data }) => { + switch (data) { + case "enter_data": + document.getElementById("formElement").value = "test"; + break; + case "reload": + bc.close(); + location.reload(); + break; + case "navigate": + bc.close(); + document.location = "file_form_restoration_no_store.html?1"; + break; + case "back": + bc.close(); + history.back(); + break; + case "close": + bc.close(); + window.close(); + break; + } + }); + bc.postMessage({ persisted, formData: document.getElementById("formElement").value }); + }); + </script> +</head> +<body> + <input id="formElement" type="text" value="initial"> +</body> +</html> diff --git a/docshell/test/mochitest/file_form_restoration_no_store.html^headers^ b/docshell/test/mochitest/file_form_restoration_no_store.html^headers^ new file mode 100644 index 0000000000..4030ea1d3d --- /dev/null +++ b/docshell/test/mochitest/file_form_restoration_no_store.html^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store diff --git a/docshell/test/mochitest/file_framedhistoryframes.html b/docshell/test/mochitest/file_framedhistoryframes.html new file mode 100644 index 0000000000..314f9c72d8 --- /dev/null +++ b/docshell/test/mochitest/file_framedhistoryframes.html @@ -0,0 +1,16 @@ +<!DOCTYPE HTML> +<html> +<body> +<iframe id="iframe" src="historyframes.html"></iframe> +<script type="application/javascript"> + +var SimpleTest = window.opener.SimpleTest; +var is = window.opener.is; + +function done() { + window.opener.done(); +} + +</script> +</body> +</html> diff --git a/docshell/test/mochitest/file_load_during_reload.html b/docshell/test/mochitest/file_load_during_reload.html new file mode 100644 index 0000000000..600d5c1728 --- /dev/null +++ b/docshell/test/mochitest/file_load_during_reload.html @@ -0,0 +1,12 @@ +<!DOCTYPE HTML> +<html> + <head> + <script> + function notifyOpener() { + opener.postMessage("loaded", "*"); + } + </script> + </head> + <body onload="notifyOpener()"> + </body> +</html> diff --git a/docshell/test/mochitest/file_pushState_after_document_open.html b/docshell/test/mochitest/file_pushState_after_document_open.html new file mode 100644 index 0000000000..97a6954f2e --- /dev/null +++ b/docshell/test/mochitest/file_pushState_after_document_open.html @@ -0,0 +1,11 @@ +<!DOCTYPE html> +<script> + document.addEventListener("DOMContentLoaded", function() { + document.open(); + document.write("<!DOCTYPE html>New Document here"); + document.close(); + // Notify parent via postMessage, since otherwise exceptions will not get + // caught by its onerror handler. + parent.postMessage("doTest", "*"); + }); +</script> diff --git a/docshell/test/mochitest/file_redirect_history.html b/docshell/test/mochitest/file_redirect_history.html new file mode 100644 index 0000000000..3971faf4fd --- /dev/null +++ b/docshell/test/mochitest/file_redirect_history.html @@ -0,0 +1,18 @@ +<html> + <head> + <script> + function loaded() { + addEventListener("message", ({ data }) => { + document.getElementById("form").action = data; + document.getElementById("button").click(); + }, { once: true }); + opener.postMessage("loaded", "*"); + } + </script> + </head> + <body onload="loaded();"> + <form id="form" method="POST"> + <input id="button" type="submit" /> + </form> + </body> +</html> diff --git a/docshell/test/mochitest/form_submit.sjs b/docshell/test/mochitest/form_submit.sjs new file mode 100644 index 0000000000..1a1fa5d89c --- /dev/null +++ b/docshell/test/mochitest/form_submit.sjs @@ -0,0 +1,40 @@ +"use strict"; + +const CC = Components.Constructor; +const BinaryInputStream = CC( + "@mozilla.org/binaryinputstream;1", + "nsIBinaryInputStream", + "setInputStream" +); + +const BinaryOutputStream = CC( + "@mozilla.org/binaryoutputstream;1", + "nsIBinaryOutputStream", + "setOutputStream" +); + +function log(str) { + // dump(`LOG: ${str}\n`); +} + +async function handleRequest(request, response) { + if (request.method !== "POST") { + throw new Error("Expected a post request"); + } else { + log("Reading request"); + let available = 0; + let inputStream = new BinaryInputStream(request.bodyInputStream); + while ((available = inputStream.available()) > 0) { + log(inputStream.readBytes(available)); + } + } + + log("Setting Headers"); + response.setHeader("Content-Type", "text/html", false); + response.setStatusLine(request.httpVersion, "200", "OK"); + log("Writing body"); + response.write( + '<script>"use strict"; let target = opener ? opener : parent; target.postMessage("done", "*");</script>' + ); + log("Done"); +} diff --git a/docshell/test/mochitest/form_submit_redirect.sjs b/docshell/test/mochitest/form_submit_redirect.sjs new file mode 100644 index 0000000000..96fd84561c --- /dev/null +++ b/docshell/test/mochitest/form_submit_redirect.sjs @@ -0,0 +1,13 @@ +"use strict"; + +async function handleRequest(request, response) { + if (request.method !== "POST") { + throw new Error("Expected a post request"); + } else { + let params = new URLSearchParams(request.queryString); + let redirect = params.get("redirectTo"); + + response.setStatusLine(request.httpVersion, 302, "Moved Temporarily"); + response.setHeader("Location", redirect); + } +} diff --git a/docshell/test/mochitest/historyframes.html b/docshell/test/mochitest/historyframes.html new file mode 100644 index 0000000000..31f46a5071 --- /dev/null +++ b/docshell/test/mochitest/historyframes.html @@ -0,0 +1,176 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=602256 +--> +<head> + <title>Test for Bug 602256</title> +</head> +<body onload="SimpleTest.executeSoon(run_test)"> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=602256">Mozilla Bug 602256</a> +<div id="content"> + <iframe id="iframe" src="start_historyframe.html"></iframe> +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 602256 */ + +var testWin = window.opener ? window.opener : window.parent; + +var SimpleTest = testWin.SimpleTest; +function is() { testWin.is.apply(testWin, arguments); } + +var gFrame = null; + +function gState() { + return location.hash.replace(/^#/, ""); +} + +function waitForLoad(aCallback) { + function listener() { + gFrame.removeEventListener("load", listener); + SimpleTest.executeSoon(aCallback); + } + + gFrame.addEventListener("load", listener); +} + +function loadContent(aURL, aCallback) { + waitForLoad(aCallback); + + gFrame.src = aURL; +} + +function getURL() { + return gFrame.contentDocument.documentURI; +} + +function getContent() { + return gFrame.contentDocument.getElementById("text").textContent; +} + +var BASE_URI = "http://mochi.test:8888/tests/docshell/test/mochitest/"; +var START = BASE_URI + "start_historyframe.html"; +var URL1 = BASE_URI + "url1_historyframe.html"; +var URL2 = BASE_URI + "url2_historyframe.html"; + +function run_test() { + window.location.hash = "START"; + + gFrame = document.getElementById("iframe"); + + test_basic_inner_navigation(); +} + +function end_test() { + testWin.done(); +} + +var gTestContinuation = null; +function continueAsync() { + setTimeout(function() { gTestContinuation.next(); }) +} + +function test_basic_inner_navigation() { + // Navigate the inner frame a few times + loadContent(URL1, function() { + is(getURL(), URL1, "URL should be correct"); + is(getContent(), "Test1", "Page should be correct"); + + loadContent(URL2, function() { + is(getURL(), URL2, "URL should be correct"); + is(getContent(), "Test2", "Page should be correct"); + + // Test that history is working + waitForLoad(function() { + is(getURL(), URL1, "URL should be correct"); + is(getContent(), "Test1", "Page should be correct"); + + waitForLoad(function() { + is(getURL(), URL2, "URL should be correct"); + is(getContent(), "Test2", "Page should be correct"); + + gTestContinuation = test_state_navigation(); + gTestContinuation.next(); + }); + window.history.forward(); + }); + window.history.back(); + }); + }); +} + +function* test_state_navigation() { + window.location.hash = "STATE1"; + + is(getURL(), URL2, "URL should be correct"); + is(getContent(), "Test2", "Page should be correct"); + + window.location.hash = "STATE2"; + + is(getURL(), URL2, "URL should be correct"); + is(getContent(), "Test2", "Page should be correct"); + + window.addEventListener("popstate", (e) => { + continueAsync(); + }, {once: true}); + window.history.back(); + yield; + + is(gState(), "STATE1", "State should be correct after going back"); + is(getURL(), URL2, "URL should be correct"); + is(getContent(), "Test2", "Page should be correct"); + + window.addEventListener("popstate", (e) => { + continueAsync(); + }, {once: true}); + window.history.forward(); + yield; + + is(gState(), "STATE2", "State should be correct after going forward"); + is(getURL(), URL2, "URL should be correct"); + is(getContent(), "Test2", "Page should be correct"); + + window.addEventListener("popstate", (e) => { + continueAsync(); + }, {once: true}); + window.history.back(); + yield; + + window.addEventListener("popstate", (e) => { + continueAsync(); + }, {once: true}); + window.history.back(); + yield; + + is(gState(), "START", "State should be correct"); + is(getURL(), URL2, "URL should be correct"); + is(getContent(), "Test2", "Page should be correct"); + + waitForLoad(function() { + is(getURL(), URL1, "URL should be correct"); + is(getContent(), "Test1", "Page should be correct"); + + waitForLoad(function() { + is(gState(), "START", "State should be correct"); + is(getURL(), START, "URL should be correct"); + is(getContent(), "Start", "Page should be correct"); + + end_test(); + }); + + window.history.back(); + + is(gState(), "START", "State should be correct after going back twice"); + }); + + window.history.back(); + continueAsync(); + yield; + is(gState(), "START", "State should be correct"); +} +</script> +</pre> +</body> +</html> diff --git a/docshell/test/mochitest/mochitest.toml b/docshell/test/mochitest/mochitest.toml new file mode 100644 index 0000000000..8d593c9e36 --- /dev/null +++ b/docshell/test/mochitest/mochitest.toml @@ -0,0 +1,321 @@ +[DEFAULT] +support-files = [ + "bug404548-subframe.html", + "bug404548-subframe_window.html", + "bug413310-post.sjs", + "bug413310-subframe.html", + "bug529119-window.html", + "bug570341_recordevents.html", + "bug668513_redirect.html", + "bug668513_redirect.html^headers^", + "bug691547_frame.html", + "dummy_page.html", + "file_anchor_scroll_after_document_open.html", + "file_bfcache_plus_hash_1.html", + "file_bfcache_plus_hash_2.html", + "file_bug385434_1.html", + "file_bug385434_2.html", + "file_bug385434_3.html", + "file_bug475636.sjs", + "file_bug509055.html", + "file_bug540462.html", + "file_bug580069_1.html", + "file_bug580069_2.sjs", + "file_bug598895_1.html", + "file_bug598895_2.html", + "file_bug590573_1.html", + "file_bug590573_2.html", + "file_bug634834.html", + "file_bug637644_1.html", + "file_bug637644_2.html", + "file_bug640387.html", + "file_bug653741.html", + "file_bug660404", + "file_bug660404^headers^", + "file_bug660404-1.html", + "file_bug662170.html", + "file_bug669671.sjs", + "file_bug680257.html", + "file_bug703855.html", + "file_bug728939.html", + "file_bug1121701_1.html", + "file_bug1121701_2.html", + "file_bug1186774.html", + "file_bug1151421.html", + "file_bug1450164.html", + "file_close_onpagehide1.html", + "file_close_onpagehide2.html", + "file_compressed_multipart", + "file_compressed_multipart^headers^", + "file_pushState_after_document_open.html", + "historyframes.html", + "ping.html ", + "start_historyframe.html", + "url1_historyframe.html", + "url2_historyframe.html", +] + +["test_anchor_scroll_after_document_open.html"] + +["test_bfcache_plus_hash.html"] + +["test_bug385434.html"] + +["test_bug387979.html"] + +["test_bug402210.html"] +skip-if = [ + "http3", + "http2", +] + +["test_bug404548.html"] + +["test_bug413310.html"] +skip-if = ["true"] # Disabled for too many intermittent failures (bug 719186) + +["test_bug475636.html"] + +["test_bug509055.html"] + +["test_bug511449.html"] +skip-if = [ + "os == 'win'", + "os == 'linux'", + "os == 'android'", + "headless", # Headless: bug 1410525 +] +support-files = ["file_bug511449.html"] + +["test_bug529119-1.html"] + +["test_bug529119-2.html"] +skip-if = [ + "http3", + "http2", +] + +["test_bug530396.html"] +support-files = [ + "bug530396-noref.sjs", + "bug530396-subframe.html", +] +skip-if = [ + "http3", + "http2", +] + +["test_bug540462.html"] +skip-if = ["os == 'android' && debug"] + +["test_bug551225.html"] + +["test_bug570341.html"] +skip-if = ["(verify && !debug && (os == 'win'))"] + +["test_bug580069.html"] +skip-if = ["(verify && !debug && (os == 'win'))"] + +["test_bug590573.html"] + +["test_bug598895.html"] + +["test_bug634834.html"] +skip-if = [ + "http3", + "http2", +] + +["test_bug637644.html"] + +["test_bug640387_1.html"] + +["test_bug640387_2.html"] + +["test_bug653741.html"] + +["test_bug660404.html"] + +["test_bug662170.html"] + +["test_bug668513.html"] +support-files = ["file_bug668513.html"] + +["test_bug669671.html"] + +["test_bug675587.html"] +support-files = ["file_bug675587.html"] + +["test_bug680257.html"] + +["test_bug691547.html"] + +["test_bug694612.html"] + +["test_bug703855.html"] + +["test_bug728939.html"] + +["test_bug797909.html"] + +["test_bug1045096.html"] + +["test_bug1121701.html"] + +["test_bug1151421.html"] + +["test_bug1186774.html"] + +["test_bug1422334.html"] +support-files = [ + "bug1422334_redirect.html", + "bug1422334_redirect.html^headers^", + "!/docshell/test/navigation/blank.html", +] + +["test_bug1450164.html"] + +["test_bug1507702.html"] + +["test_bug1645781.html"] +support-files = ["form_submit.sjs"] +skip-if = [ + "http3", + "http2", +] + +["test_bug1729662.html"] +support-files = ["file_bug1729662.html"] + +["test_bug1740516.html"] +support-files = [ + "file_bug1740516_1.html", + "file_bug1740516_1_inner.html", + "file_bug1740516_2.html", +] + +["test_bug1741132.html"] +support-files = ["file_bug1741132.html"] +skip-if = ["os == 'android' && !sessionHistoryInParent"] + +["test_bug1742865.html"] +support-files = [ + "file_bug1742865.sjs", + "file_bug1742865_outer.sjs", +] +skip-if = [ + "os == 'android' && debug && fission && verify", # Bug 1745937 + "http3", + "http2", +] + +["test_bug1743353.html"] +support-files = ["file_bug1743353.html"] + +["test_bug1747033.html"] +support-files = ["file_bug1747033.sjs"] +skip-if = [ + "http3", + "http2", +] + +["test_bug1773192.html"] +support-files = [ + "file_bug1773192_1.html", + "file_bug1773192_2.html", + "file_bug1773192_3.sjs", +] + +["test_bug1850335.html"] +support-files = [ + "file_bug1850335_1.html", + "file_bug1850335_2.html", + "file_bug1850335_3.html", +] + +["test_close_onpagehide_by_history_back.html"] + +["test_close_onpagehide_by_window_close.html"] + +["test_compressed_multipart.html"] + +["test_content_javascript_loads.html"] +support-files = [ + "file_content_javascript_loads_root.html", + "file_content_javascript_loads_frame.html", +] +skip-if = [ + "http3", + "http2", +] + +["test_double_submit.html"] +support-files = [ + "clicker.html", + "double_submit.sjs", +] +skip-if = [ + "http3", + "http2", +] + +["test_forceinheritprincipal_overrule_owner.html"] +skip-if = [ + "http3", + "http2", +] + +["test_form_restoration.html"] +support-files = [ + "file_form_restoration_no_store.html", + "file_form_restoration_no_store.html^headers^", +] + +["test_framedhistoryframes.html"] +support-files = ["file_framedhistoryframes.html"] +skip-if = [ + "http3", + "http2", +] + +["test_iframe_srcdoc_to_remote.html"] +skip-if = [ + "http3", + "http2", +] + +["test_javascript_sandboxed_popup.html"] + +["test_load_during_reload.html"] +support-files = ["file_load_during_reload.html"] + +["test_navigate_after_pagehide.html"] +skip-if = [ + "http3", + "http2", +] + +["test_pushState_after_document_open.html"] + +["test_redirect_history.html"] +support-files = [ + "file_redirect_history.html", + "form_submit_redirect.sjs", +] +skip-if = [ + "http3", + "http2", +] + +["test_triggeringprincipal_location_seturi.html"] +skip-if = [ + "http3", + "http2", +] + +["test_windowedhistoryframes.html"] +skip-if = [ + "!debug && os == 'android'", # Bug 1573892 + "http3", + "http2", +] diff --git a/docshell/test/mochitest/ping.html b/docshell/test/mochitest/ping.html new file mode 100644 index 0000000000..7d84560dd1 --- /dev/null +++ b/docshell/test/mochitest/ping.html @@ -0,0 +1,6 @@ +<!doctype html> +<script> + "use strict"; + let target = (window.opener || window.parent); + target.postMessage("ping", "*"); +</script> diff --git a/docshell/test/mochitest/start_historyframe.html b/docshell/test/mochitest/start_historyframe.html new file mode 100644 index 0000000000..a791af4e64 --- /dev/null +++ b/docshell/test/mochitest/start_historyframe.html @@ -0,0 +1 @@ +<p id='text'>Start</p> diff --git a/docshell/test/mochitest/test_anchor_scroll_after_document_open.html b/docshell/test/mochitest/test_anchor_scroll_after_document_open.html new file mode 100644 index 0000000000..5309f6cf19 --- /dev/null +++ b/docshell/test/mochitest/test_anchor_scroll_after_document_open.html @@ -0,0 +1,55 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=881487 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 881487</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + + /** Test for Bug 881487 */ + SimpleTest.waitForExplicitFinish(); + // Child needs to invoke us, otherwise our onload will fire before the child + // has done the write/close bit. + var gotOnload = false; + addLoadEvent(function() { + gotOnload = true; + }); + onmessage = function handleMessage(msg) { + if (msg.data == "doTest") { + if (!gotOnload) { + addLoadEvent(function() { handleMessage(msg); }); + return; + } + frames[0].onscroll = function() { + ok(true, "Got a scroll event"); + SimpleTest.finish(); + }; + frames[0].location.hash = "#target"; + return; + } + if (msg.data == "haveHash") { + ok(false, "Child got reloaded"); + } else { + ok(false, "Unexpected message"); + } + SimpleTest.finish(); + }; + + </script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=881487">Mozilla Bug 881487</a> +<p id="display"> + <!-- iframe goes here so it can scroll --> +<iframe src="file_anchor_scroll_after_document_open.html"></iframe> +</p> +<div id="content" style="display: none"> +</div> +<pre id="test"> +</pre> +</body> +</html> diff --git a/docshell/test/mochitest/test_bfcache_plus_hash.html b/docshell/test/mochitest/test_bfcache_plus_hash.html new file mode 100644 index 0000000000..cb5bc06f21 --- /dev/null +++ b/docshell/test/mochitest/test_bfcache_plus_hash.html @@ -0,0 +1,153 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=646641 +--> +<head> + <title>Test for Bug 646641</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="/tests/SimpleTest/WindowSnapshot.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=646641">Mozilla Bug 646641</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 646641 */ + +/** + * Steps: + * - Main page (this one) opens file_bfcache_plus_hash_1.html (subpage 1) + * - subpage 1 sends msg { "childLoad", 1 } + * - subpage 1 sends msg { "childPageshow", 1 } + * - main page sends message "pushState" + * - subpage 1 does pushState() + * - subpage 1 navigates to file_bfcache_plus_hash_2.html (subpage 2) + * - subpage 2 sends msg { "childLoad", 2 } + * - subpage 2 sends msg { "childPageshow", 2 } + * - main page sends msg "go-2" + * - subpage 2 goes back two history entries + * - subpage 1 sends msg { "childPageshow", 1 } + * - Receiving only this msg shows we have retrieved the document from bfcache + * - main page sends msg "close" + * - subpage 1 sends msg "closed" + */ +SimpleTest.waitForExplicitFinish(); + +function debug(msg) { + // Wrap dump so we can turn debug messages on and off easily. + dump(msg + "\n"); +} + +var expectedLoadNum = -1; +var expectedPageshowNum = -1; + +function waitForLoad(n) { + debug("Waiting for load " + n); + expectedLoadNum = n; +} + +function waitForShow(n) { + debug("Waiting for show " + n); + expectedPageshowNum = n; +} + + + +function executeTest() { + function* test() { + window.open("file_bfcache_plus_hash_1.html", "", "noopener"); + waitForLoad(1); + waitForShow(1); + yield undefined; + yield undefined; + + bc1.postMessage("pushState"); + + waitForLoad(2); + waitForShow(2); + yield undefined; + yield undefined; + + // Now go back 2. The first page should be retrieved from bfcache. + bc2.postMessage("go-2"); + waitForShow(1); + yield undefined; + + bc1.postMessage("close"); + } + + var bc1 = new BroadcastChannel("bug646641_1"); + var bc2 = new BroadcastChannel("bug646641_2"); + bc1.onmessage = (msgEvent) => { + var msg = msgEvent.data.message; + var n = msgEvent.data.num; + if (msg == "childLoad") { + if (n == expectedLoadNum) { + debug("Got load " + n); + expectedLoadNum = -1; + + // Spin the event loop before calling gGen.next() so the generator runs + // outside the onload handler. This prevents us from encountering all + // sorts of docshell quirks. + setTimeout(function() { gGen.next(); }, 0); + } else { + debug("Got unexpected load " + n); + ok(false, "Got unexpected load " + n); + } + } else if (msg == "childPageshow") { + if (n == expectedPageshowNum) { + debug("Got expected pageshow " + n); + expectedPageshowNum = -1; + ok(true, "Got expected pageshow " + n); + setTimeout(function() { gGen.next(); }, 0); + } else { + debug("Got unexpected pageshow " + n); + ok(false, "Got unexpected pageshow " + n); + } + } else if (msg == "closed") { + bc1.close(); + bc2.close(); + SimpleTest.finish(); + } + } + + bc2.onmessage = bc1.onmessage; + + var gGen = test(); + + // If Fission is disabled, the pref is no-op. + SpecialPowers.pushPrefEnv({set: [["fission.bfcacheInParent", true]]}, () => { + gGen.next(); + }); +} +if (isXOrigin) { + // Bug 1746646: Make mochitests work with TCP enabled (cookieBehavior = 5) + // Acquire storage access permission here so that the BroadcastChannel used to + // communicate with the opened windows works in xorigin tests. Otherwise, + // the iframe containing this page is isolated from first-party storage access, + // which isolates BroadcastChannel communication. + SpecialPowers.wrap(document).notifyUserGestureActivation(); + SpecialPowers.addPermission("storageAccessAPI", true, window.location.href).then(() => { + SpecialPowers.wrap(document).requestStorageAccess().then(() => { + SpecialPowers.pushPrefEnv({ + set: [["privacy.partition.always_partition_third_party_non_cookie_storage", false]], + }).then(() => { + executeTest(); + }); + }); + }); +} else { + executeTest(); +} + + +</script> +</pre> +</body> +</html> diff --git a/docshell/test/mochitest/test_bug1045096.html b/docshell/test/mochitest/test_bug1045096.html new file mode 100644 index 0000000000..2df2232b7e --- /dev/null +++ b/docshell/test/mochitest/test_bug1045096.html @@ -0,0 +1,29 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1045096 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 1045096</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1045096">Mozilla Bug 1045096</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> + <script type="application/javascript"> + + /** Test for Bug 1045096 */ + var i = document.createElement("iframe"); + i.src = "javascript:false"; // This is required! + $("content").appendChild(i); + ok(i.contentWindow.performance, "Should have a performance object"); + </script> +</body> +</html> diff --git a/docshell/test/mochitest/test_bug1121701.html b/docshell/test/mochitest/test_bug1121701.html new file mode 100644 index 0000000000..cd0b2529d4 --- /dev/null +++ b/docshell/test/mochitest/test_bug1121701.html @@ -0,0 +1,108 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1121701 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 1121701</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + + /** Test for Bug 1121701 */ + SimpleTest.waitForExplicitFinish(); + + var testUrl1 = "file_bug1121701_1.html"; + var testUrl2 = "file_bug1121701_2.html"; + + var page1LoadCount = 0; + let page1Done = {}; + page1Done.promise = new Promise(resolve => { + page1Done.resolve = resolve; + }); + let page2Done = {}; + page2Done.promise = new Promise(resolve => { + page2Done.resolve = resolve; + }); + + addLoadEvent(async function() { + + // Bug 1746646: Make mochitests work with TCP enabled (cookieBehavior = 5) + // Acquire storage access permission here so that the BroadcastChannel used to + // communicate with the opened windows works in xorigin tests. Otherwise, + // the iframe containing this page is isolated from first-party storage access, + // which isolates BroadcastChannel communication. + if (isXOrigin) { + await SpecialPowers.pushPrefEnv({ + set: [["privacy.partition.always_partition_third_party_non_cookie_storage", false]], + }); + SpecialPowers.wrap(document).notifyUserGestureActivation(); + await SpecialPowers.addPermission("storageAccessAPI", true, window.location.href); + await SpecialPowers.wrap(document).requestStorageAccess(); + } + + var bc = new BroadcastChannel("file_bug1121701_1"); + var bc2 = new BroadcastChannel("file_bug1121701_2"); + + async function scheduleFinish() { + await Promise.all([page1Done.promise, page2Done.promise]); + bc2.close(); + bc.close(); + SimpleTest.finish(); + } + + bc.onmessage = (msgEvent) => { + var msg = msgEvent.data; + var command = msg.command; + if (command == "child1PageShow") { + ++page1LoadCount; + var persisted = msg.persisted; + var pageHideAsserts = msg.pageHideAsserts; + if (pageHideAsserts) { + ok(pageHideAsserts.persisted, "onpagehide: test page 1 should get persisted"); + is(pageHideAsserts.innerHTML, "modified", "onpagehide: innerHTML text is 'modified'"); + } + if (page1LoadCount == 1) { + SimpleTest.executeSoon(function() { + is(persisted, false, "Initial page load shouldn't be persisted."); + bc.postMessage({command: "setInnerHTML", testUrl2}); + }); + } else if (page1LoadCount == 2) { + is(persisted, true, "Page load from bfcache should be persisted."); + is(msg.innerHTML, "modified", "innerHTML text is 'modified'"); + bc.postMessage({command: "close"}); + } + } else if (command == "closed") { + page1Done.resolve(); + } + } + bc2.onmessage = (msgEvent) => { + var msg = msgEvent.data; + var command = msg.command; + if (command == "child2PageShow") { + bc2.postMessage({command: "setInnerHTML", location: location.href}); + } else if (command == "onmessage") { + page2Done.resolve(); + } + } + + scheduleFinish(); + // If Fission is disabled, the pref is no-op. + SpecialPowers.pushPrefEnv({set: [["fission.bfcacheInParent", true]]}, () => { + window.open(testUrl1, "", "noopener"); + }); + }); + + </script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1121701">Mozilla Bug 1121701</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +</body> +</html> diff --git a/docshell/test/mochitest/test_bug1151421.html b/docshell/test/mochitest/test_bug1151421.html new file mode 100644 index 0000000000..0738ee783e --- /dev/null +++ b/docshell/test/mochitest/test_bug1151421.html @@ -0,0 +1,61 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1151421 +--> +<head> + <title>Test for Bug 1151421</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1151421">Mozilla Bug 1151421</a> + +<script type="application/javascript"> + +/** Test for Bug 1151421 */ +SimpleTest.waitForExplicitFinish(); + +function childLoad() { + // Spin the event loop so we leave the onload handler. + SimpleTest.executeSoon(childLoad2); +} + +function childLoad2() { + let iframe = document.getElementById("iframe"); + let cw = iframe.contentWindow; + let content = cw.document.getElementById("content"); + + // Create a function to calculate an invariant. + let topPlusOffset = function() { + return Math.round(content.getBoundingClientRect().top + cw.pageYOffset); + }; + + let initialTPO = topPlusOffset(); + + // Scroll the iframe to various positions, and check the TPO. + // Scrolling down to the bottom will adjust the page offset by a fractional amount. + let positions = [-100, 0.17, 0, 1.5, 10.41, 1e6, 12.1]; + + // Run some tests with scrollTo() and ensure we have the same invariant after scrolling. + positions.forEach(function(pos) { + cw.scrollTo(0, pos); + is(topPlusOffset(), initialTPO, "Top plus offset should remain invariant across scrolling."); + }); + + positions.reverse().forEach(function(pos) { + cw.scrollTo(0, pos); + is(topPlusOffset(), initialTPO, "(reverse) Top plus offset should remain invariant across scrolling."); + }); + + SimpleTest.finish(); +} + +</script> + +<!-- When the iframe loads, it calls childLoad(). --> +<br> +<iframe height='100px' id='iframe' src='file_bug1151421.html'></iframe> + +</body> +</html> diff --git a/docshell/test/mochitest/test_bug1186774.html b/docshell/test/mochitest/test_bug1186774.html new file mode 100644 index 0000000000..9ec56baf11 --- /dev/null +++ b/docshell/test/mochitest/test_bug1186774.html @@ -0,0 +1,51 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1186774 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 1186774</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + + /** Test for Bug 1186774 */ + +var child; + +function runTest() { + child = window.open("file_bug1186774.html", "", "width=100,height=100"); + child.onload = function() { + setTimeout(function() { + child.scrollTo(0, 0); + child.history.pushState({}, "initial"); + child.scrollTo(0, 3000); + child.history.pushState({}, "scrolled"); + child.scrollTo(0, 6000); + child.history.back(); + }); + }; + + child.onpopstate = function() { + is(Math.round(child.scrollY), 6000, "Shouldn't have scrolled before popstate"); + child.close(); + SimpleTest.finish(); + }; +} + +SimpleTest.waitForExplicitFinish(); +addLoadEvent(runTest); + + </script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1186774">Mozilla Bug 1186774</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +</body> +</html> diff --git a/docshell/test/mochitest/test_bug1422334.html b/docshell/test/mochitest/test_bug1422334.html new file mode 100644 index 0000000000..b525ae1d9c --- /dev/null +++ b/docshell/test/mochitest/test_bug1422334.html @@ -0,0 +1,40 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <title>Ensure that reload after replaceState after 3xx redirect does the right thing.</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" href="/tests/SimpleTest/test.css"/> + <script> + SimpleTest.waitForExplicitFinish(); + addLoadEvent(function() { + var ifr = document.querySelector("iframe"); + var win = ifr.contentWindow; + is(win.location.href, location.href.replace(location.search, "") + .replace("mochitest/test_bug1422334.html", + "navigation/blank.html?x=y"), + "Should have the right location on initial load"); + + win.history.replaceState(null, '', win.location.pathname); + is(win.location.href, location.href.replace(location.search, "") + .replace("mochitest/test_bug1422334.html", + "navigation/blank.html"), + "Should have the right location after replaceState call"); + + ifr.onload = function() { + is(win.location.href, location.href.replace(location.search, "") + .replace("mochitest/test_bug1422334.html", + "navigation/blank.html"), + "Should have the right location after reload"); + SimpleTest.finish(); + } + win.location.reload(); + }); + </script> +</head> +<body> +<p id="display"><iframe src="bug1422334_redirect.html"></iframe></p> +<div id="content" style="display: none"></div> +<pre id="test"></pre> +</body> +</html> diff --git a/docshell/test/mochitest/test_bug1450164.html b/docshell/test/mochitest/test_bug1450164.html new file mode 100644 index 0000000000..546a988394 --- /dev/null +++ b/docshell/test/mochitest/test_bug1450164.html @@ -0,0 +1,31 @@ +<!DOCTYPE HTML> +<html> + <!-- + https://bugzilla.mozilla.org/show_bug.cgi?id=1450164 + --> + <head> + <meta charset="utf-8"> + <title>Test for Bug 1450164</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + + /** Test for Bug 1450164 */ + + function runTest() { + var child = window.open("file_bug1450164.html", "", "width=100,height=100"); + child.onload = function() { + // After the window loads, close it. If we don't crash in debug, consider that a pass. + child.close(); + }; + } + + SimpleTest.waitForExplicitFinish(); + addLoadEvent(runTest); + + </script> + </head> + <body> + <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1450164">Mozilla Bug 1450164</a> + </body> +</html> diff --git a/docshell/test/mochitest/test_bug1507702.html b/docshell/test/mochitest/test_bug1507702.html new file mode 100644 index 0000000000..fd88ee60a5 --- /dev/null +++ b/docshell/test/mochitest/test_bug1507702.html @@ -0,0 +1,57 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1507702 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 1507702</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <link rel="icon" href="about:crashparent"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1507702">Mozilla Bug 1507702</a> +<img src="about:crashparent"> +<img src="about:crashcontent"> +<iframe src="about:crashparent"></iframe> +<iframe src="about:crashcontent"></iframe> +<script> + let urls = ["about:crashparent", "about:crashcontent"]; + async function testFetch() { + const url = urls.shift(); + if (!url) { + return Promise.resolve(); + } + + let threw; + try { + await fetch(url); + threw = false; + } catch (e) { + threw = true; + } + + ok(threw === true, "fetch should reject"); + return testFetch(); + } + + document.body.onload = async () => { + for (const url of ["about:crashparent", "about:crashcontent"]) { + SimpleTest.doesThrow(() => { + top.location.href = url; + }, "navigation should throw"); + + SimpleTest.doesThrow(() => { + location.href = url; + }, "navigation should throw"); + } + + await testFetch(); + SimpleTest.finish(); + }; + + SimpleTest.waitForExplicitFinish(); +</script> +</body> +</html> diff --git a/docshell/test/mochitest/test_bug1645781.html b/docshell/test/mochitest/test_bug1645781.html new file mode 100644 index 0000000000..6cf676b7a9 --- /dev/null +++ b/docshell/test/mochitest/test_bug1645781.html @@ -0,0 +1,90 @@ +<!doctype html> +<html> + <head> + <title>Test for Bug 1590762</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="/tests/SimpleTest/EventUtils.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + </head> + <body> + <form id="form" action="form_submit.sjs" method="POST" target="targetFrame"> + <input id="input" type="text" name="name" value=""> + <input id="button" type="submit"> + </form> + <script> + "use strict"; + const PATH = "/tests/docshell/test/mochitest/"; + const SAME_ORIGIN = new URL(PATH, window.location.origin);; + // eslint-disable-next-line @microsoft/sdl/no-insecure-url + const CROSS_ORIGIN_1 = new URL(PATH, "http://test1.example.com/"); + const CROSS_ORIGIN_2 = new URL(PATH, "https://example.com/"); + const TARGET = "ping.html"; + const ACTION = "form_submit.sjs"; + + function generateBody(size) { + let data = new Uint8Array(size); + for (let i = 0; i < size; ++i) { + data[i] = 97 + Math.random() * (123 - 97); + } + + return new TextDecoder().decode(data); + } + + async function withFrame(url) { + info("Creating frame"); + let frame = document.createElement('iframe'); + frame.name = "targetFrame"; + + return new Promise(resolve => { + addEventListener('message', async function({source}) { + info("Frame loaded"); + if (frame.contentWindow == source) { + resolve(frame); + } + }, { once: true }); + frame.src = url; + document.body.appendChild(frame); + }); + } + + function click() { + synthesizeMouse(document.getElementById('button'), 5, 5, {}); + } + + function* spec() { + let urls = [SAME_ORIGIN, CROSS_ORIGIN_1, CROSS_ORIGIN_2]; + for (let action of urls) { + for (let target of urls) { + yield { action: new URL(ACTION, action), + target: new URL(TARGET, target) }; + } + } + } + + info("Starting tests"); + let form = document.getElementById('form'); + + // The body of the POST needs to be large to trigger this. + // 1024*1024 seems to be enough, but scaling to get a margin. + document.getElementById('input').value = generateBody(1024*1024); + for (let { target, action } of spec()) { + add_task(async function runTest() { + info(`Running test ${target} with ${action}`); + form.action = action; + let frame = await withFrame(target); + await new Promise(resolve => { + addEventListener('message', async function() { + info("Form loaded"); + frame.remove(); + resolve(); + }, { once: true }); + + click(); + }); + + ok(true, `Submitted to ${origin} with target ${action}`) + }); + }; + </script> + </body> +</html> diff --git a/docshell/test/mochitest/test_bug1729662.html b/docshell/test/mochitest/test_bug1729662.html new file mode 100644 index 0000000000..ec43508494 --- /dev/null +++ b/docshell/test/mochitest/test_bug1729662.html @@ -0,0 +1,76 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <title>Test back/forward after pushState</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" href="/tests/SimpleTest/test.css"/> + <script> + SimpleTest.waitForExplicitFinish(); + SimpleTest.requestFlakyTimeout("Need to wait to make sure an event does not fire"); + + async function runTest() { + let win = window.open(); + let goneBackAndForwardOnce = new Promise((resolve) => { + let timeoutID; + + // We should only get one load event in win. + let bc = new BroadcastChannel("bug1729662"); + bc.addEventListener("message", () => { + bc.addEventListener("message", () => { + clearTimeout(timeoutID); + resolve(false); + }); + }, { once: true }); + + let goneBack = false, goneForward = false; + win.addEventListener("popstate", ({ state }) => { + // We should only go back and forward once, if we get another + // popstate after that then we should fall through to the + // failure case below. + if (!(goneBack && goneForward)) { + // Check if this is the popstate for the forward (the one for + // back will have state == undefined). + if (state == 1) { + ok(goneBack, "We should have gone back before going forward"); + + goneForward = true; + + // Wait a bit to make sure there are no more popstate events. + // eslint-disable-next-line mozilla/no-arbitrary-setTimeout + timeoutID = setTimeout(resolve, 1000, true); + + return; + } + + // Check if we've gone back once before, if we get another + // popstate after that then we should fall through to the + // failure case below. + if (!goneBack) { + goneBack = true; + + return; + } + } + + clearTimeout(timeoutID); + resolve(false); + }); + }); + + win.location = "file_bug1729662.html"; + + ok(await goneBackAndForwardOnce, "Stopped navigating history"); + + win.close(); + + SimpleTest.finish(); + } + </script> +</head> +<body onload="runTest();"> +<p id="display"></p> +<div id="content" style="display: none"></div> +<pre id="test"></pre> +</body> +</html> diff --git a/docshell/test/mochitest/test_bug1740516.html b/docshell/test/mochitest/test_bug1740516.html new file mode 100644 index 0000000000..b54932c736 --- /dev/null +++ b/docshell/test/mochitest/test_bug1740516.html @@ -0,0 +1,79 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <title>Test pageshow event order for iframe</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" href="/tests/SimpleTest/test.css"/> + <script> + SimpleTest.waitForExplicitFinish(); + + function waitForPageShow(outer, inner) { + return new Promise((resolve) => { + let results = []; + outer.addEventListener("message", ({ data: persisted }) => { + results.push({ name: outer.name, persisted }); + if (results.length == 2) { + resolve(results); + } + }, { once: true }); + inner.addEventListener("message", ({ data: persisted }) => { + results.push({ name: inner.name, persisted }); + if (results.length == 2) { + resolve(results); + } + }, { once: true }); + }); + } + async function runTest() { + let outerBC = new BroadcastChannel("bug1740516_1"); + let innerBC = new BroadcastChannel("bug1740516_1_inner"); + + let check = waitForPageShow(outerBC, innerBC).then(([first, second]) => { + is(first.name, "bug1740516_1_inner", "Should get pageShow from inner iframe page first."); + ok(!first.persisted, "First navigation shouldn't come from BFCache."); + is(second.name, "bug1740516_1", "Should get pageShow from outer page second."); + ok(!second.persisted, "First navigation shouldn't come from BFCache."); + }, () => { + ok(false, "The promises should not be rejected."); + }); + window.open("file_bug1740516_1.html", "", "noopener"); + await check; + + check = waitForPageShow(outerBC, innerBC).then(([first, second]) => { + is(first.name, "bug1740516_1_inner", "Should get pageShow from inner iframe page first."); + ok(first.persisted, "Second navigation should come from BFCache"); + is(second.name, "bug1740516_1", "Should get pageShow from outer page second."); + ok(second.persisted, "Second navigation should come from BFCache"); + }, () => { + ok(false, "The promises should not be rejected."); + }); + outerBC.postMessage("navigate"); + await check; + + check = waitForPageShow(outerBC, innerBC).then(([first, second]) => { + is(first.name, "bug1740516_1_inner", "Should get pageShow from inner iframe page first."); + ok(!first.persisted, "Third navigation should not come from BFCache"); + is(second.name, "bug1740516_1", "Should get pageShow from outer page second."); + ok(!second.persisted, "Third navigation should not come from BFCache"); + }, () => { + ok(false, "The promises should not be rejected."); + }); + outerBC.postMessage("block_bfcache_and_navigate"); + await check; + + outerBC.postMessage("close"); + + outerBC.close(); + innerBC.close(); + + SimpleTest.finish(); + } + </script> +</head> +<body onload="runTest();"> +<p id="display"></p> +<div id="content" style="display: none"></div> +<pre id="test"></pre> +</body> +</html> diff --git a/docshell/test/mochitest/test_bug1741132.html b/docshell/test/mochitest/test_bug1741132.html new file mode 100644 index 0000000000..1ae9727d9c --- /dev/null +++ b/docshell/test/mochitest/test_bug1741132.html @@ -0,0 +1,79 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <title>Test form restoration for no-store pages</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" href="/tests/SimpleTest/test.css"/> + <script> + // The number of entries which we keep in the BFCache (see nsSHistory.h). + const VIEWER_WINDOW = 3; + + SimpleTest.waitForExplicitFinish(); + + function runTest() { + let bc = new BroadcastChannel("bug1741132"); + + // Setting the pref to 0 should evict all content viewers. + let load = SpecialPowers.pushPrefEnv({ + set: [["browser.sessionhistory.max_total_viewers", 0]], + }).then(() => { + // Set the pref to VIEWER_WINDOW + 2 now, to be sure we + // could fit all entries. + SpecialPowers.pushPrefEnv({ + set: [["browser.sessionhistory.max_total_viewers", VIEWER_WINDOW + 2]], + }); + }).then(() => { + return new Promise(resolve => { + bc.addEventListener("message", resolve, { once: true }); + window.open("file_bug1741132.html", "", "noopener"); + }); + }); + // We want to try to keep one entry too many in the BFCache, + // so we ensure that there's at least VIEWER_WINDOW + 2 + // entries in session history (with one for the displayed + // page). + for (let i = 0; i < VIEWER_WINDOW + 2; ++i) { + load = load.then(() => { + return new Promise((resolve) => { + bc.addEventListener("message", resolve, { once: true }); + bc.postMessage({ cmd: "load", arg: `file_bug1741132.html?${i}` }); + }); + }); + } + load.then(() => { + return new Promise((resolve) => { + bc.addEventListener("message", ({ data: persisted }) => { + resolve(persisted); + }, { once: true }); + // Go back past the first entry that should be in the BFCache. + bc.postMessage({ cmd: "go", arg: -(VIEWER_WINDOW + 1) }); + }); + }).then((persisted) => { + ok(!persisted, "Only 3 pages should be kept in the BFCache"); + }).then(() => { + return new Promise((resolve) => { + bc.addEventListener("message", ({ data: persisted }) => { + resolve(persisted); + }, { once: true }); + // Go forward to the first entry that should be in the BFCache. + bc.postMessage({ cmd: "go", arg: 1 }); + }); + }).then((persisted) => { + ok(persisted, "3 pages should be kept in the BFCache"); + + bc.postMessage("close"); + + bc.close(); + + SimpleTest.finish(); + }); + } + </script> +</head> +<body onload="runTest();"> +<p id="display"></p> +<div id="content" style="display: none"></div> +<pre id="test"></pre> +</body> +</html> diff --git a/docshell/test/mochitest/test_bug1742865.html b/docshell/test/mochitest/test_bug1742865.html new file mode 100644 index 0000000000..c8f9a4eca3 --- /dev/null +++ b/docshell/test/mochitest/test_bug1742865.html @@ -0,0 +1,137 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <title>Auto refreshing pages shouldn't add an entry to session history</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" href="/tests/SimpleTest/test.css"/> + <script> + const REFRESH_REDIRECT_TIMER = 15; + + // 2 tests (same and cross origin) consisting of 2 refreshes of maximum 1 seconds + // 2 tests (same and cross origin) consisting of 2 refreshes of REFRESH_REDIRECT_TIMER seconds + // => We need (2 * 1) + (2 * 15) seconds + SimpleTest.requestLongerTimeout(3); + SimpleTest.waitForExplicitFinish(); + + const SJS = new URL("file_bug1742865.sjs", location.href); + const SJS_OUTER = new URL("file_bug1742865_outer.sjs", location.href); + const SCROLL = 500; + + let tolerance; + function setup() { + return SpecialPowers.spawn(window.top, [], () => { + return SpecialPowers.getDOMWindowUtils(content.window).getResolution(); + }).then(resolution => { + // Allow a half pixel difference if the top document's resolution is lower + // than 1.0 because the scroll position is aligned with screen pixels + // instead of CSS pixels. + tolerance = resolution < 1.0 ? 0.5 : 0.0; + }); + } + + function checkScrollPosition(scrollPosition, shouldKeepScrollPosition) { + isfuzzy(scrollPosition, shouldKeepScrollPosition ? SCROLL : 0, tolerance, + `Scroll position ${shouldKeepScrollPosition ? "should" : "shouldn't"} be maintained for meta refresh`); + } + + function openWindowAndCheckRefresh(url, params, shouldAddToHistory, shouldKeepScrollPosition) { + info(`Running test for ${JSON.stringify(params)}`); + + url = new URL(url); + Object.entries(params).forEach(([k, v]) => { url.searchParams.append(k, v) }); + url.searchParams.append("scrollTo", SCROLL); + + let resetURL = new URL(SJS); + resetURL.search = "?reset"; + return fetch(resetURL).then(() => { + return new Promise((resolve) => { + let count = 0; + window.addEventListener("message", function listener({ data: { commandType, commandData = {} } }) { + if (commandType == "onChangedInputValue") { + let { historyLength, inputValue } = commandData; + + if (shouldAddToHistory) { + is(historyLength, count, "Auto-refresh should add entries to session history"); + } else { + is(historyLength, 1, "Auto-refresh shouldn't add entries to session history"); + } + + is(inputValue, "1234", "Input's value should have been changed"); + + win.postMessage("loadNext", "*"); + return; + } + + is(commandType, "pageShow", "Unknown command type"); + + let { inputValue, scrollPosition } = commandData; + + switch (++count) { + // file_bug1742865.sjs causes 3 loads: + // * first load, returns first meta refresh + // * second load, caused by first meta refresh, returns second meta refresh + // * third load, caused by second meta refresh, doesn't return a meta refresh + case 2: + checkScrollPosition(scrollPosition, shouldKeepScrollPosition); + break; + case 3: + checkScrollPosition(scrollPosition, shouldKeepScrollPosition); + win.postMessage("changeInputValue", "*"); + break; + case 4: + win.postMessage("back", "*"); + break; + case 5: + is(inputValue, "1234", "Entries for auto-refresh should be attached to session history"); + checkScrollPosition(scrollPosition, shouldKeepScrollPosition); + removeEventListener("message", listener); + win.close(); + resolve(); + break; + } + }); + let win = window.open(url); + }); + }); + } + + function doTest(seconds, crossOrigin, shouldAddToHistory, shouldKeepScrollPosition) { + let params = { + seconds, + crossOrigin, + }; + + return openWindowAndCheckRefresh(SJS, params, shouldAddToHistory, shouldKeepScrollPosition).then(() => + openWindowAndCheckRefresh(SJS_OUTER, params, shouldAddToHistory, shouldKeepScrollPosition) + ); + } + + async function runTest() { + const FAST = Math.min(1, REFRESH_REDIRECT_TIMER); + const SLOW = REFRESH_REDIRECT_TIMER + 1; + let tests = [ + // [ time, crossOrigin, shouldAddToHistory, shouldKeepScrollPosition ] + [ FAST, false, false, true ], + [ FAST, true, false, false ], + [ SLOW, false, false, true ], + [ SLOW, true, true, false ], + ]; + + await setup(); + + for (let [ time, crossOrigin, shouldAddToHistory, shouldKeepScrollPosition ] of tests) { + await doTest(time, crossOrigin, shouldAddToHistory, shouldKeepScrollPosition); + } + + SimpleTest.finish(); + } + </script> +</head> +<body onload="runTest();"> +<p id="display"></p> +<div id="content" style="display: none"> +</div> +<pre id="test"></pre> +</body> +</html> diff --git a/docshell/test/mochitest/test_bug1743353.html b/docshell/test/mochitest/test_bug1743353.html new file mode 100644 index 0000000000..a5d88df3f6 --- /dev/null +++ b/docshell/test/mochitest/test_bug1743353.html @@ -0,0 +1,57 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <title>Test back/forward after pushState</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" href="/tests/SimpleTest/test.css"/> + <script> + SimpleTest.waitForExplicitFinish(); + + function runTest() { + let bc = new BroadcastChannel("bug1743353"); + new Promise((resolve) => { + bc.addEventListener("message", () => { + resolve(); + }, { once: true }); + + window.open("file_bug1743353.html", "", "noopener"); + }).then(() => { + return new Promise(resolve => { + bc.addEventListener("message", () => { + resolve(); + }, { once: true }); + + bc.postMessage("load"); + }) + }).then(() => { + return new Promise(resolve => { + let results = []; + bc.addEventListener("message", function listener({ data }) { + results.push(data); + if (results.length == 3) { + bc.removeEventListener("message", listener); + resolve(results); + } + }); + + bc.postMessage("back"); + }); + }).then((results) => { + is(results[0], "pagehide", "First event should be 'pagehide'."); + is(results[1], "unload", "Second event should be 'unload'."); + is(results[2], "pageshow", "Third event should be 'pageshow'."); + + bc.postMessage("close"); + + SimpleTest.finish(); + }); + } + </script> +</head> +<body onload="runTest();"> +<p id="display"></p> +<div id="content" style="display: none"></div> +<pre id="test"></pre> +</body> +</html> diff --git a/docshell/test/mochitest/test_bug1747033.html b/docshell/test/mochitest/test_bug1747033.html new file mode 100644 index 0000000000..539b78fec0 --- /dev/null +++ b/docshell/test/mochitest/test_bug1747033.html @@ -0,0 +1,97 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <title>Test history after loading multipart</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" href="/tests/SimpleTest/test.css"/> + <script> + SimpleTest.waitForExplicitFinish(); + + function runTest() { + let bc = new BroadcastChannel("bug1747033"); + new Promise(resolve => { + bc.addEventListener("message", ({ data: { historyLength } }) => { + is(historyLength, 1, "Correct length for first normal load."); + + resolve(); + }, { once: true }); + + window.open("file_bug1747033.sjs", "", "noopener"); + }).then(() => { + return new Promise(resolve => { + let loaded = 0; + bc.addEventListener("message", function listener({ data: { historyLength } }) { + ++loaded; + + is(historyLength, 2, `Correct length for multipart load ${loaded}.`); + + // We want 3 parts in total. + if (loaded < 3) { + if (loaded == 2) { + // We've had 2 parts, make the server send the last part. + fetch("file_bug1747033.sjs?sendLastPart"); + } else { + fetch("file_bug1747033.sjs?sendNextPart"); + } + return; + } + + bc.removeEventListener("message", listener); + resolve(); + }); + + bc.postMessage({ cmd: "load", arg: "file_bug1747033.sjs?multipart" }); + }); + }).then(() => { + return new Promise(resolve => { + bc.addEventListener("message", ({ data: { historyLength } }) => { + is(historyLength, 2, "Correct length after calling replaceState in multipart."); + + resolve(); + }, { once: true }); + + bc.postMessage({ cmd: "replaceState", arg: "file_bug1747033.sjs?replaced" }); + }); + }).then(() => { + return new Promise(resolve => { + bc.addEventListener("message", ({ data: { historyLength } }) => { + is(historyLength, 3, "Correct length for first normal load after multipart."); + + resolve(); + }, { once: true }); + + bc.postMessage({ cmd: "load", arg: "file_bug1747033.sjs" }); + }); + }).then(() => { + return new Promise(resolve => { + let goneBack = 0; + bc.addEventListener("message", function listener({ data: { historyLength } }) { + ++goneBack; + + is(historyLength, 3, "Correct length after going back."); + + if (goneBack == 1) { + bc.postMessage({ cmd: "back" }); + } else if (goneBack == 2) { + bc.removeEventListener("message", listener); + resolve(); + } + }); + + bc.postMessage({ cmd: "back" }); + }); + }).then(() => { + bc.postMessage({ cmd: "close" }); + + SimpleTest.finish(); + }); + } + </script> +</head> +<body onload="runTest();"> +<p id="display"></p> +<div id="content" style="display: none"></div> +<pre id="test"></pre> +</body> +</html> diff --git a/docshell/test/mochitest/test_bug1773192.html b/docshell/test/mochitest/test_bug1773192.html new file mode 100644 index 0000000000..d4c42dc1a7 --- /dev/null +++ b/docshell/test/mochitest/test_bug1773192.html @@ -0,0 +1,61 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <title>Test referrer with going back</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" href="/tests/SimpleTest/test.css"/> + <script> + SimpleTest.waitForExplicitFinish(); + + // file_bug1773192_1.html will send a message with some data on pageshow. + function waitForData(bc) { + return new Promise(resolve => { + bc.addEventListener( + "message", + ({ data }) => { + resolve(data); + }, + { once: true } + ); + }); + } + async function runTest() { + let bc = new BroadcastChannel("bug1743353"); + + let getData = waitForData(bc); + + window.open("file_bug1773192_1.html", "", "noreferrer"); + + await getData.then(({ referrer }) => { + is(referrer, "", "Referrer should be empty at first."); + }); + + getData = waitForData(bc); + + // When file_bug1773192_1.html receives this message it will navigate to + // file_bug1773192_2.html. file_bug1773192_2.html removes itself from + // history with replaceState and submits a form with the POST method to + // file_bug1773192_3.sjs. file_bug1773192_3.sjs goes back in history. + // We should end up back at file_bug1773192_1.html, which will send a + // message with some data on pageshow. + bc.postMessage("next"); + + await getData.then(({ location, referrer }) => { + let firstURL = new URL("file_bug1773192_1.html", location).toString(); + is(location, firstURL, "Location should be the first page again."); + is(referrer, firstURL, "Referrer should also be the first page."); + }); + + bc.postMessage("close"); + + SimpleTest.finish(); + } + </script> +</head> +<body onload="runTest();"> +<p id="display"></p> +<div id="content" style="display: none"></div> +<pre id="test"></pre> +</body> +</html> diff --git a/docshell/test/mochitest/test_bug1850335.html b/docshell/test/mochitest/test_bug1850335.html new file mode 100644 index 0000000000..546aab59c8 --- /dev/null +++ b/docshell/test/mochitest/test_bug1850335.html @@ -0,0 +1,72 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <title>Test referrer with going back</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" href="/tests/SimpleTest/test.css"/> + <script> + SimpleTest.waitForExplicitFinish(); + + function waitForMessage(bc) { + return new Promise(resolve => { + bc.addEventListener("message", ({ data }) => { resolve(data); }, { once: true }); + }); + } + + async function runTest() { + let bc = new BroadcastChannel("bug1850335"); + + // Load the first page. + let waitForPage1 = waitForMessage(bc); + window.open("file_bug1850335_1.html", "_blank", "noopener"); + let { persisted, value: initial } = await waitForPage1; + + ok(!persisted, "Loaded first page"); + is(initial, "", "Initial value is empty string"); + + // Set the value of the input element in the first page. + let waitForValue = waitForMessage(bc); + bc.postMessage({ cmd: "setValue", arg: "ok" }); + let { value: expected }= await waitForValue; + is(expected, "ok", "Loaded first page"); + + // Load the second page (same origin with the first page). + let waitForPage2 = waitForMessage(bc); + bc.postMessage({ cmd: "load", arg: "file_bug1850335_2.html" }); + ({ persisted } = await waitForPage2); + + ok(!persisted, "Loaded second page (same-origin)"); + + // Load the third page (cross origin with the first and second pages). The + // third page will immediately do |history.back()| to go back to the + // second page. + waitForPage2 = waitForMessage(bc); + const crossOrigin = new URL("file_bug1850335_3.html", `https://example.com${location.pathname}`); + bc.postMessage({ cmd: "load", arg: crossOrigin.href }); + ({ persisted } = await waitForPage2); + + ok(!persisted, "Second page should not be in the BFCache"); + + // Go back to the first page. + waitForPage1 = waitForMessage(bc); + bc.postMessage({ cmd: "back" }); + let { persisted: fromBFCache, value: result } = await waitForPage1; + + ok(fromBFCache, "Page came from BFCache"); + is(result, expected, "Value wasn't cleared"); + + bc.postMessage({ cmd: "close" }); + + bc.close(); + + SimpleTest.finish(); + } + </script> +</head> +<body onload="runTest();"> +<p id="display"></p> +<div id="content" style="display: none"></div> +<pre id="test"></pre> +</body> +</html> diff --git a/docshell/test/mochitest/test_bug385434.html b/docshell/test/mochitest/test_bug385434.html new file mode 100644 index 0000000000..bc82de9daf --- /dev/null +++ b/docshell/test/mochitest/test_bug385434.html @@ -0,0 +1,211 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=385434 +--> +<head> + <title>Test for Bug 385434</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="/tests/SimpleTest/EventUtils.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=385434">Mozilla Bug 385434</a> +<p id="display"></p> +<div id="content"> + <iframe id="frame" style="height:100px; width:100px; border:0"></iframe> + <div id="status" style="display: none"></div> +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 385434 */ +SimpleTest.waitForExplicitFinish(); +SimpleTest.requestFlakyTimeout("untriaged"); +SimpleTest.expectAssertions(0, 1); // bug 1333702 + +var gNumHashchanges = 0; +var gCallbackOnIframeLoad = false; +var gSampleEvent; + +function statusMsg(msg) { + var msgElem = document.createElement("p"); + msgElem.appendChild(document.createTextNode(msg)); + + document.getElementById("status").appendChild(msgElem); +} + +function longWait() { + setTimeout(function() { gGen.next(); }, 1000); +} + +// onIframeHashchange, onIframeLoad, and onIframeScroll are all called by the +// content we load into our iframe in order to notify the parent frame of an +// event which was fired. +function onIframeHashchange() { + gNumHashchanges++; + gGen.next(); +} + +function onIframeLoad() { + if (gCallbackOnIframeLoad) { + gCallbackOnIframeLoad = false; + gGen.next(); + } +} + +function onIframeScroll() { + is(gNumHashchanges, 0, "onscroll should fire before onhashchange."); +} + +function enableIframeLoadCallback() { + gCallbackOnIframeLoad = true; +} + +function noEventExpected(msg) { + is(gNumHashchanges, 0, msg); + + // Even if there's an error, set gNumHashchanges to 0 so other tests don't + // fail. + gNumHashchanges = 0; +} + +function eventExpected(msg) { + is(gNumHashchanges, 1, msg); + + // Eat up this event, whether the test above was true or not + gNumHashchanges = 0; +} + +/* + * The hashchange event is dispatched asynchronously, so if we want to observe + * it, we have to yield within run_test(), transferring control back to the + * event loop. + * + * When we're expecting our iframe to observe a hashchange event after we poke + * it, we just yield and wait for onIframeHashchange() to call gGen.next() and + * wake us up. + * + * When we're testing to ensure that the iframe doesn't dispatch a hashchange + * event, we try to hook onto the iframe's load event. We call + * enableIframeLoadCallback(), which causes onIframeLoad() to call gGen.next() + * upon the next observed load. After we get our callback, we check that a + * hashchange didn't occur. + * + * We can't always just wait for page load in order to observe that a + * hashchange didn't happen. In these cases, we call longWait() and yield + * until either a hashchange occurs or longWait's callback is scheduled. This + * is something of a hack; it's entirely possible that longWait won't wait long + * enough, and we won't observe what should have been a failure of the test. + * But it shouldn't happen that good code will randomly *fail* this test. + */ +function* run_test() { + /* + * TEST 1 tests that: + * <body onhashchange = ... > works, + * the event is (not) fired at the correct times + */ + var frame = document.getElementById("frame"); + var frameCw = frame.contentWindow; + + enableIframeLoadCallback(); + frameCw.document.location = "file_bug385434_1.html"; + // Wait for the iframe to load and for our callback to fire + yield undefined; + + noEventExpected("No hashchange expected initially."); + + sendMouseEvent({type: "click"}, "link1", frameCw); + yield undefined; + eventExpected("Clicking link1 should trigger a hashchange."); + + sendMouseEvent({type: "click"}, "link1", frameCw); + longWait(); + yield undefined; + // succeed if a hashchange event wasn't triggered while we were waiting + noEventExpected("Clicking link1 again should not trigger a hashchange."); + + sendMouseEvent({type: "click"}, "link2", frameCw); + yield undefined; + eventExpected("Clicking link2 should trigger a hashchange."); + + frameCw.history.go(-1); + yield undefined; + eventExpected("Going back should trigger a hashchange."); + + frameCw.history.go(1); + yield undefined; + eventExpected("Going forward should trigger a hashchange."); + + // window.location has a trailing '#' right now, so we append "link1", not + // "#link1". + frameCw.window.location = frameCw.window.location + "link1"; + yield undefined; + eventExpected("Assigning to window.location should trigger a hashchange."); + + // Set up history in the iframe which looks like: + // file_bug385434_1.html#link1 + // file_bug385434_2.html + // file_bug385434_1.html#foo <-- current page + enableIframeLoadCallback(); + frameCw.window.location = "file_bug385434_2.html"; + yield undefined; + + enableIframeLoadCallback(); + frameCw.window.location = "file_bug385434_1.html#foo"; + yield undefined; + + // Now when we do history.go(-2) on the frame, it *shouldn't* fire a + // hashchange. Although the URIs differ only by their hashes, they belong to + // two different Documents. + frameCw.history.go(-2); + longWait(); + yield undefined; + noEventExpected("Moving between different Documents shouldn't " + + "trigger a hashchange."); + + /* + * TEST 2 tests that: + * <frameset onhashchange = ... > works, + * the event is targeted at the window object + * the event's cancelable, bubbles settings are correct + */ + + enableIframeLoadCallback(); + frameCw.document.location = "file_bug385434_2.html"; + yield undefined; + + frameCw.document.location = "file_bug385434_2.html#foo"; + yield undefined; + + eventExpected("frame onhashchange should fire events."); + // iframe should set gSampleEvent + is(gSampleEvent.target, frameCw, + "The hashchange event should be targeted to the window."); + is(gSampleEvent.type, "hashchange", + "Event type should be 'hashchange'."); + is(gSampleEvent.cancelable, false, + "The hashchange event shouldn't be cancelable."); + is(gSampleEvent.bubbles, false, + "The hashchange event should not bubble."); + + /* + * TEST 3 tests that: + * hashchange is dispatched if the current document readyState is + * not "complete" (bug 504837). + */ + frameCw.document.location = "file_bug385434_3.html"; + yield undefined; + eventExpected("Hashchange should fire even if the document " + + "hasn't finished loading."); + + SimpleTest.finish(); +} + +var gGen = run_test(); +gGen.next(); + +</script> +</pre> +</body> +</html> diff --git a/docshell/test/mochitest/test_bug387979.html b/docshell/test/mochitest/test_bug387979.html new file mode 100644 index 0000000000..0aca2ee89b --- /dev/null +++ b/docshell/test/mochitest/test_bug387979.html @@ -0,0 +1,52 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=387979 +--> +<head> + <title>Test for Bug 387979</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=387979">Mozilla Bug 387979</a> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +/** Test for Bug 387979 */ +function a(s) { + var r; + try { r = frames[0].document.body; } catch (e) { r = e; } + is(r instanceof frames[0].HTMLBodyElement, true, "Can't get body" + s); +} +var p = 0; +function b() { + switch (++p) { + case 1: + frames[0].location = "about:blank"; + break; + case 2: + a("before reload"); + frames[0].location.reload(); + break; + case 3: + a("after reload"); + SimpleTest.finish(); + break; + } +} + +SimpleTest.waitForExplicitFinish(); + +</script> +</pre> +<p id="display"> + <iframe onload="b()"></iframe> + <pre id="p">-</pre> +</p> +</body> +</html> + diff --git a/docshell/test/mochitest/test_bug402210.html b/docshell/test/mochitest/test_bug402210.html new file mode 100644 index 0000000000..326f98cf9f --- /dev/null +++ b/docshell/test/mochitest/test_bug402210.html @@ -0,0 +1,50 @@ +<!DOCTYPE HTML> +<html> +<!-- +While working on bug 402210, it came up that the code was doing + +a.href = proto + host + +which technically produces "https:host" instead of "https://host" and +that the code was relying on href's setting having fixup behaviour +for this kind of thing. + +If we rely on it, we might as well test for it, even if it isn't the +problem 402210 was meant to fix. + +https://bugzilla.mozilla.org/show_bug.cgi?id=402210 +--> +<head> + <title>Test for Bug 402210</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=402210">Mozilla Bug 402210</a> +<p id="display"> + <a id="testlink">Test Link</a> +</p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +SimpleTest.waitForExplicitFinish(); + +function runTest() { + $("testlink").href = "https:example.com"; + is($("testlink").href, "https://example.com/", "Setting href on an anchor tag should fixup missing slashes after https protocol"); + + $("testlink").href = "ftp:example.com"; + is($("testlink").href, "ftp://example.com/", "Setting href on an anchor tag should fixup missing slashes after non-http protocol"); + + SimpleTest.finish(); +} + +addLoadEvent(runTest); +</script> +</pre> +</body> +</html> + diff --git a/docshell/test/mochitest/test_bug404548.html b/docshell/test/mochitest/test_bug404548.html new file mode 100644 index 0000000000..a8a773dce5 --- /dev/null +++ b/docshell/test/mochitest/test_bug404548.html @@ -0,0 +1,39 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=404548 +--> +<head> + <title>Test for Bug 404548</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=404548">Mozilla Bug 404548</a> +<p id="display"> +</p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +/** Test for Bug 404548 */ +var firstRemoved = false; +var secondHidden = false; + +SimpleTest.waitForExplicitFinish(); + +var w = window.open("bug404548-subframe.html", "", "width=10,height=10"); + +function finishTest() { + is(firstRemoved, true, "Should have removed iframe from the DOM"); + is(secondHidden, true, "Should have fired pagehide on second kid"); + w.close(); + SimpleTest.finish(); +} +</script> +</pre> +</body> +</html> + diff --git a/docshell/test/mochitest/test_bug413310.html b/docshell/test/mochitest/test_bug413310.html new file mode 100644 index 0000000000..4299605575 --- /dev/null +++ b/docshell/test/mochitest/test_bug413310.html @@ -0,0 +1,106 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=413310 +--> +<head> + <title>Test for Bug 413310</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=413310">Mozilla Bug 413310</a> +<p id="display"> +<script class="testbody" type="text/javascript"> + +if (navigator.platform.startsWith("Mac")) { + SimpleTest.expectAssertions(0, 2); +} else { + SimpleTest.expectAssertions(0, 1); +} + +/** Test for Bug 413310 */ + +// NOTE: If we ever make subframes do bfcache stuff, this test will need to be +// modified accordingly! It assumes that subframes do NOT get bfcached. +var onloadCount = 0; + +var step = -1; // One increment will come from the initial subframe onload. + // Note that this script should come before the subframe, + // so that doNextStep is defined when its onload handler fires. + +var textContent; + +SimpleTest.waitForExplicitFinish(); + +addLoadEvent(doNextStep); + +function doNextStep() { + ++step; + switch (step) { + case 1: + is(onloadCount, 1, "Loaded initial page"); + is($("i").contentWindow.location.href, + location.href.replace(/test_bug413310.html/, + "bug413310-subframe.html"), + "Unexpected subframe location after initial load"); + $("i").contentDocument.forms[0].submit(); + break; + case 2: + is(onloadCount, 2, "Loaded POST result"); + + is($("i").contentWindow.location.href, + location.href.replace(/test_bug413310.html/, + "bug413310-post.sjs"), + "Unexpected subframe location after POST load"); + + textContent = $("i").contentDocument.body.textContent; + isDeeply(textContent.match(/^POST /), ["POST "], "Not a POST?"); + + $("i").contentWindow.location.hash = "foo"; + setTimeout(doNextStep, 0); + break; + case 3: + is(onloadCount, 2, "Anchor scroll should not fire onload"); + is($("i").contentWindow.location.href, + location.href.replace(/test_bug413310.html/, + "bug413310-post.sjs#foo"), + "Unexpected subframe location after anchor scroll"); + is(textContent, $("i").contentDocument.body.textContent, + "Did a load when scrolling?"); + $("i").contentWindow.location.href = "bug413310-subframe.html"; + break; + case 4: + is(onloadCount, 3, "Done new load"); + is($("i").contentWindow.location.href, + location.href.replace(/test_bug413310.html/, + "bug413310-subframe.html"), + "Unexpected subframe location after new load"); + history.back(); + break; + case 5: + is(onloadCount, 4, + "History traversal didn't fire onload: bfcache issues!"); + is($("i").contentWindow.location.href, + location.href.replace(/test_bug413310.html/, + "bug413310-post.sjs#foo"), + "Unexpected subframe location"); + is(textContent, $("i").contentDocument.body.textContent, + "Did a load when going back?"); + SimpleTest.finish(); + break; + } +} +</script> +<!-- Use a timeout in onload so that we don't do a load immediately inside onload --> +<iframe id="i" src="bug413310-subframe.html" onload="setTimeout(doNextStep, 20)"> +</iframe> +</p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +</body> +</html> + diff --git a/docshell/test/mochitest/test_bug475636.html b/docshell/test/mochitest/test_bug475636.html new file mode 100644 index 0000000000..fb1827ad04 --- /dev/null +++ b/docshell/test/mochitest/test_bug475636.html @@ -0,0 +1,52 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=475636 +Test that refresh to data: URIs don't inherit the principal +--> +<head> + <title>Test for Bug 475636</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body onload="gen.next()"> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=475636">Mozilla Bug 475636</a> + +<div id="content" style="display: none"> + +</div> +<iframe id=loader></iframe> +<pre id="test"> +<script class="testbody" type="application/javascript"> + +SimpleTest.waitForExplicitFinish(); + +var gen = runTests(); + +window.private = 42; + +window.addEventListener("message", function(e) { + gen.next(e.data); +}); + +var url = "file_bug475636.sjs?"; + +function* runTests() { + var loader = document.getElementById("loader"); + for (var testNum = 1; ; ++testNum) { + loader.src = url + testNum; + let res = (yield); + if (res == "done") { + SimpleTest.finish(); + return; + } + is(res, "pass"); + } +} + + +</script> +</pre> +</body> +</html> diff --git a/docshell/test/mochitest/test_bug509055.html b/docshell/test/mochitest/test_bug509055.html new file mode 100644 index 0000000000..57ede19b43 --- /dev/null +++ b/docshell/test/mochitest/test_bug509055.html @@ -0,0 +1,115 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=509055 +--> +<head> + <title>Test for Bug 509055</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="/tests/SimpleTest/EventUtils.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=509055">Mozilla Bug 509055</a> +<p id="display"></p> +<div id="status"></div> +<div id="content"> +</div> +<pre id="test"> + <script type="application/javascript"> + + /** Test for Bug 509055 */ + + SimpleTest.waitForExplicitFinish(); + + var gGen; + + function shortWait() { + setTimeout(function() { gGen.next(); }, 0, false); + } + + function onChildHashchange(e) { + // gGen might be undefined when we refresh the page, so we have to check here + dump("onChildHashchange() called.\n"); + if (gGen) + gGen.next(); + } + + function onChildLoad(e) { + if (gGen) + gGen.next(); + } + + async function* runTest() { + var popup = window.open("file_bug509055.html", "popup 0", + "height=200,width=200,location=yes," + + "menubar=yes,status=yes,toolbar=yes,dependent=yes"); + popup.hashchangeCallback = onChildHashchange; + popup.onload = onChildLoad; + dump("Waiting for initial load.\n"); + yield undefined; + + // Without this wait, the change to location.hash below doesn't create a + // SHEntry or enable the back button. + shortWait(); + dump("Got initial load. Spinning event loop.\n"); + yield undefined; + + popup.location.hash = "#1"; + dump("Waiting for hashchange.\n"); + yield undefined; + + popup.history.back(); + dump("Waiting for second hashchange.\n"); + yield undefined; // wait for hashchange + + popup.document.title = "Changed"; + + // Wait for listeners to be notified of the title change. + shortWait(); + dump("Got second hashchange. Spinning event loop.\n"); + yield undefined; + + let sheTitle = ""; + if (!SpecialPowers.Services.appinfo.sessionHistoryInParent) { + var sh = SpecialPowers.wrap(popup) + .docShell + .QueryInterface(SpecialPowers.Ci.nsIWebNavigation) + .sessionHistory; + + // Get the title of the inner popup's current SHEntry + sheTitle = sh.legacySHistory.getEntryAtIndex(sh.index).title; + } else { + let chromeScript = SpecialPowers.loadChromeScript(() => { + /* eslint-env mozilla/chrome-script */ + addMessageListener("getTitle", browsingContext => { + // eslint-disable-next-line no-shadow + let sh = browsingContext.sessionHistory; + let title = sh.getEntryAtIndex(sh.index).title; + sendAsyncMessage("title", title); + }); + }); + + let p = chromeScript.promiseOneMessage("title"); + let browsingContext = SpecialPowers.wrap(popup) + .docShell.browsingContext; + chromeScript.sendAsyncMessage("getTitle", browsingContext); + sheTitle = await p; + chromeScript.destroy(); + } + is(sheTitle, "Changed", "SHEntry's title should change when we change."); + + popup.close(); + + SimpleTest.executeSoon(SimpleTest.finish); + } + + window.addEventListener("load", function() { + gGen = runTest(); + gGen.next(); + }); + + </script> + +</body> +</html> diff --git a/docshell/test/mochitest/test_bug511449.html b/docshell/test/mochitest/test_bug511449.html new file mode 100644 index 0000000000..da95909d1c --- /dev/null +++ b/docshell/test/mochitest/test_bug511449.html @@ -0,0 +1,56 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=511449 +--> +<head> + <title>Test for Bug 511449</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="/tests/SimpleTest/EventUtils.js"></script> + <script src="/tests/SimpleTest/NativeKeyCodes.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=511449">Mozilla Bug 511449</a> +<p id="display"></p> +<div id="status"></div> +<div id="content"> +</div> +<input type="text" id="input"> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 511449 */ + +SimpleTest.waitForExplicitFinish(); +SimpleTest.requestFlakyTimeout("untriaged"); +window.addEventListener("load", runTest); + +var win = null; + +function runTest() { + document.getElementById("input").focus(); + win = window.open("file_bug511449.html", ""); + SimpleTest.waitForFocus(runNextTest, win); +} + +function runNextTest() { + var didClose = false; + win.onunload = function() { + didClose = true; + }; + synthesizeNativeKey(KEYBOARD_LAYOUT_EN_US, MAC_VK_ANSI_W, {metaKey: 1}, "w", "w"); + + setTimeout(function() { + ok(didClose, "Cmd+W should have closed the tab"); + if (!didClose) { + win.close(); + } + SimpleTest.finish(); + }, 1000); +} + +</script> + +</body> +</html> diff --git a/docshell/test/mochitest/test_bug529119-1.html b/docshell/test/mochitest/test_bug529119-1.html new file mode 100644 index 0000000000..1c89780fc7 --- /dev/null +++ b/docshell/test/mochitest/test_bug529119-1.html @@ -0,0 +1,110 @@ +<!DOCTYPE HTML> +<html> +<head> +<title>Test bug 529119</title> +<script src="/tests/SimpleTest/SimpleTest.js"></script> +<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + +<script class="testbody" type="text/javascript"> + +SimpleTest.waitForExplicitFinish(); +SimpleTest.requestFlakyTimeout("untriaged"); + +var workingURL = "http://mochi.test:8888/tests/docshell/test/mochitest/bug529119-window.html"; +var faultyURL = "https://www.some-nonexistent-domain-27489274c892748217cn2384.test/"; + +var w = null; +var phase = 0; +var gotWrongPageOnTryAgainClick = false; +// Token that represents which page we currently have loaded. +var token = 0; + +function delay(msec) { + return new Promise(resolve => setTimeout(resolve, msec)); +} + +async function assignToken(tokenToAssign) { + await SpecialPowers.spawn(w, [tokenToAssign], + newToken => { this.content.token = newToken }); +} + +async function pollForPage(win) { + while (true) { + try { + // When we do our navigation, there may be an interstitial about:blank + // page if the navigation involves a process switch. That about:blank + // will exist between the new process's docshell being created and the + // actual page that's being loaded loading (which can happen async from + // the docshell creation). We want to avoid treating the initial + // about:blank as a new page. + // + // We could conceivably expose Document::IsInitialDocument() as a + // ChromeOnly thing and use it here, but let's just filter out all + // about:blank, since we don't expect any in this test. + var haveNewPage = await SpecialPowers.spawn(w, [token], + currentToken => this.content.token != currentToken && + this.content.location.href != "about:blank"); + + if (haveNewPage) { + ++token; + assignToken(token); + break; + } + } catch (e) { + // Something went wrong; just keep waiting. + } + + await delay(100); + } +} + +async function windowLoaded() { + switch (phase) { + case 0: + assignToken(token); + + /* 2. We have succeededfully loaded a page, now go to a faulty URL */ + window.setTimeout(function() { + w.location.href = faultyURL; + }, 0); + + phase = 1; + + await pollForPage(w); + is(await SpecialPowers.spawn(w, [], () => this.content.location.href), + faultyURL, + "Is on an error page initially"); + + /* 3. now, while we are on the error page, try to reload it, actually + click the "Try Again" button */ + SpecialPowers.spawn(w, [], () => this.content.location.reload()); + + await pollForPage(w); + + /* 4-finish, check we are still on the error page */ + is(await SpecialPowers.spawn(w, [], () => this.content.location.href), + faultyURL, + "Is on an error page"); + is(gotWrongPageOnTryAgainClick, false, + "Must not get www.example.com page on reload of an error page"); + w.close(); + SimpleTest.finish(); + break; + + case 1: + /* 4-check, we must not get here! */ + gotWrongPageOnTryAgainClick = true; + break; + } +} + +function startTest() { + /* 1. load a URL that leads to an error page */ + w = window.open(workingURL); +} + +</script> +</head> +<body onload="startTest();"> +</body> +</html> diff --git a/docshell/test/mochitest/test_bug529119-2.html b/docshell/test/mochitest/test_bug529119-2.html new file mode 100644 index 0000000000..a8bd57d4f7 --- /dev/null +++ b/docshell/test/mochitest/test_bug529119-2.html @@ -0,0 +1,116 @@ +<!DOCTYPE HTML> +<html> +<head> +<title>Test bug 529119</title> +<script src="/tests/SimpleTest/SimpleTest.js"></script> +<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + +<script class="testbody" type="text/javascript"> + +SimpleTest.waitForExplicitFinish(); +SimpleTest.requestFlakyTimeout("untriaged"); + +var workingURL = "http://mochi.test:8888/tests/docshell/test/mochitest/bug529119-window.html"; +// eslint-disable-next-line @microsoft/sdl/no-insecure-url +var faultyURL = "http://some-nonexistent-domain-27489274c892748217cn2384.test/"; + +var w = null; +var phase = 0; +var isWindowLoaded = false; +// Token that represents which page we currently have loaded. +var token = 0; + +function delay(msec) { + return new Promise(resolve => setTimeout(resolve, msec)); +} + +async function assignToken(tokenToAssign) { + await SpecialPowers.spawn(w, [tokenToAssign], + newToken => { this.content.token = newToken }); +} + +// Returns when a new page is loaded and returns whether that page is an +// error page. +async function pollForPage(win) { + while (true) { + try { + // When we do our navigation, there may be an interstitial about:blank + // page if the navigation involves a process switch. That about:blank + // will exist between the new process's docshell being created and the + // actual page that's being loaded loading (which can happen async from + // the docshell creation). We want to avoid treating the initial + // about:blank as a new page. + // + // We could conceivably expose Document::IsInitialDocument() as a + // ChromeOnly thing and use it here, but let's just filter out all + // about:blank, since we don't expect any in this test. + var haveNewPage = await SpecialPowers.spawn(w, [token], + currentToken => this.content.token != currentToken && + this.content.location.href != "about:blank"); + + if (haveNewPage) { + ++token; + assignToken(token); + + // In this test, error pages are non-same-origin with us, and non-error + // pages are same-origin. + let haveErrorPage = false; + try { + win.document.title; + } catch (ex) { + haveErrorPage = true; + } + return haveErrorPage; + } + } catch (e) { + // Something went wrong; just keep waiting. + } + + await delay(100); + } +} + +async function windowLoaded() { + // The code under here should only be run once + // The test popup window workingURL was already opened + if (isWindowLoaded) + return; + isWindowLoaded = true; + + assignToken(token); + + /* 2. We have successfully loaded a page, now go to a faulty URL */ + // XXX The test fails when we change the location synchronously + window.setTimeout(function() { + w.location.href = faultyURL; + }, 0); + + ok(await pollForPage(w), "Waiting for error page succeeded"); + /* 3. now, while we are on the error page, navigate back */ + try { + // We need the SpecialPowers bit, because this is a cross-origin window + // and we normally can't touch .history on those. + await SpecialPowers.spawn(w, [], () => this.content.history.back()); + } catch (ex) { + ok(false, "w.history.back() threw " + ex); + } + + ok(!await pollForPage(w), "Waiting for original page succeeded"); + /* 4-finish, check we are back at the original page */ + is(await SpecialPowers.spawn(w, [], () => this.content.location.href), + workingURL, + "Is on the previous page"); + w.close(); + SimpleTest.finish(); +} + +function startTest() { + /* 1. load a URL that leads to an error page */ + w = window.open(workingURL); +} + +</script> +</head> +<body onload="startTest();"> +</body> +</html> diff --git a/docshell/test/mochitest/test_bug530396.html b/docshell/test/mochitest/test_bug530396.html new file mode 100644 index 0000000000..fa3ddc6db6 --- /dev/null +++ b/docshell/test/mochitest/test_bug530396.html @@ -0,0 +1,56 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=530396 +--> +<head> + <title>Test for Bug 530396</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="/tests/SimpleTest/EventUtils.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=530396">Mozilla Bug 530396</a> + +<p> + +<iframe id="testFrame" src="http://mochi.test:8888/tests/docshell/test/mochitest/bug530396-subframe.html"></iframe> + +<pre id="test"> +<script class="testbody" type="text/javascript"> + +// NOTE: If we ever make subframes do bfcache stuff, this test will need to be +// modified accordingly! It assumes that subframes do NOT get bfcached. +var onloadCount = 0; + +var step = 0; + +var gTestFrame = document.getElementById("testFrame"); + +SimpleTest.waitForExplicitFinish(); +SimpleTest.requestFlakyTimeout("untriaged"); +addLoadEvent(doNextStep); + +function doNextStep() { + ++step; + switch (step) { + case 1: + is(onloadCount, 1, "Loaded initial page"); + sendMouseEvent({type: "click"}, "target2", gTestFrame.contentWindow); + window.setTimeout(doNextStep, 1000); + break; + + case 2: + is(onloadCount, 1, "opener must be null"); + sendMouseEvent({type: "click"}, "target1", gTestFrame.contentWindow); + break; + + case 3: + is(onloadCount, 2, "don't send referrer with rel=referrer"); + SimpleTest.finish(); + break; + } +} +</script> +</pre> +</html> diff --git a/docshell/test/mochitest/test_bug540462.html b/docshell/test/mochitest/test_bug540462.html new file mode 100644 index 0000000000..e0a0861aaf --- /dev/null +++ b/docshell/test/mochitest/test_bug540462.html @@ -0,0 +1,44 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=540462 +--> +<head> + <title>Test for Bug 540462</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body onload="runTest()"> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=540462">Mozilla Bug 540462</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 540462 */ + +var win; +function runTest() { + win = window.open("file_bug540462.html", "", "width=100,height=100"); +} + +var dwlCount = 0; +var originalURL; +function documentWriteLoad() { + if (++dwlCount == 1) { + originalURL = win.document.body.firstChild.href; + } else if (dwlCount == 2) { + is(win.document.body.firstChild.href, originalURL, "Wrong href!"); + win.close(); + SimpleTest.finish(); + } +} + +SimpleTest.waitForExplicitFinish(); + +</script> +</pre> +</body> +</html> diff --git a/docshell/test/mochitest/test_bug551225.html b/docshell/test/mochitest/test_bug551225.html new file mode 100644 index 0000000000..b2862fcad8 --- /dev/null +++ b/docshell/test/mochitest/test_bug551225.html @@ -0,0 +1,32 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=551225 +--> +<head> + <title>Test for Bug 551225</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="/tests/SimpleTest/EventUtils.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=551225">Mozilla Bug 551225</a> + +<script type="application/javascript"> + +/** Test for Bug 551225 */ + +var obj = { + a: new Date("1/1/2000"), + b: /^foo$/, + c: "bar", +}; + +history.replaceState(obj, "", ""); +is(history.state.a.toString(), new Date("1/1/2000").toString(), "Date object."); +is(history.state.b.toString(), "/^foo$/", "Regex"); +is(history.state.c, "bar", "Other state"); + +</script> +</body> +</html> diff --git a/docshell/test/mochitest/test_bug570341.html b/docshell/test/mochitest/test_bug570341.html new file mode 100644 index 0000000000..363f985407 --- /dev/null +++ b/docshell/test/mochitest/test_bug570341.html @@ -0,0 +1,142 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=570341 +--> +<head> + <title>Test for Bug 570341</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +<script> + var start = Date.now(); + var moments = {}; + + var unload = 0; + var wasEnabled = true; + + function collectMoments() { + var win = frames[0]; + var timing = (win.performance && win.performance.timing) || {}; + for (let p in timing) { + moments[p] = timing[p]; + } + for (let p in win) { + if (p.substring(0, 9) == "_testing_") { + moments[p.substring(9)] = win[p]; + } + } + moments.evt_unload = unload; + return moments; + } + + function showSequence(node) { + while (node.firstChild) { + node.firstChild.remove(); + } + var sequence = []; + for (var p in moments) { + sequence.push(p); + } + sequence.sort(function(a, b) { + return moments[a] - moments[b]; + }); + var table = document.createElement("table"); + node.appendChild(table); + var row = document.createElement("tr"); + table.appendChild(row); + var cell = document.createElement("td"); + row.appendChild(cell); + cell.appendChild(document.createTextNode("start")); + cell = document.createElement("td"); + row.appendChild(cell); + cell.appendChild(document.createTextNode(start)); + for (var i = 0; i < sequence.length; ++i) { + var prop = sequence[i]; + row = document.createElement("tr"); + table.appendChild(row); + cell = document.createElement("td"); + row.appendChild(cell); + cell.appendChild(document.createTextNode(prop)); + cell = document.createElement("td"); + row.appendChild(cell); + cell.appendChild(document.createTextNode(moments[prop])); + } + } + + function checkValues() { + var win = frames[0]; + ok(win.performance, + "window.performance is missing or not accessible for frame"); + ok(!win.performance || win.performance.timing, + "window.performance.timing is missing or not accessible for frame"); + collectMoments(); + + var sequences = [ + ["navigationStart", "unloadEventStart", "unloadEventEnd"], + ["navigationStart", "fetchStart", "domainLookupStart", "domainLookupEnd", + "connectStart", "connectEnd", "requestStart", "responseStart", "responseEnd"], + ["responseStart", "domLoading", "domInteractive", "domComplete"], + ["domContentLoadedEventStart", "domContentLoadedEventEnd", + "loadEventStart", "loadEventEnd"], + ]; + + for (var i = 0; i < sequences.length; ++i) { + var seq = sequences[i]; + for (var j = 0; j < seq.length; ++j) { + var prop = seq[j]; + if (j > 0) { + var prevProp = seq[j - 1]; + ok(moments[prevProp] <= moments[prop], + ["Expected ", prevProp, " to happen before ", prop, + ", got ", prevProp, " = ", moments[prevProp], + ", ", prop, " = ", moments[prop]].join("")); + } + } + } + + SimpleTest.finish(); + } + +window.onload = function() { + var win = frames[0]; + win.addEventListener("unload", function() { + unload = Date.now(); + }, true); + var seenLoad = 0; + win.addEventListener("load", function() { + seenLoad = Date.now(); + }, true); + frames[0].location = "bug570341_recordevents.html"; + var interval = setInterval(function() { + // time constants here are arbitrary, chosen to allow the test to pass + var stopPolling = (win.performance && win.performance.loadEventEnd) || + (seenLoad && Date.now() >= seenLoad + 3000) || + Date.now() >= start + 30000; + if (stopPolling) { + clearInterval(interval); + checkValues(); + } else if (win._testing_evt_load) { + seenLoad = Date.now(); + } + }, 100); +}; +</script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=570341">Mozilla Bug 570341</a> +<div id="frames"> +<iframe name="child0" src="navigation/blank.html"></iframe> +</div> +<button type="button" onclick="showSequence(document.getElementById('display'))"> + Show Events</button> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> +SimpleTest.waitForExplicitFinish(); +</script> +</pre> +</body> +</html> diff --git a/docshell/test/mochitest/test_bug580069.html b/docshell/test/mochitest/test_bug580069.html new file mode 100644 index 0000000000..bb0a3bc823 --- /dev/null +++ b/docshell/test/mochitest/test_bug580069.html @@ -0,0 +1,58 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=580069 +--> +<head> + <title>Test for Bug 580069</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="/tests/SimpleTest/EventUtils.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=580069">Mozilla Bug 580069</a> + +<script type="application/javascript"> + +add_task(async function() { + let iframe = document.createElement("iframe"); + iframe.setAttribute("src", "file_bug580069_1.html"); + + // Insert the initial <iframe> document, and wait for page1Load to be called + // after it loads. + document.body.appendChild(iframe); + await new Promise(resolve => { + window.page1Load = resolve; + }); + let iframeCw = iframe.contentWindow; + + info("iframe's location is: " + iframeCw.location + "\n"); + + // Submit the forum and wait for the initial page load using a POST load. + iframeCw.document.getElementById("form").submit(); + let method1 = await new Promise(resolve => { + window.page2Load = resolve; + }); + info("iframe's location is: " + iframeCw.location + ", method is " + method1 + "\n"); + is(method1, "POST", "Method for first load should be POST."); + + // Push a new state, and refresh the page. This refresh shouldn't pop up the + // "are you sure you want to refresh a page with POST data?" dialog. If it + // does, this test will hang and fail, and we'll see 'Refreshing iframe...' at + // the end of the test log. + iframeCw.history.replaceState("", "", "?replaced"); + + info("Refreshing iframe...\n"); + iframeCw.location.reload(); + let method2 = await new Promise(resolve => { + window.page2Load = resolve; + }); + + info("iframe's location is: " + iframeCw.location + ", method is " + method2 + "\n"); + is(method2, "GET", "Method for second load should be GET."); + is(iframeCw.location.search, "?replaced", "Wrong search on iframe after refresh."); +}); +</script> + +</body> +</html> diff --git a/docshell/test/mochitest/test_bug590573.html b/docshell/test/mochitest/test_bug590573.html new file mode 100644 index 0000000000..83554a7a66 --- /dev/null +++ b/docshell/test/mochitest/test_bug590573.html @@ -0,0 +1,198 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=590573 +--> +<head> + <title>Test for Bug 590573</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="/tests/SimpleTest/EventUtils.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=590573">Mozilla Bug 590573</a> + +<script type='application/javascript'> +SimpleTest.waitForExplicitFinish(); + +// Listen to the first callback, since this indicates that the page loaded. +var page1LoadCallbackEnabled = true; +function page1Load() { + if (page1LoadCallbackEnabled) { + page1LoadCallbackEnabled = false; + dump("Got page1 load.\n"); + pageLoad(); + } else { + dump("Ignoring page1 load.\n"); + } +} + +var page1PageShowCallbackEnabled = false; +function page1PageShow() { + if (page1PageShowCallbackEnabled) { + page1PageShowCallbackEnabled = false; + dump("Got page1 pageshow.\n"); + pageLoad(); + } else { + dump("Ignoring page1 pageshow.\n"); + } +} + +var page2LoadCallbackEnabled = false; +function page2Load() { + if (page2LoadCallbackEnabled) { + page2LoadCallbackEnabled = false; + dump("Got page2 popstate.\n"); + pageLoad(); + } else { + dump("Ignoring page2 popstate.\n"); + } +} + +var page2PopstateCallbackEnabled = false; +function page2Popstate() { + if (page2PopstateCallbackEnabled) { + page2PopstateCallbackEnabled = false; + dump("Got page2 popstate.\n"); + pageLoad(); + } else { + dump("Ignoring page2 popstate.\n"); + } +} + +var page2PageShowCallbackEnabled = false; +function page2PageShow() { + if (page2PageShowCallbackEnabled) { + page2PageShowCallbackEnabled = false; + dump("Got page2 pageshow.\n"); + pageLoad(); + } else { + dump("Ignoring page2 pageshow.\n"); + } +} + +var popup = window.open("file_bug590573_1.html"); + +var gTestContinuation = null; +var loads = 0; +function pageLoad() { + loads++; + dump("pageLoad(loads=" + loads + ", page location=" + popup.location + ")\n"); + + if (!gTestContinuation) { + gTestContinuation = testBody(); + } + var ret = gTestContinuation.next(); + if (ret.done) { + SimpleTest.finish(); + } +} + +function continueAsync() { + popup.addEventListener("popstate", function() { + popup.requestAnimationFrame(function() { gTestContinuation.next(); }); + }, + {once: true}); +} + +function* testBody() { + is(popup.scrollY, 0, "test 1"); + popup.scroll(0, 100); + + popup.history.pushState("", "", "?pushed"); + is(Math.round(popup.scrollY), 100, "test 2"); + popup.scroll(0, 200); // set state-2's position to 200 + + popup.history.back(); + continueAsync(); + yield; + is(Math.round(popup.scrollY), 100, "test 3"); + popup.scroll(0, 150); // set original page's position to 150 + + popup.history.forward(); + continueAsync(); + yield; + is(Math.round(popup.scrollY), 200, "test 4"); + + popup.history.back(); + continueAsync(); + yield; + is(Math.round(popup.scrollY), 150, "test 5"); + + popup.history.forward(); + continueAsync(); + yield; + is(Math.round(popup.scrollY), 200, "test 6"); + + // At this point, the history looks like: + // PATH POSITION + // file_bug590573_1.html 150 <-- oldest + // file_bug590573_1.html?pushed 200 <-- newest, current + + // Now test that the scroll position is persisted when we have real + // navigations involved. First, we need to spin the event loop so that the + // navigation doesn't replace our current history entry. + + setTimeout(pageLoad, 0); + yield; + + page2LoadCallbackEnabled = true; + popup.location = "file_bug590573_2.html"; + yield; + + ok(popup.location.href.match("file_bug590573_2.html$"), + "Location was " + popup.location + + " but should end with file_bug590573_2.html"); + + is(popup.scrollY, 0, "test 7"); + popup.scroll(0, 300); + + // We need to spin the event loop again before we go back, otherwise the + // scroll positions don't get updated properly. + setTimeout(pageLoad, 0); + yield; + + page1PageShowCallbackEnabled = true; + popup.history.back(); + yield; + + // Spin the event loop again so that we get the right scroll positions. + setTimeout(pageLoad, 0); + yield; + + is(popup.location.search, "?pushed"); + ok(popup.document.getElementById("div1"), "page should have div1."); + + is(Math.round(popup.scrollY), 200, "test 8"); + + popup.history.back(); + continueAsync(); + yield; + is(Math.round(popup.scrollY), 150, "test 9"); + popup.history.forward(); + continueAsync(); + yield; + + is(Math.round(popup.scrollY), 200, "test 10"); + + // Spin one last time... + setTimeout(pageLoad, 0); + yield; + + page2PageShowCallbackEnabled = true; + popup.history.forward(); + yield; + + // Bug 821821, on Android tegras we get 299 instead of 300 sometimes + const scrollY = Math.floor(popup.scrollY); + if (scrollY >= 299 && scrollY <= 300) { + is(1, 1, "test 11"); + } else { + is(1, 0, "test 11, got " + popup.scrollY + " for popup.scrollY instead of 299|300"); + } + popup.close(); +} +</script> + +</body> +</html> diff --git a/docshell/test/mochitest/test_bug598895.html b/docshell/test/mochitest/test_bug598895.html new file mode 100644 index 0000000000..e0b17e2663 --- /dev/null +++ b/docshell/test/mochitest/test_bug598895.html @@ -0,0 +1,52 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=598895 +--> +<head> + <title>Test for Bug 598895</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="/tests/SimpleTest/WindowSnapshot.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=598895">Mozilla Bug 598895</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 598895 */ +SimpleTest.waitForExplicitFinish(); + +addLoadEvent(function() { +var win1 = window.open(); +win1.document.body.textContent = "Should show"; + +var windowsLoaded = 0; + +window.onmessage = async function(ev) { + is(ev.data, "loaded", "Message should be 'loaded'"); + if (++windowsLoaded == 2) { + var one = await snapshotWindow(win1); + var two = await snapshotWindow(win2); + var three = await snapshotWindow(win3); + win1.close(); + win2.close(); + win3.close(); + ok(compareSnapshots(one, two, true)[0], "Popups should look identical"); + ok(compareSnapshots(one, three, false)[0], "Popups should not look identical"); + + SimpleTest.finish(); + } +}; + +var win2 = window.open("file_bug598895_1.html"); +var win3 = window.open("file_bug598895_2.html"); +}); +</script> +</pre> +</body> +</html> diff --git a/docshell/test/mochitest/test_bug634834.html b/docshell/test/mochitest/test_bug634834.html new file mode 100644 index 0000000000..e1f87de000 --- /dev/null +++ b/docshell/test/mochitest/test_bug634834.html @@ -0,0 +1,52 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=634834 +--> +<head> + <title>Test for Bug 634834</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="/tests/SimpleTest/EventUtils.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=634834">Mozilla Bug 634834</a> + +<script type='application/javascript'> +SimpleTest.waitForExplicitFinish(); + +function iframe_loaded() { + var loadedAfterPushstate = false; + $("iframe").onload = function() { + loadedAfterPushstate = true; + }; + + var obj = { name: "name" }; + obj.__defineGetter__("a", function() { + // eslint-disable-next-line @microsoft/sdl/no-insecure-url + $("iframe").contentWindow.location = "http://example.com"; + + // Wait until we've loaded example.com. + do { + var r = new XMLHttpRequest(); + r.open("GET", location.href, false); + r.overrideMimeType("text/plain"); + try { r.send(null); } catch (e) {} + } while (!loadedAfterPushstate); + }); + + try { + $("iframe").contentWindow.history.pushState(obj, ""); + ok(false, "pushState should throw exception."); + } catch (e) { + ok(true, "pushState threw an exception."); + } + SimpleTest.finish(); +} + +</script> + +<iframe id='iframe' src='file_bug634834.html' onload='iframe_loaded()'></iframe> + +</body> +</html> diff --git a/docshell/test/mochitest/test_bug637644.html b/docshell/test/mochitest/test_bug637644.html new file mode 100644 index 0000000000..1e5f4380b4 --- /dev/null +++ b/docshell/test/mochitest/test_bug637644.html @@ -0,0 +1,52 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=637644 +--> +<head> + <title>Test for Bug 637644</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="/tests/SimpleTest/WindowSnapshot.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=637644">Mozilla Bug 637644</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 637644 */ +SimpleTest.waitForExplicitFinish(); + +addLoadEvent(function() { +var win1 = window.open("", "", "height=500,width=500"); +win1.document.body.textContent = "Should show"; + +var windowsLoaded = 0; + +window.onmessage = async function(ev) { + is(ev.data, "loaded", "Message should be 'loaded'"); + if (++windowsLoaded == 2) { + var one = await snapshotWindow(win1); + var two = await snapshotWindow(win2); + var three = await snapshotWindow(win3); + win1.close(); + win2.close(); + win3.close(); + ok(compareSnapshots(one, two, true)[0], "Popups should look identical"); + ok(compareSnapshots(one, three, false)[0], "Popups should not look identical"); + + SimpleTest.finish(); + } +}; + +var win2 = window.open("file_bug637644_1.html", "", "height=500,width=500"); +var win3 = window.open("file_bug637644_2.html", "", "height=500,width=500"); +}); +</script> +</pre> +</body> +</html> diff --git a/docshell/test/mochitest/test_bug640387_1.html b/docshell/test/mochitest/test_bug640387_1.html new file mode 100644 index 0000000000..b8aab054a1 --- /dev/null +++ b/docshell/test/mochitest/test_bug640387_1.html @@ -0,0 +1,107 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=640387 +--> +<head> + <title>Test for Bug 640387</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="/tests/SimpleTest/EventUtils.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=640387">Mozilla Bug 640387</a> + +<script type='application/javascript'> +SimpleTest.waitForExplicitFinish(); + +function* test() { + /* Spin the event loop so we get out of the onload handler. */ + SimpleTest.executeSoon(function() { gGen.next(); }); + yield undefined; + + popup.history.pushState("", "", "#hash1"); + popup.history.pushState("", "", "#hash2"); + + // Now the history looks like: + // file_bug640387.html + // file_bug640387.html#hash1 + // file_bug640387.html#hash2 <-- current + + // Going back should trigger a hashchange, which will wake us up from the + // yield. + popup.history.back(); + yield undefined; + ok(true, "Got first hashchange."); + + // Going back should wake us up again. + popup.history.back(); + yield undefined; + ok(true, "Got second hashchange."); + + // Now the history looks like: + // file_bug640387.html <-- current + // file_bug640387.html#hash1 + // file_bug640387.html#hash2 + + // Going forward should trigger a hashchange. + popup.history.forward(); + yield undefined; + ok(true, "Got third hashchange."); + + // Now modify the history so it looks like: + // file_bug640387.html + // file_bug640387.html#hash1 + // file_bug640387.html#hash1 <-- current + popup.history.pushState("", "", "#hash1"); + + // Now when we go back, we should not get a hashchange. Instead, wait for a + // popstate. We need to asynchronously go back because popstate is fired + // sync. + gHashchangeExpected = false; + gCallbackOnPopstate = true; + SimpleTest.executeSoon(function() { popup.history.back(); }); + yield undefined; + ok(true, "Got popstate."); + gCallbackOnPopstate = false; + + // Spin the event loop so hashchange has a chance to fire, if it's going to. + SimpleTest.executeSoon(function() { gGen.next(); }); + yield undefined; + + popup.close(); + SimpleTest.finish(); +} + +var gGen = null; +function childLoad() { + gGen = test(); + gGen.next(); +} + +var gHashchangeExpected = true; +function childHashchange() { + if (gHashchangeExpected) { + gGen.next(); + } else { + ok(false, "Got hashchange when we weren't expecting one."); + } +} + +var gCallbackOnPopstate = false; +function childPopstate() { + if (gCallbackOnPopstate) { + gGen.next(); + } +} + +/* We need to run this test in a popup, because navigating an iframe + * back/forwards tends to cause intermittent orange. */ +var popup = window.open("file_bug640387.html"); + +/* Control now flows up to childLoad(), called once the popup loads. */ + +</script> + +</body> +</html> diff --git a/docshell/test/mochitest/test_bug640387_2.html b/docshell/test/mochitest/test_bug640387_2.html new file mode 100644 index 0000000000..c248a64836 --- /dev/null +++ b/docshell/test/mochitest/test_bug640387_2.html @@ -0,0 +1,89 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=640387 +--> +<head> + <title>Test for Bug 640387</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="/tests/SimpleTest/EventUtils.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=640387">Mozilla Bug 640387</a> + +<!-- Test that, when going from + + http://example.com/#foo + +to + + http://example.com/ + +via a non-history load, we do a true load, rather than a scroll. --> + +<script type='application/javascript'> +SimpleTest.waitForExplicitFinish(); + +var callbackOnLoad = false; +function childLoad() { + if (callbackOnLoad) { + callbackOnLoad = false; + gGen.next(); + } +} + +var errorOnHashchange = false; +var callbackOnHashchange = false; +function childHashchange() { + if (errorOnHashchange) { + ok(false, "Got unexpected hashchange."); + } + if (callbackOnHashchange) { + callbackOnHashchange = false; + gGen.next(); + } +} + +function* run_test() { + var iframe = $("iframe").contentWindow; + + ok(true, "Got first load"); + + // Spin the event loop so we exit the onload handler. + SimpleTest.executeSoon(function() { gGen.next(); }); + yield undefined; + + let origLocation = iframe.location + ""; + callbackOnHashchange = true; + iframe.location.hash = "#1"; + // Wait for a hashchange event. + yield undefined; + + ok(true, "Got hashchange."); + + iframe.location = origLocation; + // This should produce a load event and *not* a hashchange, because the + // result of the load is a different document than we had previously. + callbackOnLoad = true; + errorOnHashchange = true; + yield undefined; + + ok(true, "Got final load."); + + // Spin the event loop to give hashchange a chance to fire, if it's going to. + SimpleTest.executeSoon(function() { gGen.next(); }); + yield undefined; + + SimpleTest.finish(); +} + +callbackOnLoad = true; +var gGen = run_test(); + +</script> + +<iframe id='iframe' src='file_bug640387.html'></iframe> + +</body> +</html> diff --git a/docshell/test/mochitest/test_bug653741.html b/docshell/test/mochitest/test_bug653741.html new file mode 100644 index 0000000000..33ba7077e4 --- /dev/null +++ b/docshell/test/mochitest/test_bug653741.html @@ -0,0 +1,49 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=653741 +--> +<head> + <title>Test for Bug 653741</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="/tests/SimpleTest/WindowSnapshot.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=653741">Mozilla Bug 653741</a> + +<script type="application/javascript"> + +/** Test for Bug 653741 */ +SimpleTest.waitForExplicitFinish(); + +function childLoad() { + // Spin the event loop so we leave the onload handler. + SimpleTest.executeSoon(childLoad2); +} + +function childLoad2() { + let cw = $("iframe").contentWindow; + + // Save the Y offset. For sanity's sake, make sure it's not 0, because we + // should be at the bottom of the page! + let origYOffset = Math.round(cw.pageYOffset); + ok(origYOffset != 0, "Original Y offset is not 0."); + + // Scroll the iframe to the top, then navigate to #bottom again. + cw.scrollTo(0, 0); + + // Our current location is #bottom, so this should scroll us down to the + // bottom again. + cw.location = cw.location + ""; + + is(Math.round(cw.pageYOffset), origYOffset, "Correct offset after reloading page."); + SimpleTest.finish(); +} + +</script> + +<iframe height='100px' id='iframe' src='file_bug653741.html#bottom'></iframe> + +</body> +</html> diff --git a/docshell/test/mochitest/test_bug660404.html b/docshell/test/mochitest/test_bug660404.html new file mode 100644 index 0000000000..94e3f67aa1 --- /dev/null +++ b/docshell/test/mochitest/test_bug660404.html @@ -0,0 +1,76 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=660404 +--> +<head> + <title>Test for Bug 660404</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=660404">Mozilla Bug 660404</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 660404 */ +SimpleTest.waitForExplicitFinish(); + +var textContent = +` + var bc = new BroadcastChannel("bug660404_multipart"); + bc.postMessage({command: "finishTest", + textContent: window.document.documentElement.textContent, + innerHTML: window.document.documentElement.innerHTML + }); + bc.close(); + window.close(); +`; +var innerHTML = +`<head><script> + var bc = new BroadcastChannel("bug660404_multipart"); + bc.postMessage({command: "finishTest", + textContent: window.document.documentElement.textContent, + innerHTML: window.document.documentElement.innerHTML + }); + bc.close(); + window.close(); +</` +// eslint-disable-next-line no-useless-concat ++ `script></head>` +; +var bc_multipart = new BroadcastChannel("bug660404_multipart"); +bc_multipart.onmessage = (msgEvent) => { + var msg = msgEvent.data; + var command = msg.command; + if (command == "finishTest") { + is(msg.textContent, textContent); + is(msg.innerHTML, innerHTML); + bc_multipart.close(); + SimpleTest.finish(); + } +} +var bc = new BroadcastChannel("bug660404"); +bc.onmessage = (msgEvent) => { + var msg = msgEvent.data; + var command = msg.command; + if (command == "pagehide") { + is(msg.persisted, true, "Should be bfcached when navigating to multipart"); + bc.close(); + } +} + +// If Fission is disabled, the pref is no-op. +SpecialPowers.pushPrefEnv({set: [["fission.bfcacheInParent", true]]}, () => { + // Have to open a new window, since there's no bfcache in subframes + window.open("file_bug660404-1.html", "", "noopener"); +}); + +</script> +</pre> +</body> +</html> diff --git a/docshell/test/mochitest/test_bug662170.html b/docshell/test/mochitest/test_bug662170.html new file mode 100644 index 0000000000..d25ee3bd0f --- /dev/null +++ b/docshell/test/mochitest/test_bug662170.html @@ -0,0 +1,51 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=662170 +--> +<head> + <title>Test for Bug 662170</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="/tests/SimpleTest/WindowSnapshot.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=662170">Mozilla Bug 662170</a> + +<script type="application/javascript"> + +/** Test for Bug 662170 */ +SimpleTest.waitForExplicitFinish(); + +function childLoad() { + // Spin the event loop so we leave the onload handler. + SimpleTest.executeSoon(childLoad2); +} + +function childLoad2() { + let cw = $("iframe").contentWindow; + + // When we initially load the page, we should be at the top. + is(cw.pageYOffset, 0, "Initial Y offset should be 0."); + + // Scroll the iframe to the bottom. + cw.scrollTo(0, 300); + + // Did we actually scroll somewhere? + isnot(Math.round(cw.pageYOffset), 0, "Y offset should be non-zero after scrolling."); + + // Now load file_bug662170.html#, which should take us to the top of the + // page. + cw.location = cw.location + "#"; + + is(cw.pageYOffset, 0, "Correct Y offset after loading #."); + SimpleTest.finish(); +} + +</script> + +<!-- When the iframe loads, it calls childLoad(). --> +<iframe height='100px' id='iframe' src='file_bug662170.html'></iframe> + +</body> +</html> diff --git a/docshell/test/mochitest/test_bug668513.html b/docshell/test/mochitest/test_bug668513.html new file mode 100644 index 0000000000..09c848b6c1 --- /dev/null +++ b/docshell/test/mochitest/test_bug668513.html @@ -0,0 +1,28 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=668513 +--> +<head> + <title>Test for Bug 668513</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=668513">Mozilla Bug 668513</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> +if (navigator.platform.startsWith("Linux")) { + SimpleTest.expectAssertions(0, 1); +} + +SimpleTest.waitForExplicitFinish(); +window.open("file_bug668513.html"); +</script> +</pre> +</body> +</html> diff --git a/docshell/test/mochitest/test_bug669671.html b/docshell/test/mochitest/test_bug669671.html new file mode 100644 index 0000000000..4470cd6682 --- /dev/null +++ b/docshell/test/mochitest/test_bug669671.html @@ -0,0 +1,145 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=669671 +--> +<head> + <title>Test for Bug 669671</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=669671">Mozilla Bug 669671</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** + * Test for Bug 669671. + * + * This is a bit complicated. We have a script, file_bug669671.sjs, which counts + * how many times it's loaded and returns that count in the body of an HTML + * document. For brevity, call this page X. + * + * X is sent with Cache-Control: max-age=0 and can't be bfcached (it has an + * onunload handler). Our test does the following in a popup: + * + * 1) Load X?pushed, to prime the cache. + * 2) Navigate to X. + * 3) Call pushState and navigate from X to X?pushed. + * 4) Navigate to X?navigated. + * 5) Go back (to X?pushed). + * + * We do all this work so we can check that in step 5, we fetch X?pushed from + * the network -- we shouldn't use our cached copy, because of the + * cache-control header X sends. + * + * Then we go back and repeat the whole process but call history.replaceState + * instead of pushState. And for good measure, we test once more, this time + * modifying only the hash of the URI using replaceState. In this case, we + * should* load from the cache. + * + */ +SimpleTest.requestLongerTimeout(2); +SimpleTest.waitForExplicitFinish(); + +function onChildLoad() { + SimpleTest.executeSoon(function() { gGen.next(); }); +} + +var _loadCount = 0; +function checkPopupLoadCount() { + is(popup.document.body.innerHTML, _loadCount + "", "Load count"); + + // We normally want to increment _loadCount here. But if the test fails + // because we didn't do a load we should have, let's not cause a cascade of + // failures by incrementing _loadCount. + var origCount = _loadCount; + if (popup.document.body.innerHTML >= _loadCount + "") + _loadCount++; + return origCount; +} + +function* test() { + // Step 0 - Make sure the count is reset to 0 in case of reload + popup.location = "file_bug669671.sjs?countreset"; + yield; + is(popup.document.body.innerHTML, "0", + "Load count should be reset to 0"); + + // Step 1 - The popup's body counts how many times we've requested the + // resource. This is the first time we've requested it, so it should be '0'. + checkPopupLoadCount(); + + // Step 2 - We'll get another onChildLoad when this finishes. + popup.location = "file_bug669671.sjs"; + yield undefined; + + // Step 3 - Call pushState and change the URI back to ?pushed. + checkPopupLoadCount(); + popup.history.pushState("", "", "?pushed"); + + // Step 4 - Navigate away. This should trigger another onChildLoad. + popup.location = "file_bug669671.sjs?navigated-1"; + yield undefined; + + // Step 5 - Go back. This should result in another onload (because the file is + // not in bfcache) and should be the fourth time we've requested the sjs file. + checkPopupLoadCount(); + popup.history.back(); + yield undefined; + + // This is the check which was failing before we fixed the bug. + checkPopupLoadCount(); + + popup.close(); + + // Do the whole thing again, but with replaceState. + popup = window.open("file_bug669671.sjs?replaced"); + yield undefined; + checkPopupLoadCount(); + popup.location = "file_bug669671.sjs"; + yield undefined; + checkPopupLoadCount(); + popup.history.replaceState("", "", "?replaced"); + popup.location = "file_bug669671.sjs?navigated-2"; + yield undefined; + checkPopupLoadCount(); + popup.history.back(); + yield undefined; + checkPopupLoadCount(); + popup.close(); + + // Once more, with feeling. Notice that we don't have to prime the cache + // with an extra load here, because X and X#hash share the same cache entry. + popup = window.open("file_bug669671.sjs?hash-test"); + yield undefined; + var initialCount = checkPopupLoadCount(); + popup.history.replaceState("", "", "#hash"); + popup.location = "file_bug669671.sjs?navigated-3"; + yield undefined; + checkPopupLoadCount(); + popup.history.back(); + yield undefined; + is(popup.document.body.innerHTML, initialCount + "", + "Load count (should be cached)"); + popup.close(); + + SimpleTest.finish(); +} + +var gGen = test(); +var popup; + +// Disable RCWN to make cache behavior deterministic. +SpecialPowers.pushPrefEnv({set: [["network.http.rcwn.enabled", false]]}, () => { + // This will call into onChildLoad once it loads. + popup = window.open("file_bug669671.sjs?pushed"); +}); +</script> +</pre> +</body> +</html> diff --git a/docshell/test/mochitest/test_bug675587.html b/docshell/test/mochitest/test_bug675587.html new file mode 100644 index 0000000000..452bbc8058 --- /dev/null +++ b/docshell/test/mochitest/test_bug675587.html @@ -0,0 +1,33 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=675587 +--> +<head> + <title>Test for Bug 675587</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=675587">Mozilla Bug 675587</a> +<p id="display"> + <iframe src="file_bug675587.html#hash"></iframe> +</p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 675587 */ +SimpleTest.waitForExplicitFinish(); +addLoadEvent(function() { + ok(window.frames[0].location.href.endsWith("file_bug675587.html#"), + "Should have the right href"); + SimpleTest.finish(); +}); + +</script> +</pre> +</body> +</html> diff --git a/docshell/test/mochitest/test_bug680257.html b/docshell/test/mochitest/test_bug680257.html new file mode 100644 index 0000000000..4d5736ac0a --- /dev/null +++ b/docshell/test/mochitest/test_bug680257.html @@ -0,0 +1,76 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=680257 +--> +<head> + <title>Test for Bug 680257</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=680257">Mozilla Bug 680257</a> + +<script type="application/javascript"> + +SimpleTest.waitForExplicitFinish(); + +var popup = window.open("file_bug680257.html"); + +var gTestContinuation = null; +function continueAsync() { + popup.addEventListener("hashchange", + function(e) { gTestContinuation.next(); }, { once: true }); +} + +// The popup will call into popupLoaded() once it loads. +function popupLoaded() { + // runTests() needs to be called from outside popupLoaded's onload handler. + // Otherwise, the navigations we do in runTests won't create new SHEntries. + SimpleTest.executeSoon(function() { + if (!gTestContinuation) { + gTestContinuation = runTests(); + } + gTestContinuation.next(); + }); +} + +function* runTests() { + checkPopupLinkStyle(false, "Initial"); + + popup.location.hash = "a"; + continueAsync(); + yield; + checkPopupLinkStyle(true, "After setting hash"); + + popup.history.back(); + continueAsync(); + yield; + + checkPopupLinkStyle(false, "After going back"); + + popup.history.forward(); + continueAsync(); + yield; + checkPopupLinkStyle(true, "After going forward"); + + popup.close(); + SimpleTest.finish(); +} + +function checkPopupLinkStyle(isTarget, desc) { + var link = popup.document.getElementById("a"); + var style = popup.getComputedStyle(link); + var color = style.getPropertyValue("color"); + + // Color is red if isTarget, black otherwise. + if (isTarget) { + is(color, "rgb(255, 0, 0)", desc); + } else { + is(color, "rgb(0, 0, 0)", desc); + } +} + +</script> +</body> +</html> diff --git a/docshell/test/mochitest/test_bug691547.html b/docshell/test/mochitest/test_bug691547.html new file mode 100644 index 0000000000..706cd5013b --- /dev/null +++ b/docshell/test/mochitest/test_bug691547.html @@ -0,0 +1,59 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=691547 +--> +<head> + <title>Test for Bug 691547</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + var navStart = 0; + var beforeReload = 0; + function onContentLoad() { + var frame = frames[0]; + if (!navStart) { + // First time we perform navigation in subframe. The bug is that + // load in subframe causes timing.navigationStart to be recorded + // as if it was a start of the next navigation. + var innerFrame = frame.frames[0]; + navStart = frame.performance.timing.navigationStart; + innerFrame.location = "bug570341_recordevents.html"; + // Let's wait a bit so the difference is clear anough. + setTimeout(reload, 3000); + } else { + // Content reloaded, time to check. We are allowing a huge time slack, + // in case clock is imprecise. If we have a bug, the difference is + // expected to be about the timeout value set above. + var diff = frame.performance.timing.navigationStart - beforeReload; + ok(diff >= -200, + "navigationStart should be set after reload request. " + + "Measured difference: " + diff + " (should be positive)"); + SimpleTest.finish(); + } + } + function reload() { + var frame = frames[0]; + ok(navStart == frame.performance.timing.navigationStart, + "navigationStart should not change when frame loads."); + beforeReload = Date.now(); + frame.location.reload(); + } + </script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=570341">Mozilla Bug 570341</a> +<div id="frames"> +<iframe name="frame0" id="frame0" src="bug691547_frame.html" onload="onContentLoad()"></iframe> +</div> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> +SimpleTest.waitForExplicitFinish(); +SimpleTest.requestFlakyTimeout("untriaged"); +</script> +</pre> +</body> +</html> diff --git a/docshell/test/mochitest/test_bug694612.html b/docshell/test/mochitest/test_bug694612.html new file mode 100644 index 0000000000..8ea4331c43 --- /dev/null +++ b/docshell/test/mochitest/test_bug694612.html @@ -0,0 +1,34 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=694612 +--> +<head> + <title>Test for Bug 694612</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=694612">Mozilla Bug 694612</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> +/** Test for Bug 694612 */ +SimpleTest.waitForExplicitFinish(); + +window.addEventListener("message", receiveMessage); +function receiveMessage(event) { + ok(event.data.result, "should have performance API in an <object>"); + window.removeEventListener("message", receiveMessage); + SimpleTest.finish(); +} +</script> +<object type="text/html" + data="data:text/html,<script>parent.postMessage({result:performance!=null},'*');</script>"> +</object> +</pre> +</body> +</html> diff --git a/docshell/test/mochitest/test_bug703855.html b/docshell/test/mochitest/test_bug703855.html new file mode 100644 index 0000000000..4aa7b08800 --- /dev/null +++ b/docshell/test/mochitest/test_bug703855.html @@ -0,0 +1,79 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=703855 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 703855</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=703855">Mozilla Bug 703855</a> +<p id="display"></p> +<div id="content" style="display: none"> + <iframe id="f" src="file_bug703855.html"></iframe> +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 703855 */ + +SimpleTest.waitForExplicitFinish(); + +var timingAttributes = [ + "connectEnd", + "connectStart", + "domComplete", + "domContentLoadedEventEnd", + "domContentLoadedEventStart", + "domInteractive", + "domLoading", + "domainLookupEnd", + "domainLookupStart", + "fetchStart", + "loadEventEnd", + "loadEventStart", + "navigationStart", + "redirectEnd", + "redirectStart", + "requestStart", + "responseEnd", + "responseStart", + "unloadEventEnd", + "unloadEventStart", +]; +var originalTiming = {}; + +function runTest() { + var timing = $("f").contentWindow.performance.timing; + for (let i in timingAttributes) { + originalTiming[timingAttributes[i]] = timing[timingAttributes[i]]; + } + + var doc = $("f").contentDocument; + doc.open(); + doc.write("<!DOCTYPE html>"); + doc.close(); + + SimpleTest.executeSoon(function() { + var newTiming = $("f").contentWindow.performance.timing; + for (let i in timingAttributes) { + is(newTiming[timingAttributes[i]], originalTiming[timingAttributes[i]], + "document.open should not affect value of " + timingAttributes[i]); + } + SimpleTest.finish(); + }); +} + +addLoadEvent(function() { + SimpleTest.executeSoon(runTest); +}); + + + +</script> +</pre> +</body> +</html> diff --git a/docshell/test/mochitest/test_bug728939.html b/docshell/test/mochitest/test_bug728939.html new file mode 100644 index 0000000000..168184099a --- /dev/null +++ b/docshell/test/mochitest/test_bug728939.html @@ -0,0 +1,37 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=728939 +--> +<head> + <title>Test for Bug 728939</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=728939">Mozilla Bug 728939</a> + +<script type="application/javascript"> + +SimpleTest.waitForExplicitFinish(); + +// Called when the popup finishes loading. +function popupLoaded() { + popup.location.hash = "#foo"; + is(popup.document.URL, popup.location.href, "After hashchange."); + + popup.history.pushState("", "", "bar"); + is(popup.document.URL, popup.location.href, "After pushState."); + + popup.history.replaceState("", "", "baz"); + is(popup.document.URL, popup.location.href, "After replaceState."); + + popup.close(); + SimpleTest.finish(); +} + +var popup = window.open("file_bug728939.html"); + +</script> +</body> +</html> diff --git a/docshell/test/mochitest/test_bug797909.html b/docshell/test/mochitest/test_bug797909.html new file mode 100644 index 0000000000..15b7c27c0f --- /dev/null +++ b/docshell/test/mochitest/test_bug797909.html @@ -0,0 +1,66 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=797909 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 797909</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body onload="runTest()"> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=797909">Mozilla Bug 797909</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + /** Test for Bug 797909 */ + + SimpleTest.waitForExplicitFinish(); + + function runTest() { + var iframe = document.getElementById("ifr"); + try { + iframe.contentWindow.document; + ok(false, "Should have thrown an exception"); + } catch (ex) { + ok(true, "Got an exception"); + } + + iframe = document.createElement("iframe"); + // set sandbox attribute + iframe.sandbox = "allow-scripts"; + // and then insert into the doc + document.body.appendChild(iframe); + + try { + iframe.contentWindow.document; + ok(false, "Should have thrown an exception"); + } catch (ex) { + ok(true, "Got an exception"); + } + + iframe = document.createElement("iframe"); + // set sandbox attribute + iframe.sandbox = "allow-same-origin"; + // and then insert into the doc + document.body.appendChild(iframe); + + try { + iframe.contentWindow.document; + ok(true, "Shouldn't have thrown an exception"); + } catch (ex) { + ok(false, "Got an unexpected exception"); + } + + SimpleTest.finish(); + } + +</script> +</pre> +<iframe id="ifr" sandbox = "allow-scripts"></iframe> +</body> +</html> diff --git a/docshell/test/mochitest/test_close_onpagehide_by_history_back.html b/docshell/test/mochitest/test_close_onpagehide_by_history_back.html new file mode 100644 index 0000000000..33140502f7 --- /dev/null +++ b/docshell/test/mochitest/test_close_onpagehide_by_history_back.html @@ -0,0 +1,24 @@ +<!doctype html> +<title>Test for closing window in pagehide event callback caused by history.back()</title> +<script src="/tests/SimpleTest/SimpleTest.js"></script> +<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1432396">Mozilla Bug 1432396</a> +<p id="display"></p> +<script> +SimpleTest.waitForExplicitFinish(); + +const w = window.open("file_close_onpagehide1.html"); +window.addEventListener("message", e => { + is(e.data, "initial", "The initial page loaded"); + window.addEventListener("message", evt => { + is(evt.data, "second", "The second page loaded"); + w.onpagehide = () => { + w.close(); + info("try to close the popped up window in onpagehide"); + SimpleTest.finish(); + }; + w.history.back(); + }, { once: true }); + w.location = "file_close_onpagehide2.html"; +}, { once: true }); +</script> diff --git a/docshell/test/mochitest/test_close_onpagehide_by_window_close.html b/docshell/test/mochitest/test_close_onpagehide_by_window_close.html new file mode 100644 index 0000000000..8b094cdaa4 --- /dev/null +++ b/docshell/test/mochitest/test_close_onpagehide_by_window_close.html @@ -0,0 +1,20 @@ +<!doctype html> +<title>Test for closing window in pagehide event callback caused by window.close()</title> +<script src="/tests/SimpleTest/SimpleTest.js"></script> +<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1432396">Mozilla Bug 1432396</a> +<p id="display"></p> +<script> +SimpleTest.waitForExplicitFinish(); + +const w = window.open("file_close_onpagehide1.html"); +window.addEventListener("message", e => { + is(e.data, "initial", "The initial page loaded"); + w.onpagehide = () => { + w.close(); + info("try to close the popped up window in onpagehide"); + SimpleTest.finish(); + }; + w.close(); +}, { once: true }); +</script> diff --git a/docshell/test/mochitest/test_compressed_multipart.html b/docshell/test/mochitest/test_compressed_multipart.html new file mode 100644 index 0000000000..438819b643 --- /dev/null +++ b/docshell/test/mochitest/test_compressed_multipart.html @@ -0,0 +1,41 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1600211 + +Loads a document that is served as multipart/x-mixed-replace as well as gzip compressed. +Checks that we correctly decompress and display it (via running JS within the document to notify us). +--> +<head> + <title>Test for Bug 1600211</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1600211">Mozilla Bug 1600211</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 1600211 */ +SimpleTest.waitForExplicitFinish(); + +var w; + +function finishTest() { + is(w.document.documentElement.textContent, "opener.finishTest();"); + is(w.document.documentElement.innerHTML, "<head><script>opener.finishTest();</" + + "script></head>"); + w.close(); + SimpleTest.finish(); +} + +w = window.open("file_compressed_multipart"); + +</script> +</pre> +</body> +</html> diff --git a/docshell/test/mochitest/test_content_javascript_loads.html b/docshell/test/mochitest/test_content_javascript_loads.html new file mode 100644 index 0000000000..eabc1d314e --- /dev/null +++ b/docshell/test/mochitest/test_content_javascript_loads.html @@ -0,0 +1,163 @@ +<!DOCTYPE html> +<html> +<head> + <title>Test for Bug 1647519</title> + <meta charset="utf-8"> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="/tests/SimpleTest/EventUtils.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1647519">Mozilla Bug 1647519</a> + +<script type="application/javascript"> +"use strict"; + +function promiseMessage(source, filter = event => true) { + return new Promise(resolve => { + function listener(event) { + if (event.source == source && filter(event)) { + window.removeEventListener("message", listener); + resolve(event); + } + } + window.addEventListener("message", listener); + }); +} + +async function runTests(resourcePath) { + /* globals Assert, content */ + let doc = content.document; + + // Sends a message to the given target window and waits for a response a few + // times to (more or less) ensure that a `javascript:` load request has had + // time to succeed, if it were going to. + async function doSomeRoundTrips(target) { + for (let i = 0; i < 3; i++) { + // Note: The ping message needs to be sent from a script running in the + // content scope or there will be no source window for the reply to be + // sent to. + await content.wrappedJSObject.ping(target); + } + } + + function promiseEvent(target, name) { + return new Promise(resolve => { + target.addEventListener(name, resolve, { once: true }); + }); + } + + function createIframe(host, id) { + let iframe = doc.createElement("iframe"); + iframe.id = id; + iframe.name = id; + iframe.src = `https://${host}${resourcePath}file_content_javascript_loads_frame.html`; + doc.body.appendChild(iframe); + return promiseEvent(iframe, "load"); + } + + const ID_SAME_ORIGIN = "frame-same-origin"; + const ID_SAME_BASE_DOMAIN = "frame-same-base-domain"; + const ID_CROSS_BASE_DOMAIN = "frame-cross-base-domain"; + + await Promise.all([ + createIframe("example.com", ID_SAME_ORIGIN), + createIframe("test1.example.com", ID_SAME_BASE_DOMAIN), + createIframe("example.org", ID_CROSS_BASE_DOMAIN), + ]); + + let gotJSLoadFrom = null; + let pendingJSLoadID = null; + content.addEventListener("message", event => { + if ("javascriptLoadID" in event.data) { + Assert.equal( + event.data.javascriptLoadID, + pendingJSLoadID, + "Message from javascript: load should have the expected ID" + ); + Assert.equal( + gotJSLoadFrom, + null, + "Should not have seen a previous load message this cycle" + ); + gotJSLoadFrom = event.source.name; + } + }); + + async function watchForJSLoads(frameName, expected, task) { + let loadId = Math.random(); + + let jsURI = + "javascript:" + + encodeURI(`parent.postMessage({ javascriptLoadID: ${loadId} }, "*")`); + + pendingJSLoadID = loadId; + gotJSLoadFrom = null; + + await task(jsURI); + + await doSomeRoundTrips(content.wrappedJSObject[frameName]); + + if (expected) { + Assert.equal( + gotJSLoadFrom, + frameName, + `Should have seen javascript: URI loaded into ${frameName}` + ); + } else { + Assert.equal( + gotJSLoadFrom, + null, + "Should not have seen javascript: URI loaded" + ); + } + } + + let frames = [ + { name: ID_SAME_ORIGIN, expectLoad: true }, + { name: ID_SAME_BASE_DOMAIN, expectLoad: false }, + { name: ID_CROSS_BASE_DOMAIN, expectLoad: false }, + ]; + for (let { name, expectLoad } of frames) { + info(`Checking loads for frame "${name}". Expecting loads: ${expectLoad}`); + + info("Checking location setter"); + await watchForJSLoads(name, expectLoad, jsURI => { + // Note: We need to do this from the content scope since security checks + // depend on the JS caller scope. + content.wrappedJSObject.setFrameLocation(name, jsURI); + }); + + info("Checking targeted <a> load"); + await watchForJSLoads(name, expectLoad, jsURI => { + let a = doc.createElement("a"); + a.target = name; + a.href = jsURI; + doc.body.appendChild(a); + a.click(); + a.remove(); + }); + + info("Checking targeted window.open load"); + await watchForJSLoads(name, expectLoad, jsURI => { + content.wrappedJSObject.open(jsURI, name); + }); + } +} + +add_task(async function() { + const resourcePath = location.pathname.replace(/[^\/]+$/, ""); + + let win = window.open( + `https://example.com${resourcePath}file_content_javascript_loads_root.html` + ); + await promiseMessage(win, event => event.data == "ready"); + + await SpecialPowers.spawn(win, [resourcePath], runTests); + + win.close(); +}); +</script> + +</body> +</html> diff --git a/docshell/test/mochitest/test_double_submit.html b/docshell/test/mochitest/test_double_submit.html new file mode 100644 index 0000000000..640930718d --- /dev/null +++ b/docshell/test/mochitest/test_double_submit.html @@ -0,0 +1,98 @@ +<!doctype html> +<html> + <head> + <title>Test for Bug 1590762</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="/tests/SimpleTest/EventUtils.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + </head> + <body> + <iframe name="targetFrame" id="targetFrame"></iframe> + <form id="form" action="double_submit.sjs?delay=1000" method="POST" target="targetFrame"> + <input id="token" type="text" name="token" value=""> + <input id="button" type="submit"> + </form> + <script> + "use strict"; + + // eslint-disable-next-line @microsoft/sdl/no-insecure-url + const CROSS_ORIGIN_URI = "http://test1.example.com/tests/docshell/test/mochitest/ping.html"; + + function asyncClick(counts) { + let frame = document.createElement('iframe'); + frame.addEventListener( + 'load', () => frame.contentWindow.postMessage({command: "start"}, "*"), + { once:true }); + frame.src = "clicker.html"; + + addEventListener('message', ({source}) => { + if (source === frame.contentWindow) { + counts.click++; + synthesizeMouse(document.getElementById('button'), 5, 5, {}); + } + }, { once: true }); + + document.body.appendChild(frame); + return stop; + } + + function click(button) { + synthesizeMouse(button, 5, 5, {}); + } + + add_task(async function runTest() { + let frame = document.getElementById('targetFrame'); + await new Promise(resolve => { + addEventListener('message', resolve, {once: true}); + frame.src = CROSS_ORIGIN_URI; + }); + + let form = document.getElementById('form'); + let button = document.getElementById('button'); + + let token = document.getElementById('token'); + token.value = "first"; + + await new Promise((resolve, reject) => { + let counts = { click: 0, submit: 0 }; + form.addEventListener('submit', () => counts.submit++); + asyncClick(counts); + form.requestSubmit(button); + token.value = "bad"; + let steps = { + good: { + entered: false, + next: () => { steps.good.entered = true; resolve(); }, + assertion: () => { + ok(steps.first.entered && !steps.bad.entered, "good comes after first, but not bad") + } + }, + first: { + entered: false, + next: () => { steps.first.entered = true; token.value = "good"; click(button); }, + assertion: () => { + ok(!steps.good.entered && !steps.bad.entered, "first message is first") + is(counts.click, 1, "clicked"); + is(counts.submit, 2, "did submit"); + } + }, + bad: { + entered: false, + next: () => { reject(); }, + assertion: () => ok(false, "we got a bad message") + } + }; + addEventListener('message', ({source, data}) => { + if (source !== frame.contentWindow) { + return; + } + + let step = steps[data] || reject; + step.assertion(); + step.next(); + }) + }); + }); + </script> + </body> +</html> diff --git a/docshell/test/mochitest/test_forceinheritprincipal_overrule_owner.html b/docshell/test/mochitest/test_forceinheritprincipal_overrule_owner.html new file mode 100644 index 0000000000..70d610a677 --- /dev/null +++ b/docshell/test/mochitest/test_forceinheritprincipal_overrule_owner.html @@ -0,0 +1,57 @@ +<!DOCTYPE html> +<html> +<head> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> + +<script type="text/javascript"> + +var channel = SpecialPowers.wrap(window).docShell.currentDocumentChannel; +var loadInfo = channel.loadInfo; + +// 1) perform some sanity checks +var triggeringPrincipal = channel.loadInfo.triggeringPrincipal.asciiSpec; +var loadingPrincipal = channel.loadInfo.loadingPrincipal.asciiSpec; +var principalToInherit = channel.loadInfo.principalToInherit.asciiSpec; + +ok(triggeringPrincipal.startsWith("http://mochi.test:8888/") + || triggeringPrincipal.startsWith("http://mochi.xorigin-test:8888/"), + "initial triggeringPrincipal correct"); +ok(loadingPrincipal.startsWith("http://mochi.test:8888/") + || loadingPrincipal.startsWith("http://mochi.xorigin-test:8888/"), + "initial loadingPrincipal correct"); +ok(principalToInherit.startsWith("http://mochi.test:8888/") + || principalToInherit.startsWith("http://mochi.xorigin-test:8888/"), + "initial principalToInherit correct"); + +// reset principals on the loadinfo +loadInfo.resetPrincipalToInheritToNullPrincipal(); + +// 2) verify loadInfo contains the correct principals +triggeringPrincipal = channel.loadInfo.triggeringPrincipal.asciiSpec; +loadingPrincipal = channel.loadInfo.loadingPrincipal.asciiSpec; +principalToInherit = channel.loadInfo.principalToInherit; + +ok(triggeringPrincipal.startsWith("http://mochi.test:8888/") + || triggeringPrincipal.startsWith("http://mochi.xorigin-test:8888/"), + "triggeringPrincipal after resetting correct"); +ok(loadingPrincipal.startsWith("http://mochi.test:8888/") + || loadingPrincipal.startsWith("http://mochi.xorigin-test:8888/"), + "loadingPrincipal after resetting correct"); +ok(principalToInherit.isNullPrincipal + || principalToInherit.startsWith("http://mochi.xorigin-test:8888/"), + "principalToInherit after resetting correct"); + +// 3) verify that getChannelResultPrincipal returns right principal +var resultPrincipal = SpecialPowers.Services.scriptSecurityManager + .getChannelResultPrincipal(channel); + +ok(resultPrincipal.isNullPrincipal, + "resultPrincipal after resetting correct"); + +</script> +</pre> +</body> +</html> diff --git a/docshell/test/mochitest/test_form_restoration.html b/docshell/test/mochitest/test_form_restoration.html new file mode 100644 index 0000000000..b929236770 --- /dev/null +++ b/docshell/test/mochitest/test_form_restoration.html @@ -0,0 +1,77 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <title>Test form restoration for no-store pages</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" href="/tests/SimpleTest/test.css"/> + <script> + function waitForMessage(aBroadcastChannel) { + return new Promise(resolve => { + aBroadcastChannel.addEventListener("message", ({ data }) => { + resolve(data); + }, { once: true }); + }); + } + + function postMessageAndWait(aBroadcastChannel, aMsg) { + let promise = waitForMessage(aBroadcastChannel); + aBroadcastChannel.postMessage(aMsg); + return promise; + } + + async function startTest(aTestFun) { + let bc = new BroadcastChannel("form_restoration"); + + let promise = waitForMessage(bc); + window.open("file_form_restoration_no_store.html", "", "noopener"); + await promise; + + // test steps + await aTestFun(bc); + + // close broadcast channel and window + bc.postMessage("close"); + bc.close(); + } + + /* Test for bug1740517 */ + add_task(async function history_back() { + await startTest(async (aBroadcastChannel) => { + // update form data + aBroadcastChannel.postMessage("enter_data"); + + // navigate + await postMessageAndWait(aBroadcastChannel, "navigate"); + + // history back + let { persisted, formData } = await postMessageAndWait(aBroadcastChannel, "back"); + + // check form data + ok(!persisted, "Page with a no-store header shouldn't be bfcached."); + is(formData, "initial", "We shouldn't restore form data when going back to a page with a no-store header."); + }); + }); + + /* Test for bug1752250 */ + add_task(async function location_reload() { + await startTest(async (aBroadcastChannel) => { + // update form data + aBroadcastChannel.postMessage("enter_data"); + + // reload + let { persisted, formData } = await postMessageAndWait(aBroadcastChannel, "reload"); + + // check form data + ok(!persisted, "Page with a no-store header shouldn't be bfcached."); + is(formData, "initial", "We shouldn't restore form data when reload a page with a no-store header."); + }); + }); + </script> +</head> +<body> +<p id="display"></p> +<div id="content" style="display: none"></div> +<pre id="test"></pre> +</body> +</html> diff --git a/docshell/test/mochitest/test_framedhistoryframes.html b/docshell/test/mochitest/test_framedhistoryframes.html new file mode 100644 index 0000000000..f90028af0a --- /dev/null +++ b/docshell/test/mochitest/test_framedhistoryframes.html @@ -0,0 +1,32 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=602256 +--> +<head> + <title>Test for Bug 602256</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=602256">Mozilla Bug 602256</a> +<p id="display"></p> +<div id="content"> +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 602256 */ + +SimpleTest.waitForExplicitFinish(); +var win = window.open("file_framedhistoryframes.html"); + +function done() { + win.close(); + SimpleTest.finish(); +} + +</script> +</pre> +</body> +</html> diff --git a/docshell/test/mochitest/test_iframe_srcdoc_to_remote.html b/docshell/test/mochitest/test_iframe_srcdoc_to_remote.html new file mode 100644 index 0000000000..dac11853d0 --- /dev/null +++ b/docshell/test/mochitest/test_iframe_srcdoc_to_remote.html @@ -0,0 +1,45 @@ +<!DOCTYPE html> +<head> + <meta charset="utf-8"> +<script src="/tests/SimpleTest/SimpleTest.js"></script> +<link rel="stylesheet" href="/tests/SimpleTest/test.css" /> +</head> + +<body onload="test()"> + <script> + /* + Test to verify that when we change an OOP iframe to one that has a + srcdoc it loads in the correct process, which in this case is this + test document. + */ + SimpleTest.waitForExplicitFinish(); + async function test() { + // Create an OOP iframe + let frame = document.createElement("iframe"); + await new Promise(r => { + frame.onload = r; + document.body.appendChild(frame); + // eslint-disable-next-line @microsoft/sdl/no-insecure-url + frame.contentWindow.location = "http://example.net/tests/docshell/test/dummy_page.html"; + }); + + if (SpecialPowers.effectiveIsolationStrategy() == SpecialPowers.ISOLATION_STRATEGY.IsolateEverything) { + ok(SpecialPowers.Cu.isRemoteProxy(frame.contentWindow), "should be a remote frame"); + } + + // Remove the attribute so we can set a srcdoc attribute on it + frame.removeAttribute("src"); + + // Set a srcdoc attribute on this iframe and wait for the load + await new Promise(r => { + frame.onload = r; + frame.setAttribute("srcdoc", '<html><body>body of the srcdoc frame</body></html>'); + }); + + // We should be in the same process as this test document + ok(!SpecialPowers.Cu.isRemoteProxy(frame.contentWindow), "should NOT be a remote frame"); + SimpleTest.finish(); + } + </script> +</body> + diff --git a/docshell/test/mochitest/test_javascript_sandboxed_popup.html b/docshell/test/mochitest/test_javascript_sandboxed_popup.html new file mode 100644 index 0000000000..edce93c26f --- /dev/null +++ b/docshell/test/mochitest/test_javascript_sandboxed_popup.html @@ -0,0 +1,27 @@ +<!DOCTYPE html> +<head> +<meta charset="utf-8"> +<script src="/tests/SimpleTest/SimpleTest.js"></script> +<link rel="stylesheet" href="/tests/SimpleTest/test.css" /> +</head> + +<body> +<iframe srcdoc="<a href='javascript:opener.parent.ok(false, `The JS ran!`)' target=_blank rel=opener>click</a>" + sandbox="allow-popups allow-same-origin"></iframe> + +<script> +add_task(async function() { + let promise = new Promise(resolve =>{ + SpecialPowers.addObserver(function obs(subject) { + is(subject.opener, window[0], + "blocked javascript URI should have been targeting the pop-up document"); + subject.close(); + SpecialPowers.removeObserver(obs, "javascript-uri-blocked-by-sandbox"); + resolve(); + }, "javascript-uri-blocked-by-sandbox"); + }); + document.querySelector("iframe").contentDocument.querySelector("a").click(); + await promise; +}); +</script> +</body> diff --git a/docshell/test/mochitest/test_load_during_reload.html b/docshell/test/mochitest/test_load_during_reload.html new file mode 100644 index 0000000000..88856b0100 --- /dev/null +++ b/docshell/test/mochitest/test_load_during_reload.html @@ -0,0 +1,49 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <title>Test loading a new page after calling reload()</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" href="/tests/SimpleTest/test.css"/> + <script> + + function promiseForLoad() { + return new Promise(resolve => { + addEventListener("message", resolve, { once: true }); + }); + } + + add_task(async function runTest() { + let win = window.open("file_load_during_reload.html"); + await promiseForLoad(); + + win.location.reload(); + win.location.href = "file_load_during_reload.html?nextpage"; + await promiseForLoad(); + + ok(win.location.href.includes("nextpage"), "Should have loaded the next page."); + win.close(); + }); + + add_task(async function runTest2() { + let win = window.open("file_load_during_reload.html"); + await promiseForLoad(); + + win.history.replaceState("", "", "?1"); + win.location.reload(); + win.history.pushState("", "", "?2"); + win.location.reload(); + await promiseForLoad(); + + ok(win.location.href.includes("2"), "Should have loaded the second page."); + win.close(); + }); + + </script> +</head> +<body> +<p id="display"></p> +<div id="content" style="display: none"></div> +<pre id="test"></pre> +</body> +</html> diff --git a/docshell/test/mochitest/test_navigate_after_pagehide.html b/docshell/test/mochitest/test_navigate_after_pagehide.html new file mode 100644 index 0000000000..17d58d6e62 --- /dev/null +++ b/docshell/test/mochitest/test_navigate_after_pagehide.html @@ -0,0 +1,34 @@ +<!doctype html> +<html> + <head> + <title>Test for navigation attempts by scripts in inactive inner window</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + </head> +<body> +<iframe src="dummy_page.html" id="iframe"></iframe> + +<script> +"use strict"; + +add_task(async function() { + let iframe = document.getElementById("iframe"); + + let navigate = iframe.contentWindow.eval(`(function() { + location.href = "/"; + })`); + + // eslint-disable-next-line @microsoft/sdl/no-insecure-url + iframe.src = "http://example.com/"; + await new Promise(resolve => + iframe.addEventListener("load", resolve, { once: true }) + ); + + // This should do nothing. But, importantly, it should especially not crash. + navigate(); + + ok(true, "We didn't crash"); +}); +</script> +</body> +</html> diff --git a/docshell/test/mochitest/test_pushState_after_document_open.html b/docshell/test/mochitest/test_pushState_after_document_open.html new file mode 100644 index 0000000000..b81951b7ae --- /dev/null +++ b/docshell/test/mochitest/test_pushState_after_document_open.html @@ -0,0 +1,39 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=957479 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 957479</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + + /** Test for Bug 957479 */ + SimpleTest.waitForExplicitFinish(); + // Child needs to invoke us, otherwise our onload will fire before the child + // has done the write/close bit. + onmessage = function doTest() { + is(frames[0].location.pathname, "/tests/docshell/test/mochitest/file_pushState_after_document_open.html", + "Should have the right path here"); + is(frames[0].location.hash, "", "Should have the right hash here"); + frames[0].history.pushState({}, "", frames[0].document.URL + "#foopy"); + is(frames[0].location.pathname, "/tests/docshell/test/mochitest/file_pushState_after_document_open.html", + "Pathname should not have changed"); + is(frames[0].location.hash, "#foopy", "Hash should have changed"); + SimpleTest.finish(); + }; + + </script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=957479">Mozilla Bug 957479</a> +<p id="display"></p> +<div id="content" style="display: none"> +<iframe src="file_pushState_after_document_open.html"></iframe> +</div> +<pre id="test"> +</pre> +</body> +</html> diff --git a/docshell/test/mochitest/test_redirect_history.html b/docshell/test/mochitest/test_redirect_history.html new file mode 100644 index 0000000000..a67c808405 --- /dev/null +++ b/docshell/test/mochitest/test_redirect_history.html @@ -0,0 +1,58 @@ +<!doctype html> +<html> + <head> + <title>Test for redirect from POST</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="/tests/SimpleTest/EventUtils.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + </head> + <body> + <script> + "use strict"; + + info("Starting tests"); + + let tests = new Map([ + ["sameorigin", window.location.origin], + // eslint-disable-next-line @microsoft/sdl/no-insecure-url + ["crossorigin", "http://test1.example.com"], + ]); + for (let [kind, origin] of tests) { + add_task(async function runTest() { + info(`Submitting to ${origin}`); + + let win; + await new Promise(resolve => { + addEventListener("message", resolve, { once: true }); + info("Loading file_redirect_history.html"); + win = window.open("file_redirect_history.html"); + }); + info("Done loading file_redirect_history.html"); + + let length = win.history.length; + let loc = win.location.toString(); + + await new Promise(resolve => { + addEventListener("message", resolve, { once: true }); + info("Posting"); + win.postMessage(`${origin}/tests/docshell/test/mochitest/form_submit_redirect.sjs?redirectTo=${loc}`, "*") + }); + info("Done posting\n"); + is(win.history.length, length, `Test ${kind}: history length should not change.`); + info(`Length=${win.history.length}`); + is(win.location.toString(), loc, `Test ${kind}: location should not change.`); + + await new Promise(resolve => { + addEventListener("message", resolve, { once: true }); + info("Reloading"); + win.location.reload(); + }); + info("Done reloading\n"); + is(win.location.toString(), loc, `Test ${kind}: location should not change after reload.`); + + win.close(); + }); + } + </script> + </body> +</html> diff --git a/docshell/test/mochitest/test_triggeringprincipal_location_seturi.html b/docshell/test/mochitest/test_triggeringprincipal_location_seturi.html new file mode 100644 index 0000000000..92e20b03ea --- /dev/null +++ b/docshell/test/mochitest/test_triggeringprincipal_location_seturi.html @@ -0,0 +1,105 @@ +<!DOCTYPE html> +<html> +<head> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> + +<script type="text/javascript"> + +SimpleTest.waitForExplicitFinish(); + +const SAME_ORIGIN_URI = "http://mochi.test:8888/tests/docshell/test/dummy_page.html"; +// eslint-disable-next-line @microsoft/sdl/no-insecure-url +const CROSS_ORIGIN_URI = "http://example.com/tests/docshell/test/dummy_page.html"; +const NUMBER_OF_TESTS = 3; +let testCounter = 0; + +function checkFinish() { + testCounter++; + if (testCounter < NUMBER_OF_TESTS) { + return; + } + SimpleTest.finish(); +} + +// ---- test 1 ---- + +let myFrame1 = document.createElement("iframe"); +myFrame1.src = SAME_ORIGIN_URI; +myFrame1.addEventListener("load", checkLoadFrame1); +document.documentElement.appendChild(myFrame1); + +function checkLoadFrame1() { + myFrame1.removeEventListener("load", checkLoadFrame1); + // window.location.href is no longer cross-origin accessible in gecko. + is(SpecialPowers.wrap(myFrame1.contentWindow).location.href, SAME_ORIGIN_URI, + "initial same origin dummy loaded into frame1"); + + SpecialPowers.wrap(myFrame1.contentWindow).location.hash = "#bar"; + is(SpecialPowers.wrap(myFrame1.contentWindow).location.href, SAME_ORIGIN_URI + "#bar", + "initial same origin dummy#bar loaded into iframe1"); + + myFrame1.addEventListener("load", checkNavFrame1); + myFrame1.src = CROSS_ORIGIN_URI; +} + +async function checkNavFrame1() { + myFrame1.removeEventListener("load", checkNavFrame1); + is(await SpecialPowers.spawn(myFrame1, [], () => this.content.location.href), + CROSS_ORIGIN_URI, + "cross origin dummy loaded into frame1"); + + myFrame1.addEventListener("load", checkBackNavFrame1); + myFrame1.src = SAME_ORIGIN_URI + "#bar"; +} + +async function checkBackNavFrame1() { + myFrame1.removeEventListener("load", checkBackNavFrame1); + is(await SpecialPowers.spawn(myFrame1, [], () => this.content.location.href), + SAME_ORIGIN_URI + "#bar", + "navagiating back to same origin dummy for frame1"); + checkFinish(); +} + +// ---- test 2 ---- + +let myFrame2 = document.createElement("iframe"); +myFrame2.src = "about:blank"; +myFrame2.addEventListener("load", checkLoadFrame2); +document.documentElement.appendChild(myFrame2); + +function checkLoadFrame2() { + myFrame2.removeEventListener("load", checkLoadFrame2); + is(SpecialPowers.wrap(myFrame2.contentWindow).location.href, "about:blank", + "initial about:blank frame loaded"); + + myFrame2.contentWindow.location.hash = "#foo"; + is(SpecialPowers.wrap(myFrame2.contentWindow).location.href, "about:blank#foo", + "about:blank#foo frame loaded"); + + myFrame2.addEventListener("load", checkHistoryFrame2); + myFrame2.src = "about:blank"; +} + +function checkHistoryFrame2() { + myFrame2.removeEventListener("load", checkHistoryFrame2); + is(SpecialPowers.wrap(myFrame2.contentWindow).location.href, "about:blank", + "about:blank frame loaded again"); + checkFinish(); +} + +// ---- test 3 ---- + +let myFrame3 = document.createElement("frame"); +document.documentElement.appendChild(myFrame3); +myFrame3.contentWindow.location.hash = "#foo"; + +is(myFrame3.contentWindow.location.href, "about:blank#foo", + "created history entry with about:blank#foo"); +checkFinish(); + +</script> +</body> +</html> diff --git a/docshell/test/mochitest/test_windowedhistoryframes.html b/docshell/test/mochitest/test_windowedhistoryframes.html new file mode 100644 index 0000000000..a874da098c --- /dev/null +++ b/docshell/test/mochitest/test_windowedhistoryframes.html @@ -0,0 +1,32 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=602256 +--> +<head> + <title>Test for Bug 602256</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=602256">Mozilla Bug 602256</a> +<p id="display"></p> +<div id="content" style="display: none"></div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 602256 */ + +SimpleTest.waitForExplicitFinish(); + +function done() { + subWin.close(); + SimpleTest.finish(); +} + +var subWin = window.open("historyframes.html", "_blank"); + +</script> +</pre> +</body> +</html> diff --git a/docshell/test/mochitest/url1_historyframe.html b/docshell/test/mochitest/url1_historyframe.html new file mode 100644 index 0000000000..b86af4b3fa --- /dev/null +++ b/docshell/test/mochitest/url1_historyframe.html @@ -0,0 +1 @@ +<p id='text'>Test1</p> diff --git a/docshell/test/mochitest/url2_historyframe.html b/docshell/test/mochitest/url2_historyframe.html new file mode 100644 index 0000000000..24374d1a5b --- /dev/null +++ b/docshell/test/mochitest/url2_historyframe.html @@ -0,0 +1 @@ +<p id='text'>Test2</p> |