diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
commit | 36d22d82aa202bb199967e9512281e9a53db42c9 (patch) | |
tree | 105e8c98ddea1c1e4784a60a5a6410fa416be2de /docshell/test/chrome | |
parent | Initial commit. (diff) | |
download | firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip |
Adding upstream version 115.7.0esr.upstream/115.7.0esr
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'docshell/test/chrome')
100 files changed, 6027 insertions, 0 deletions
diff --git a/docshell/test/chrome/112564_nocache.html b/docshell/test/chrome/112564_nocache.html new file mode 100644 index 0000000000..29fb990b86 --- /dev/null +++ b/docshell/test/chrome/112564_nocache.html @@ -0,0 +1,10 @@ +<html> +<head> +<title>test1</title> +</head> +<body> +<p> +This document will be sent with a no-cache cache-control header. When sent over a secure connection, it should not be stored in bfcache. +</p> +</body> +</html> diff --git a/docshell/test/chrome/112564_nocache.html^headers^ b/docshell/test/chrome/112564_nocache.html^headers^ new file mode 100644 index 0000000000..c829a41ae9 --- /dev/null +++ b/docshell/test/chrome/112564_nocache.html^headers^ @@ -0,0 +1 @@ +Cache-control: no-cache diff --git a/docshell/test/chrome/215405_nocache.html b/docshell/test/chrome/215405_nocache.html new file mode 100644 index 0000000000..c7d48c4eba --- /dev/null +++ b/docshell/test/chrome/215405_nocache.html @@ -0,0 +1,14 @@ +<!DOCTYPE html> +<html style="height: 100%"> +<head> + <title>test1</title> +</head> +<body style="height: 100%"> + <input type="text" id="inp" value=""> + </input> + <div style="height: 50%">Some text</div> + <div style="height: 50%">Some text</div> + <div style="height: 50%">Some text</div> + <div style="height: 50%; width: 300%">Some more text</div> +</body> +</html> diff --git a/docshell/test/chrome/215405_nocache.html^headers^ b/docshell/test/chrome/215405_nocache.html^headers^ new file mode 100644 index 0000000000..c829a41ae9 --- /dev/null +++ b/docshell/test/chrome/215405_nocache.html^headers^ @@ -0,0 +1 @@ +Cache-control: no-cache diff --git a/docshell/test/chrome/215405_nostore.html b/docshell/test/chrome/215405_nostore.html new file mode 100644 index 0000000000..4f5bd0f4f0 --- /dev/null +++ b/docshell/test/chrome/215405_nostore.html @@ -0,0 +1,14 @@ +<!DOCTYPE html> +<html style="height: 100%"> +<head> + <title>test1</title> +</head> +<body style="height: 100%"> + <input type="text" id="inp" value=""> + </input> + <div style="height: 50%">Some text</div> + <div style="height: 50%">Some text</div> + <div style="height: 50%">Some text</div> + <div style="height: 50%; width: 350%">Some more text</div> +</body> +</html> diff --git a/docshell/test/chrome/215405_nostore.html^headers^ b/docshell/test/chrome/215405_nostore.html^headers^ new file mode 100644 index 0000000000..59ba296103 --- /dev/null +++ b/docshell/test/chrome/215405_nostore.html^headers^ @@ -0,0 +1 @@ +Cache-control: no-store diff --git a/docshell/test/chrome/582176_dummy.html b/docshell/test/chrome/582176_dummy.html new file mode 100644 index 0000000000..3b18e512db --- /dev/null +++ b/docshell/test/chrome/582176_dummy.html @@ -0,0 +1 @@ +hello world diff --git a/docshell/test/chrome/582176_xml.xml b/docshell/test/chrome/582176_xml.xml new file mode 100644 index 0000000000..d3dd576dfe --- /dev/null +++ b/docshell/test/chrome/582176_xml.xml @@ -0,0 +1,2 @@ +<?xml-stylesheet type="text/xsl" href="582176_xslt.xsl"?> +<out/> diff --git a/docshell/test/chrome/582176_xslt.xsl b/docshell/test/chrome/582176_xslt.xsl new file mode 100644 index 0000000000..5957416899 --- /dev/null +++ b/docshell/test/chrome/582176_xslt.xsl @@ -0,0 +1,8 @@ +<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> + <xsl:template match="out"> + <html> + <head><title>XSLT result doc</title></head> + <body><p>xslt result</p></body> + </html> + </xsl:template> +</xsl:stylesheet> diff --git a/docshell/test/chrome/662200a.html b/docshell/test/chrome/662200a.html new file mode 100644 index 0000000000..0b9ead6f3e --- /dev/null +++ b/docshell/test/chrome/662200a.html @@ -0,0 +1,8 @@ +<html> + <head> + <title>A</title> + </head> + <body> + <a id="link" href="662200b.html">Next</a> + </body> +</html> diff --git a/docshell/test/chrome/662200b.html b/docshell/test/chrome/662200b.html new file mode 100644 index 0000000000..91e6b971d6 --- /dev/null +++ b/docshell/test/chrome/662200b.html @@ -0,0 +1,8 @@ +<html> + <head> + <title>B</title> + </head> + <body> + <a id="link" href="662200c.html">Next</a> + </body> +</html> diff --git a/docshell/test/chrome/662200c.html b/docshell/test/chrome/662200c.html new file mode 100644 index 0000000000..bc00e6b14b --- /dev/null +++ b/docshell/test/chrome/662200c.html @@ -0,0 +1,7 @@ +<html> + <head> + <title>C</title> + </head> + <body> + </body> +</html> diff --git a/docshell/test/chrome/89419.html b/docshell/test/chrome/89419.html new file mode 100644 index 0000000000..b36b8d788c --- /dev/null +++ b/docshell/test/chrome/89419.html @@ -0,0 +1,7 @@ +<html> +<head> +<title>Bug 89419</title> +</head> +<body> +<img src="http://mochi.test:8888/tests/docshell/test/chrome/bug89419.sjs"> +</body> diff --git a/docshell/test/chrome/92598_nostore.html b/docshell/test/chrome/92598_nostore.html new file mode 100644 index 0000000000..47bb90441e --- /dev/null +++ b/docshell/test/chrome/92598_nostore.html @@ -0,0 +1,10 @@ +<html> +<head> +<title>test1</title> +</head> +<body> +<p> +This document will be sent with a no-store cache-control header. It should not be stored in bfcache. +</p> +</body> +</html> diff --git a/docshell/test/chrome/92598_nostore.html^headers^ b/docshell/test/chrome/92598_nostore.html^headers^ new file mode 100644 index 0000000000..59ba296103 --- /dev/null +++ b/docshell/test/chrome/92598_nostore.html^headers^ @@ -0,0 +1 @@ +Cache-control: no-store diff --git a/docshell/test/chrome/DocShellHelpers.sys.mjs b/docshell/test/chrome/DocShellHelpers.sys.mjs new file mode 100644 index 0000000000..5f4eee8724 --- /dev/null +++ b/docshell/test/chrome/DocShellHelpers.sys.mjs @@ -0,0 +1,74 @@ +/* Any copyright is dedicated to the Public Domain. +http://creativecommons.org/publicdomain/zero/1.0/ */ + +export class DocShellHelpersParent extends JSWindowActorParent { + static eventListener; + + // These static variables should be set when registering the actor + // (currently doPageNavigation in docshell_helpers.js). + static eventsToListenFor; + static observers; + + constructor() { + super(); + } + receiveMessage({ name, data }) { + if (name == "docshell_helpers:event") { + let { event, originalTargetIsHTMLDocument } = data; + + if (this.constructor.eventsToListenFor.includes(event.type)) { + this.constructor.eventListener(event, originalTargetIsHTMLDocument); + } + } else if (name == "docshell_helpers:observe") { + let { topic } = data; + + this.constructor.observers.get(topic).call(); + } + } +} + +export class DocShellHelpersChild extends JSWindowActorChild { + constructor() { + super(); + } + receiveMessage({ name, data }) { + if (name == "docshell_helpers:preventBFCache") { + // Add an RTCPeerConnection to prevent the page from being bfcached. + let win = this.contentWindow; + win.blockBFCache = new win.RTCPeerConnection(); + } + } + handleEvent(event) { + if ( + Document.isInstance(event.originalTarget) && + event.originalTarget.isInitialDocument + ) { + dump(`TEST: ignoring a ${event.type} event for an initial about:blank\n`); + return; + } + + this.sendAsyncMessage("docshell_helpers:event", { + event: { + type: event.type, + persisted: event.persisted, + originalTarget: { + title: event.originalTarget.title, + location: event.originalTarget.location.href, + visibilityState: event.originalTarget.visibilityState, + hidden: event.originalTarget.hidden, + }, + }, + originalTargetIsHTMLDocument: HTMLDocument.isInstance( + event.originalTarget + ), + }); + } + observe(subject, topic) { + if (Window.isInstance(subject) && subject.document.isInitialDocument) { + dump(`TEST: ignoring a topic notification for an initial about:blank\n`); + return; + } + + this.sendAsyncMessage("docshell_helpers:observe", { topic }); + } +} diff --git a/docshell/test/chrome/allowContentRetargeting.sjs b/docshell/test/chrome/allowContentRetargeting.sjs new file mode 100644 index 0000000000..96e467ef68 --- /dev/null +++ b/docshell/test/chrome/allowContentRetargeting.sjs @@ -0,0 +1,7 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +function handleRequest(req, resp) { + resp.setHeader("Content-Type", "application/octet-stream", false); + resp.write("hi"); +} diff --git a/docshell/test/chrome/blue.png b/docshell/test/chrome/blue.png Binary files differnew file mode 100644 index 0000000000..8df58f3a5f --- /dev/null +++ b/docshell/test/chrome/blue.png diff --git a/docshell/test/chrome/bug112564_window.xhtml b/docshell/test/chrome/bug112564_window.xhtml new file mode 100644 index 0000000000..04c25763b3 --- /dev/null +++ b/docshell/test/chrome/bug112564_window.xhtml @@ -0,0 +1,86 @@ +<?xml version="1.0"?> + +<!-- This Source Code Form is subject to the terms of the Mozilla Public + - License, v. 2.0. If a copy of the MPL was not distributed with this + - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> + +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> + +<window id="112564Test" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + width="600" + height="600" + onload="onLoad();" + title="112564 test"> + + <script type="application/javascript" src="chrome://mochikit/content/chrome-harness.js" /> + <script type="application/javascript" src="docshell_helpers.js" /> + <script type="application/javascript"><![CDATA[ + var gTestsIterator; + + function onLoad() { + gTestsIterator = testsIterator(); + nextTest(); + } + + function nextTest() { + gTestsIterator.next(); + } + + function* testsIterator() { + // Load a secure page with a no-cache header, followed by a simple page. + // no-cache should not interfere with the bfcache in the way no-store + // does. + var test1DocURI = "https://example.com:443/chrome/docshell/test/chrome/112564_nocache.html"; + + doPageNavigation({ + uri: test1DocURI, + eventsToListenFor: ["load", "pageshow"], + expectedEvents: [ { type: "load", + title: "test1" }, + { type: "pageshow", + title: "test1", + persisted: false } ], + onNavComplete: nextTest + }); + yield undefined; + + var test2DocURI = "data:text/html,<html><head><title>test2</title></head>" + + "<body>test2</body></html>"; + + doPageNavigation({ + uri: test2DocURI, + eventsToListenFor: ["load", "pageshow", "pagehide"], + expectedEvents: [ { type: "pagehide", + title: "test1", + persisted: true }, + { type: "load", + title: "test2" }, + { type: "pageshow", + title: "test2", + persisted: false } ], + onNavComplete: nextTest + }); + yield undefined; + + // Now go back in history. First page has been cached. + // Check persisted property to confirm + doPageNavigation({ + back: true, + eventsToListenFor: ["pageshow", "pagehide"], + expectedEvents: [ { type: "pagehide", + title: "test2", + persisted: true }, + { type: "pageshow", + title: "test1", + persisted: true } ], + onNavComplete: nextTest + }); + yield undefined; + + finish(); + } + ]]></script> + + <browser type="content" primary="true" flex="1" id="content" remote="true" maychangeremoteness="true" /> +</window> diff --git a/docshell/test/chrome/bug113934_window.xhtml b/docshell/test/chrome/bug113934_window.xhtml new file mode 100644 index 0000000000..794b8b2836 --- /dev/null +++ b/docshell/test/chrome/bug113934_window.xhtml @@ -0,0 +1,165 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<window title="Mozilla Bug 113934" onload="doTheTest()" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + + <hbox> + <vbox id="box1"> + </vbox> + <vbox id="box2"> + </vbox> + <spacer flex="1"/> + </hbox> + + <!-- test code goes here --> + <script type="application/javascript"><![CDATA[ + /* globals SimpleTest, is, isnot, ok, snapshotWindow, compareSnapshots, + onerror */ + var imports = [ "SimpleTest", "is", "isnot", "ok", "snapshotWindow", + "compareSnapshots", "onerror" ]; + for (var name of imports) { + window[name] = window.arguments[0][name]; + } + + function $(id) { + return document.getElementById(id); + } + + function addBrowser(parent, id, width, height) { + var b = + document.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul", "browser"); + var type = window.location.search.slice(1); + is(type == "chrome" || type == "content", true, "Unexpected type"); + b.setAttribute("type", type); + b.setAttribute("id", id); + b.style.width = width + "px"; + b.style.height = height + "px"; + $(parent).appendChild(b); + } + addBrowser("box1", "f1", 300, 200); + addBrowser("box1", "f2", 300, 200); + addBrowser("box2", "f3", 30, 200); + + /** Test for Bug 113934 */ + var doc1 = + "data:text/html,<html><body onbeforeunload='document.documentElement.textContent = \"\"' onunload='document.documentElement.textContent = \"\"' onpagehide='document.documentElement.textContent = \"\"'>This is a test</body></html>"; + var doc2 = "data:text/html,<html><head></head><body>This is a second test</body></html>"; + + + $("f1").setAttribute("src", doc1); + $("f2").setAttribute("src", doc2); + $("f3").setAttribute("src", doc2); + + async function doTheTest() { + var s2 = await snapshotWindow($("f2").contentWindow); + // var s3 = await snapshotWindow($("f3").contentWindow); + + // This test is broken - see bug 1090274 + //ok(!compareSnapshots(s2, s3, true)[0], + // "Should look different due to different sizing"); + + function getDOM(id) { + return $(id).contentDocument.documentElement.innerHTML; + } + + var dom1 = getDOM("f1"); + + var dom2 = getDOM("f2"); + $("f2").contentDocument.body.textContent = "Modified the text"; + var dom2star = getDOM("f2"); + isnot(dom2, dom2star, "We changed the DOM!"); + + $("f1").swapDocShells($("f2")); + // now we have doms 2*, 1, 2 in the frames + + is(getDOM("f1"), dom2star, "Shouldn't have changed the DOM on swap"); + is(getDOM("f2"), dom1, "Shouldn't have fired event handlers"); + + // Test for bug 480149 + // The DOMLink* events are dispatched asynchronously, thus I cannot + // just include the <link> element in the initial DOM and swap the + // docshells. Instead, the link element is added now. Then, when the + // first DOMLinkAdded event (which is a result of the actual addition) + // is dispatched, the docshells are swapped and the pageshow and pagehide + // events are tested. Only then, we wait for the DOMLink* events, + // which are a result of swapping the docshells. + var DOMLinkListener = { + _afterFirst: false, + _removedDispatched: false, + _addedDispatched: false, + async handleEvent(aEvent) { + if (!this._afterFirst) { + is(aEvent.type, "DOMLinkAdded"); + + var strs = { "f1": "", "f3" : "" }; + function attachListener(node, type) { + var listener = function(e) { + if (strs[node.id]) strs[node.id] += " "; + strs[node.id] += node.id + ".page" + type; + } + node.addEventListener("page" + type, listener); + + listener.detach = function() { + node.removeEventListener("page" + type, listener); + } + return listener; + } + + var l1 = attachListener($("f1"), "show"); + var l2 = attachListener($("f1"), "hide"); + var l3 = attachListener($("f3"), "show"); + var l4 = attachListener($("f3"), "hide"); + + $("f1").swapDocShells($("f3")); + // now we have DOMs 2, 1, 2* in the frames + + l1.detach(); + l2.detach(); + l3.detach(); + l4.detach(); + + // swapDocShells reflows asynchronously, ensure layout is + // clean so that the viewport of f1 is the right size. + $("f1").getBoundingClientRect(); + var s1_new = await snapshotWindow($("f1").contentWindow); + var [same, first, second] = compareSnapshots(s1_new, s2, true); + ok(same, "Should reflow on swap. Expected " + second + " but got " + first); + + is(strs.f1, "f1.pagehide f1.pageshow"); + is(strs.f3, "f3.pagehide f3.pageshow"); + this._afterFirst = true; + return; + } + if (aEvent.type == "DOMLinkAdded") { + is(this._addedDispatched, false); + this._addedDispatched = true; + } + else { + is(this._removedDispatched, false); + this._removedDispatched = true; + } + + if (this._addedDispatched && this._removedDispatched) { + $("f1").removeEventListener("DOMLinkAdded", this); + $("f1").removeEventListener("DOMLinkRemoved", this); + $("f3").removeEventListener("DOMLinkAdded", this); + $("f3").removeEventListener("DOMLinkRemoved", this); + window.close(); + SimpleTest.finish(); + } + } + }; + + $("f1").addEventListener("DOMLinkAdded", DOMLinkListener); + $("f1").addEventListener("DOMLinkRemoved", DOMLinkListener); + $("f3").addEventListener("DOMLinkAdded", DOMLinkListener); + $("f3").addEventListener("DOMLinkRemoved", DOMLinkListener); + + var linkElement = $("f1").contentDocument.createElement("link"); + linkElement.setAttribute("rel", "alternate"); + linkElement.setAttribute("href", "about:blank"); + $("f1").contentDocument.documentElement.firstChild.appendChild(linkElement); + } + + ]]></script> +</window> diff --git a/docshell/test/chrome/bug215405_window.xhtml b/docshell/test/chrome/bug215405_window.xhtml new file mode 100644 index 0000000000..e6dddd99ba --- /dev/null +++ b/docshell/test/chrome/bug215405_window.xhtml @@ -0,0 +1,177 @@ +<?xml version="1.0"?> + +<!-- This Source Code Form is subject to the terms of the Mozilla Public + - License, v. 2.0. If a copy of the MPL was not distributed with this + - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> + +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> + +<window id="215405Test" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + width="600" + height="600" + onload="onLoad();" + title="215405 test"> + + <script type="application/javascript"><![CDATA[ + const {BrowserTestUtils} = ChromeUtils.import("resource://testing-common/BrowserTestUtils.jsm"); + Services.prefs.setBoolPref("browser.navigation.requireUserInteraction", false); + + /* globals SimpleTest, is, isnot, ok */ + var imports = [ "SimpleTest", "is", "isnot", "ok"]; + for (var name of imports) { + window[name] = window.arguments[0][name]; + } + + const text="MOZILLA"; + const nostoreURI = "http://mochi.test:8888/tests/docshell/test/chrome/" + + "215405_nostore.html"; + const nocacheURI = "https://example.com:443/tests/docshell/test/chrome/" + + "215405_nocache.html"; + + var gBrowser; + var gTestsIterator; + var currScrollX = 0; + var currScrollY = 0; + + function finish() { + gBrowser.removeEventListener("pageshow", eventListener, true); + // Work around bug 467960 + let historyPurged; + if (SpecialPowers.Services.appinfo.sessionHistoryInParent) { + let history = gBrowser.browsingContext.sessionHistory; + history.purgeHistory(history.count); + historyPurged = Promise.resolve(); + } else { + historyPurged = SpecialPowers.spawn(gBrowser, [], () => { + let history = docShell.QueryInterface(Ci.nsIWebNavigation).sessionHistory + .legacySHistory; + history.purgeHistory(history.count); + }); + } + + historyPurged.then(_ => { + window.close(); + window.arguments[0].SimpleTest.finish(); + }); + } + + function onLoad(e) { + gBrowser = document.getElementById("content"); + gBrowser.addEventListener("pageshow", eventListener, true); + + gTestsIterator = testsIterator(); + nextTest(); + } + + function eventListener(event) { + setTimeout(nextTest, 0); + } + + function nextTest() { + gTestsIterator.next(); + } + + function* testsIterator() { + // No-store tests + var testName = "[nostore]"; + + // Load a page with a no-store header + BrowserTestUtils.loadURIString(gBrowser, nostoreURI); + yield undefined; + + + // Now that the page has loaded, amend the form contents + var form = gBrowser.contentDocument.getElementById("inp"); + form.value = text; + + // Attempt to scroll the page + var originalXPosition = gBrowser.contentWindow.scrollX; + var originalYPosition = gBrowser.contentWindow.scrollY; + var scrollToX = gBrowser.contentWindow.scrollMaxX; + var scrollToY = gBrowser.contentWindow.scrollMaxY; + gBrowser.contentWindow.scrollBy(scrollToX, scrollToY); + + // Save the scroll position for future comparison + currScrollX = gBrowser.contentWindow.scrollX; + currScrollY = gBrowser.contentWindow.scrollY; + isnot(currScrollX, originalXPosition, + testName + " failed to scroll window horizontally"); + isnot(currScrollY, originalYPosition, + testName + " failed to scroll window vertically"); + + // Load a new document into the browser + var simple = "data:text/html,<html><head><title>test2</title></head>" + + "<body>test2</body></html>"; + BrowserTestUtils.loadURIString(gBrowser, simple); + yield undefined; + + + // Now go back in history. First page should not have been cached. + gBrowser.goBack(); + yield undefined; + + + // First uncacheable page will now be reloaded. Check scroll position + // restored, and form contents not + is(gBrowser.contentWindow.scrollX, currScrollX, testName + + " horizontal axis scroll position not correctly restored"); + is(gBrowser.contentWindow.scrollY, currScrollY, testName + + " vertical axis scroll position not correctly restored"); + var formValue = gBrowser.contentDocument.getElementById("inp").value; + isnot(formValue, text, testName + " form value incorrectly restored"); + + + // https no-cache + testName = "[nocache]"; + + // Load a page with a no-cache header. This should not be + // restricted like no-store (bug 567365) + BrowserTestUtils.loadURIString(gBrowser, nocacheURI); + yield undefined; + + + // Now that the page has loaded, amend the form contents + form = gBrowser.contentDocument.getElementById("inp"); + form.value = text; + + // Attempt to scroll the page + originalXPosition = gBrowser.contentWindow.scrollX; + originalYPosition = gBrowser.contentWindow.scrollY; + scrollToX = gBrowser.contentWindow.scrollMaxX; + scrollToY = gBrowser.contentWindow.scrollMaxY; + gBrowser.contentWindow.scrollBy(scrollToX, scrollToY); + + // Save the scroll position for future comparison + currScrollX = gBrowser.contentWindow.scrollX; + currScrollY = gBrowser.contentWindow.scrollY; + isnot(currScrollX, originalXPosition, + testName + " failed to scroll window horizontally"); + isnot(currScrollY, originalYPosition, + testName + " failed to scroll window vertically"); + + BrowserTestUtils.loadURIString(gBrowser, simple); + yield undefined; + + + // Now go back in history to the cached page. + gBrowser.goBack(); + yield undefined; + + + // First page will now be reloaded. Check scroll position + // and form contents are restored + is(gBrowser.contentWindow.scrollX, currScrollX, testName + + " horizontal axis scroll position not correctly restored"); + is(gBrowser.contentWindow.scrollY, currScrollY, testName + + " vertical axis scroll position not correctly restored"); + formValue = gBrowser.contentDocument.getElementById("inp").value; + is(formValue, text, testName + " form value not correctly restored"); + + Services.prefs.clearUserPref("browser.navigation.requireUserInteraction"); + finish(); + } + ]]></script> + + <browser type="content" primary="true" flex="1" id="content" src="about:blank"/> +</window> diff --git a/docshell/test/chrome/bug293235.html b/docshell/test/chrome/bug293235.html new file mode 100644 index 0000000000..458f88431c --- /dev/null +++ b/docshell/test/chrome/bug293235.html @@ -0,0 +1,13 @@ +<html> + <head> + <title>Bug 293235 page1</title> + <style type="text/css"> + a:visited, a.forcevisited.forcevisited { color: rgb(128, 0, 128); } + a:link, a.forcelink.forcelink { color: rgb(0, 0, 128); } + a:focus { color: rgb(128, 0, 0); } + </style> + </head> + <body> + <a id="link1" href="bug293235_p2.html">This is a test link.</a> + </body> +</html> diff --git a/docshell/test/chrome/bug293235_p2.html b/docshell/test/chrome/bug293235_p2.html new file mode 100644 index 0000000000..2de067b80e --- /dev/null +++ b/docshell/test/chrome/bug293235_p2.html @@ -0,0 +1,8 @@ +<html> + <head> + <title>Bug 293235 page2</title> + </head> + <body> + Nothing to see here, move along. + </body> +</html> diff --git a/docshell/test/chrome/bug293235_window.xhtml b/docshell/test/chrome/bug293235_window.xhtml new file mode 100644 index 0000000000..7d87517824 --- /dev/null +++ b/docshell/test/chrome/bug293235_window.xhtml @@ -0,0 +1,118 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> + +<window id="293235Test" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + width="600" + height="600" + onload="setTimeout(runTests, 0);" + title="bug 293235 test"> + + <script type="application/javascript" src= "chrome://mochikit/content/chrome-harness.js" /> + <script type="application/javascript" src="docshell_helpers.js" /> + <script src="chrome://mochikit/content/tests/SimpleTest/WindowSnapshot.js"></script> + + <script type="application/javascript"><![CDATA[ + var {NetUtil} = ChromeUtils.import("resource://gre/modules/NetUtil.jsm"); + + // Return the Element object for the specified element id + function $(id) { return TestWindow.getDocument().getElementById(id); } + + //// + // Generator function for test steps for bug 293235: + // A visited link should have the :visited style applied + // to it when displayed on a page which was fetched from + // the bfcache. + // + async function runTests() { + // Register our observer to know when the link lookup is complete. + let testURI = NetUtil.newURI(getHttpUrl("bug293235_p2.html")); + let os = SpecialPowers.Services.obs; + // Load a test page containing a link that should be initially + // blue, per the :link style. + await new Promise(resolve => { + doPageNavigation({ + uri: getHttpUrl("bug293235.html"), + onNavComplete: resolve, + }); + }); + + // Now that we've been notified, we can check our link color. + // Since we can't use getComputedStyle() for this because + // getComputedStyle lies about styles that result from :visited, + // we have to take snapshots. + // First, take two reference snapshots. + var link1 = $("link1"); + link1.className = "forcelink"; + var refLink = await snapshotWindow(TestWindow.getWindow()); + link1.className = "forcevisited"; + var refVisited = await snapshotWindow(TestWindow.getWindow()); + link1.className = ""; + function snapshotsEqual(snap1, snap2) { + return compareSnapshots(snap1, snap2, true)[0]; + } + ok(!snapshotsEqual(refLink, refVisited), "references should not match"); + ok(snapshotsEqual(refLink, await snapshotWindow(TestWindow.getWindow())), + "link should initially be blue"); + + let observedVisit = false, observedPageShow = false; + await new Promise(resolve => { + function maybeResolve() { + ok(true, "maybe run next test? visited: " + observedVisit + " pageShow: " + observedPageShow); + if (observedVisit && observedPageShow) + resolve(); + } + + // Because adding visits is async, we will not be notified immediately. + let visitObserver = { + observe(aSubject, aTopic, aData) + { + if (!testURI.equals(aSubject.QueryInterface(Ci.nsIURI))) { + return; + } + os.removeObserver(this, aTopic); + observedVisit = true; + maybeResolve(); + }, + }; + os.addObserver(visitObserver, "uri-visit-saved"); + // Load the page that the link on the previous page points to. + doPageNavigation({ + uri: getHttpUrl("bug293235_p2.html"), + onNavComplete() { + observedPageShow = true; + maybeResolve(); + } + }); + }) + + // And the nodes get notified after the "uri-visit-saved" topic, so + // we need to execute soon... + await new Promise(SimpleTest.executeSoon); + + // Go back, verify the original page was loaded from the bfcache, + // and verify that the link is now purple, per the + // :visited style. + await new Promise(resolve => { + doPageNavigation({ + back: true, + eventsToListenFor: ["pageshow"], + expectedEvents: [ { type: "pageshow", + persisted: true, + title: "Bug 293235 page1" } ], + onNavComplete: resolve, + }); + }) + + // Now we can test the link color. + ok(snapshotsEqual(refVisited, await snapshotWindow(TestWindow.getWindow())), + "visited link should be purple"); + + // Tell the framework the test is finished. + finish(); + } + + ]]></script> + + <browser type="content" primary="true" flex="1" id="content" src="about:blank"/> +</window> diff --git a/docshell/test/chrome/bug294258_testcase.html b/docshell/test/chrome/bug294258_testcase.html new file mode 100644 index 0000000000..cd80fefd06 --- /dev/null +++ b/docshell/test/chrome/bug294258_testcase.html @@ -0,0 +1,43 @@ +<?xml version="1.0" encoding="utf-8"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" +"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> + <head> + <title>Bug 294258 Testcase</title> + <meta http-equiv="Content-Type" content="application/xhtml+xml"/> + <style type="text/css"> + * { + font-family: monospace; + } + </style> + </head> + <body> + <div> + <p> + input type="text": <input id="text" type="text"/> + </p> + <p> + input type="checkbox": <input id="checkbox" type="checkbox"/> + </p> + <p> + input type="file": <input id="file" type="file"/> + </p> + <p> + input type="radio": + <input type="radio" id="radio1" name="radio" value="radio1"/> + <input id="radio2" type="radio" name="radio" value="radio2"/> + </p> + <p> + textarea: <textarea id="textarea" rows="4" cols="80"></textarea> + </p> + <p> + select -> option: <select id="select"> + <option>1</option> + <option>2</option> + <option>3</option> + <option>4</option> + </select> + </p> + </div> + </body> +</html> diff --git a/docshell/test/chrome/bug294258_window.xhtml b/docshell/test/chrome/bug294258_window.xhtml new file mode 100644 index 0000000000..fe47f3e70f --- /dev/null +++ b/docshell/test/chrome/bug294258_window.xhtml @@ -0,0 +1,72 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> + +<window id="294258Test" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + width="600" + height="600" + onload="setTimeout(nextTest, 0);" + title="bug 294258 test"> + + <script type="application/javascript" src= "chrome://mochikit/content/chrome-harness.js" /> + <script type="application/javascript" src="docshell_helpers.js" /> + <script type="application/javascript"><![CDATA[ + + // Define the generator-iterator for the tests. + var tests = testIterator(); + + //// + // Execute the next test in the generator function. + // + function nextTest() { + tests.next(); + } + + function $(id) { return TestWindow.getDocument().getElementById(id); } + + //// + // Generator function for test steps for bug 294258: + // Form values should be preserved on reload. + // + function* testIterator() + { + // Load a page containing a form. + doPageNavigation( { + uri: getHttpUrl("bug294258_testcase.html"), + onNavComplete: nextTest + } ); + yield undefined; + + // Change the data for each of the form fields, and reload. + $("text").value = "text value"; + $("checkbox").checked = true; + var file = SpecialPowers.Services.dirsvc.get("TmpD", Ci.nsIFile); + file.append("294258_test.file"); + file.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0o666); + let filePath = file.path; + $("file").value = filePath; + $("textarea").value = "textarea value"; + $("radio1").checked = true; + $("select").selectedIndex = 2; + doPageNavigation( { + reload: true, + onNavComplete: nextTest + } ); + yield undefined; + + // Verify that none of the form data has changed. + is($("text").value, "text value", "Text value changed"); + is($("checkbox").checked, true, "Checkbox value changed"); + is($("file").value, filePath, "File value changed"); + is($("textarea").value, "textarea value", "Textarea value changed"); + is($("radio1").checked, true, "Radio value changed"); + is($("select").selectedIndex, 2, "Select value changed"); + + // Tell the framework the test is finished. + finish(); + } + + ]]></script> + + <browser type="content" primary="true" flex="1" id="content" src="about:blank"/> +</window> diff --git a/docshell/test/chrome/bug298622_window.xhtml b/docshell/test/chrome/bug298622_window.xhtml new file mode 100644 index 0000000000..38abf35107 --- /dev/null +++ b/docshell/test/chrome/bug298622_window.xhtml @@ -0,0 +1,135 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> + +<window id="298622Test" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + width="600" + height="600" + onload="setTimeout(runTest, 0);" + title="bug 298622 test"> + + <script type="application/javascript" src= "chrome://mochikit/content/chrome-harness.js" /> + <script type="application/javascript" src= "docshell_helpers.js" /> + <script type="application/javascript"><![CDATA[ + // Global variable that holds a reference to the find bar. + var gFindBar; + + //// + // Test for bug 298622: + // Find should work correctly on a page loaded from the + // bfcache. + // + async function runTest() + { + // Make sure bfcache is on. + enableBFCache(true); + + // Load a test page which contains some text to be found. + await promisePageNavigation({ + uri: "data:text/html,<html><head><title>test1</title></head>" + + "<body>find this!</body></html>", + }); + + // Load a second, dummy page, verifying that the original + // page gets stored in the bfcache. + await promisePageNavigation({ + uri: getHttpUrl("generic.html"), + eventsToListenFor: ["pageshow", "pagehide"], + expectedEvents: [ { type: "pagehide", + title: "test1", + persisted: true }, + { type: "pageshow", + title: "generic page" } ], + }); + + // Make sure we unsuppress painting before continuing + await new Promise(resolve => { + SimpleTest.executeSoon(resolve); + }); + + // Search for some text that's on the second page (but not on + // the first page), and verify that it can be found. + gFindBar = document.getElementById("FindToolbar"); + document.getElementById("cmd_find").doCommand(); + ok(!gFindBar.hidden, "failed to open findbar"); + gFindBar._findField.value = "A generic page"; + gFindBar._find(); + await new Promise(resolve => { + SimpleTest.executeSoon(resolve); + }); + + // Make sure Find bar's internal status is not 'notfound' + isnot(gFindBar._findField.getAttribute("status"), "notfound", + "Findfield status attribute should not have been 'notfound'" + + " after Find"); + + // Make sure the key events above have time to be processed + // before continuing + await promiseTrue(() => + SpecialPowers.spawn(document.getElementById("content"), [], function() { + return content.document.getSelection().toString().toLowerCase() == "a generic page"; + }), 20 + ); + + is(gFindBar._findField.value, "A generic page", + "expected text not present in find input field"); + is(await SpecialPowers.spawn(document.getElementById("content"), [], async function() { + return content.document.getSelection().toString().toLowerCase(); + }), + "a generic page", + "find failed on second page loaded"); + + // Go back to the original page and verify it's loaded from the + // bfcache. + await promisePageNavigation({ + back: true, + eventsToListenFor: ["pageshow"], + expectedEvents: [ { type: "pageshow", + title: "test1", + persisted: true } ], + }); + + // Search for some text that's on the original page (but not + // the dummy page loaded above), and verify that it can + // be found. + gFindBar = document.getElementById("FindToolbar"); + document.getElementById("cmd_find").doCommand(); + ok(!gFindBar.hidden, "failed to open findbar"); + gFindBar._findField.value = "find this"; + gFindBar._find(); + await new Promise(resolve => { + SimpleTest.executeSoon(resolve); + }); + + // Make sure Find bar's internal status is not 'notfound' + isnot(gFindBar._findField.getAttribute("status"), "notfound", + "Findfield status attribute should not have been 'notfound'" + + " after Find"); + + // Make sure the key events above have time to be processed + // before continuing + await promiseTrue(() => + SpecialPowers.spawn(document.getElementById("content"), [], function() { + return content.document.getSelection().toString().toLowerCase() == "find this"; + }), 20 + ); + + is(await SpecialPowers.spawn(document.getElementById("content"), [], async function() { + return content.document.getSelection().toString().toLowerCase(); + }), + "find this", + "find failed on page loaded from bfcache"); + + // Tell the framework the test is finished. + finish(); + } + + ]]></script> + + <commandset> + <command id="cmd_find" + oncommand="document.getElementById('FindToolbar').onFindCommand();"/> + </commandset> + <browser type="content" primary="true" flex="1" id="content" messagemanagergroup="test" remote="true" maychangeremoteness="true" /> + <findbar id="FindToolbar" browserid="content"/> +</window> diff --git a/docshell/test/chrome/bug301397_1.html b/docshell/test/chrome/bug301397_1.html new file mode 100644 index 0000000000..9943c2efe6 --- /dev/null +++ b/docshell/test/chrome/bug301397_1.html @@ -0,0 +1,9 @@ +<!DOCTYPE html> +<html> +<head> + <title>iframe parent</title> + </head> +<body> + <iframe id="iframe" src="bug301397_2.html"/> + </body> +</html> diff --git a/docshell/test/chrome/bug301397_2.html b/docshell/test/chrome/bug301397_2.html new file mode 100644 index 0000000000..4237107060 --- /dev/null +++ b/docshell/test/chrome/bug301397_2.html @@ -0,0 +1,10 @@ +<!DOCTYPE html> +<html> +<head> + <title>iframe content #1</title> + </head> +<body> + iframe page 1<br/> + <a id="link" href="bug301397_3.html">go to next page</a> + </body> +</html> diff --git a/docshell/test/chrome/bug301397_3.html b/docshell/test/chrome/bug301397_3.html new file mode 100644 index 0000000000..8d36e92461 --- /dev/null +++ b/docshell/test/chrome/bug301397_3.html @@ -0,0 +1,10 @@ +<!DOCTYPE html> +<html> +<head> + <title>iframe content #2</title> + </head> +<body> + iframe page 2<br/> + You made it! + </body> +</html> diff --git a/docshell/test/chrome/bug301397_4.html b/docshell/test/chrome/bug301397_4.html new file mode 100644 index 0000000000..5584a4554a --- /dev/null +++ b/docshell/test/chrome/bug301397_4.html @@ -0,0 +1,9 @@ +<!DOCTYPE html> +<html> +<head> + <title>dummy page, no iframe</title> + </head> +<body> + Just a boring test page, nothing special. + </body> +</html> diff --git a/docshell/test/chrome/bug301397_window.xhtml b/docshell/test/chrome/bug301397_window.xhtml new file mode 100644 index 0000000000..cbfa77f7fd --- /dev/null +++ b/docshell/test/chrome/bug301397_window.xhtml @@ -0,0 +1,218 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> + +<window id="301397Test" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + width="600" + height="600" + onload="setTimeout(runTest, 0);" + title="bug 301397 test"> + + <script type="application/javascript" src= "chrome://mochikit/content/chrome-harness.js" /> + <script type="application/javascript" src="docshell_helpers.js" /> + <script type="application/javascript"><![CDATA[ + Services.prefs.setBoolPref("browser.navigation.requireUserInteraction", false); + + //// + // Verifies that the given string exists in the innerHTML of the iframe + // content. + // + async function verifyIframeInnerHtml(string) { + var iframeInnerHtml = await SpecialPowers.spawn(document.getElementById("content"), [string], (string) => + content.document.getElementById("iframe").contentDocument.body.innerHTML); + ok(iframeInnerHtml.includes(string), + "iframe contains wrong document: " + iframeInnerHtml); + } + + //// + // Generator function for test steps for bug 301397: + // The correct page should be displayed in an iframe when + // navigating back and forwards, when the parent page + // occupies multiple spots in the session history. + // + async function runTest() + { + // Make sure the bfcache is enabled. + enableBFCache(8); + + // Load a dummy page. + await promisePageNavigation({ + uri: getHttpUrl("generic.html"), + }); + + // Load a page containing an iframe. + await promisePageNavigation({ + uri: getHttpUrl("bug301397_1.html"), + eventsToListenFor: ["pageshow", "pagehide"], + expectedEvents: [ { type: "pagehide", + title: "generic page", + persisted: true }, + { type: "pageshow", + title: "iframe content #1", + persisted: false }, // false on initial load + { type: "pageshow", + title: "iframe parent", + persisted: false } ], // false on initial load + }); + + // Click a link in the iframe to cause the iframe to navigate + // to a new page, and wait until the related pagehide/pageshow + // events have occurred. + let waitForLinkNavigation = promisePageEvents({ + eventsToListenFor: ["pageshow", "pagehide"], + expectedEvents: [ { type: "pagehide", + title: "iframe content #1", + persisted: false }, // false, subframe nav + { type: "pageshow", + title: "iframe content #2", + persisted: false } ], // false on initial load + }); + SpecialPowers.spawn(document.getElementById("content"), [], function() { + let iframe = content.document.getElementById("iframe"); + let link = iframe.contentDocument.getElementById("link"); + let event = iframe.contentDocument.createEvent("MouseEvents"); + event.initMouseEvent("click", true, true, iframe.contentWindow, + 0, 0, 0, 0, 0, + false, false, false, false, + 0, null); + link.dispatchEvent(event); + }); + await waitForLinkNavigation; + + // Load another dummy page. Verify that both the outgoing parent and + // iframe pages are stored in the bfcache. + await promisePageNavigation({ + uri: getHttpUrl("bug301397_4.html"), + eventsToListenFor: ["pageshow", "pagehide"], + expectedEvents: [ { type: "pagehide", + title: "iframe parent", + persisted: true }, + { type: "pagehide", + title: "iframe content #2", + persisted: true }, + { type: "pageshow", + title: "dummy page, no iframe", + persisted: false } ], // false on initial load + }); + + // Go back. The iframe should show the second page loaded in it. + // Both the parent and the iframe pages should be loaded from + // the bfcache. + await promisePageNavigation({ + back: true, + eventsToListenFor: ["pageshow", "pagehide"], + expectedEvents: [ { type: "pagehide", + title: "dummy page, no iframe", + persisted: true }, + { type: "pageshow", + persisted: true, + title: "iframe content #2" }, + { type: "pageshow", + persisted: true, + title: "iframe parent" } ], + }); + + verifyIframeInnerHtml("You made it"); + + // Go gack again. The iframe should show the first page loaded in it. + await promisePageNavigation({ + back: true, + eventsToListenFor: ["pageshow", "pagehide"], + expectedEvents: [ { type: "pagehide", + title: "iframe content #2", + persisted: false }, // false, subframe nav + { type: "pageshow", + title: "iframe content #1", + // false since this page was never stored + // in the bfcache in the first place + persisted: false } ], + }); + + verifyIframeInnerHtml("go to next page"); + + // Go back to the generic page. Now go forward to the last page, + // again verifying that the iframe shows the first and second + // pages in order. + await promisePageNavigation({ + back: true, + eventsToListenFor: ["pageshow", "pagehide"], + expectedEvents: [ { type: "pagehide", + title: "iframe parent", + persisted: true }, + { type: "pagehide", + title: "iframe content #1", + persisted: true }, + { type: "pageshow", + title: "generic page", + persisted: true } ], + }); + + await promisePageNavigation({ + forward: true, + eventsToListenFor: ["pageshow"], + expectedEvents: [ {type: "pageshow", + title: "iframe content #1", + persisted: true}, + {type: "pageshow", + title: "iframe parent", + persisted: true} ], + }); + + verifyIframeInnerHtml("go to next page"); + + await promisePageNavigation({ + forward: true, + eventsToListenFor: ["pageshow", "pagehide"], + expectedEvents: [ { type: "pagehide", + title: "iframe content #1", + persisted: false }, // false, subframe nav + { type: "pageshow", + title: "iframe content #2", + // false because the page wasn't stored in + // bfcache last time it was unloaded + persisted: false } ], + }); + + verifyIframeInnerHtml("You made it"); + + await promisePageNavigation({ + forward: true, + eventsToListenFor: ["pageshow", "pagehide"], + expectedEvents: [ { type: "pagehide", + title: "iframe parent", + persisted: true }, + { type: "pagehide", + title: "iframe content #2", + persisted: true }, + { type: "pageshow", + title: "dummy page, no iframe", + persisted: true } ], + }); + + // Go back once more, and again verify that the iframe shows the + // second page loaded in it. + await promisePageNavigation({ + back: true, + eventsToListenFor: ["pageshow", "pagehide"], + expectedEvents: [ { type: "pagehide", + title: "dummy page, no iframe", + persisted: true }, + { type: "pageshow", + persisted: true, + title: "iframe content #2" }, + { type: "pageshow", + persisted: true, + title: "iframe parent" } ], + }); + + verifyIframeInnerHtml("You made it"); + + Services.prefs.clearUserPref("browser.navigation.requireUserInteraction"); + // Tell the framework the test is finished. + finish(); + } + + ]]></script> + + <browser type="content" primary="true" flex="1" id="content" messagemanagergroup="test" remote="true" maychangeremoteness="true" /> +</window> diff --git a/docshell/test/chrome/bug303267.html b/docshell/test/chrome/bug303267.html new file mode 100644 index 0000000000..21b9f30311 --- /dev/null +++ b/docshell/test/chrome/bug303267.html @@ -0,0 +1,23 @@ +<html> +<head> + <title> + bug303267.html + </title> + </head> +<body onpageshow="showpageshowcount()"> +<script> +var pageshowcount = 0; +function showpageshowcount() { + pageshowcount++; + var div1 = document.getElementById("div1"); + while (div1.firstChild) { + div1.firstChild.remove(); + } + div1.appendChild(document.createTextNode( + "pageshowcount: " + pageshowcount)); +} +</script> +<div id="div1"> + </div> +</body> +</html> diff --git a/docshell/test/chrome/bug303267_window.xhtml b/docshell/test/chrome/bug303267_window.xhtml new file mode 100644 index 0000000000..741fab0021 --- /dev/null +++ b/docshell/test/chrome/bug303267_window.xhtml @@ -0,0 +1,83 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> + +<window id="303267Test" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + width="600" + height="600" + onload="setTimeout(runTests, 0);" + title="bug 303267 test"> + + <script type="application/javascript" src= "chrome://mochikit/content/chrome-harness.js" /> + <script type="application/javascript" src="docshell_helpers.js" /> + <script type="application/javascript"><![CDATA[ + //// + // Bug 303267: When a page is displayed from the bfcache, the script globals should + // remain intact from the page's initial load. + // + async function runTests() + { + // Load an initial test page which should be saved in the bfcache. + var navData = { + uri: getHttpUrl("bug303267.html"), + eventsToListenFor: ["pageshow"], + expectedEvents: [ {type: "pageshow", title: "bug303267.html"} ], + }; + await promisePageNavigation(navData); + + // Save the HTML of the test page for later comparison. + var originalHTML = await getInnerHTMLById("div1"); + + // Load a second test page. The first test page's pagehide event should + // have the .persisted property set to true, indicating that it was + // stored in the bfcache. + navData = { + uri: "data:text/html,<html><head><title>page2</title></head>" + + "<body>bug303267, page2</body></html>", + eventsToListenFor: ["pageshow", "pagehide"], + expectedEvents: [ {type: "pagehide", + title: "bug303267.html", + persisted: true}, + {type: "pageshow", + title: "page2"} ], + }; + await promisePageNavigation(navData); + + // Go back. Verify that the pageshow event for the original test page + // had a .persisted property of true, indicating that it came from the + // bfcache. + navData = { + back: true, + eventsToListenFor: ["pageshow", "pagehide"], + expectedEvents: [ {type: "pagehide", + title: "page2"}, + {type: "pageshow", + title: "bug303267.html", + persisted: true} ], + }; + await promisePageNavigation(navData); + + // After going back, if showpagecount() could access a global variable + // and change the test div's innerHTML, then we pass. Otherwise, it + // threw an exception and the following test will fail. + var newHTML = await getInnerHTMLById("div1"); + isnot(originalHTML, + newHTML, "HTML not updated on pageshow; javascript broken?"); + + // Tell the framework the test is finished. + finish(); + } + + //// + // Return the innerHTML of a particular element in the content document. + // + function getInnerHTMLById(id) { + return SpecialPowers.spawn(TestWindow.getBrowser(), [id], (id) => { + return content.document.getElementById(id).innerHTML; + }); + } + + ]]></script> + + <browser type="content" primary="true" flex="1" id="content" remote="true" maychangeremoteness="true" /> +</window> diff --git a/docshell/test/chrome/bug311007_window.xhtml b/docshell/test/chrome/bug311007_window.xhtml new file mode 100644 index 0000000000..13ae5e16e3 --- /dev/null +++ b/docshell/test/chrome/bug311007_window.xhtml @@ -0,0 +1,204 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> + +<window id="311007Test" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + width="600" + height="600" + onload="startup();" + title="bug 311007 test"> + + <script src="chrome://mochikit/content/chrome-harness.js" /> + <script type="application/javascript" src="docshell_helpers.js"></script> + <script type="application/javascript"><![CDATA[ + // `content` is the id of the browser element used for the test. + /* global content */ +/* + Regression test for bug 283733 and bug 307027. + + Bug 283733 + "accessing a relative anchor in a secure page removes the + locked icon and yellow background UI" + + Bug 307027 + "Going back from secure page to error page does not clear yellow bar" + + And enhancements: + + Bug 478927 + onLocationChange should notify whether or not loading an error page. + + */ + +const kDNSErrorURI = "https://example/err.html"; +const kSecureURI = + "https://example.com/tests/docshell/test/navigation/blank.html"; + +/* + Step 1: load a network error page. <err.html> Not Secure + Step 2: load a secure page. <blank.html> Secure + Step 3: a secure page + hashchange. <blank.html#foo> Secure (bug 283733) + Step 4: go back to the error page. <err.html> Not Secure (bug 307027) + */ + +var gListener = null; + +function WebProgressListener() { + this._callback = null; +} + +WebProgressListener.prototype = { + QueryInterface: ChromeUtils.generateQI([ + "nsIWebProgressListener", + "nsISupportsWeakReference", + ]), + + onLocationChange(aWebProgress, aRequest, aLocation, aFlags) { + setTimeout(this._callback, 0, aWebProgress, aRequest, aLocation, aFlags); + }, + + set callback(aVal) { + this._callback = aVal; + } +}; + +function startup() { + gListener = new WebProgressListener(); + + document.getElementById("content") + .webProgress + .addProgressListener(gListener, + Ci.nsIWebProgress + .NOTIFY_LOCATION); + + setTimeout(step1A, 0); +} + +/****************************************************************************** + * Step 1: Load an error page, and confirm UA knows it's insecure. + ******************************************************************************/ + +function step1A() { + gListener.callback = step1B; + content.location = kDNSErrorURI; +} + +function step1B(aWebProgress, aRequest, aLocation, aFlags) { + is(aLocation.spec, kDNSErrorURI, "Error page's URI (1)"); + + ok(!(aFlags & Ci.nsIWebProgressListener + .LOCATION_CHANGE_SAME_DOCUMENT), + "DocShell loaded a document (1)"); + + ok((aFlags & Ci.nsIWebProgressListener + .LOCATION_CHANGE_ERROR_PAGE), + "This page is an error page."); + + ok(!(document.getElementById("content") + .browsingContext + .secureBrowserUI.state & + Ci.nsIWebProgressListener.STATE_IS_SECURE), + "This is not a secure page (1)"); + + /* Go to step 2. */ + setTimeout(step2A, 0); +} + +/****************************************************************************** + * Step 2: Load a HTTPS page, and confirm it's secure. + ******************************************************************************/ + +function step2A() { + gListener.callback = step2B; + content.location = kSecureURI; +} + +function step2B(aWebProgress, aRequest, aLocation, aFlags) { + is(aLocation.spec, kSecureURI, "A URI on HTTPS (2)"); + + ok(!(aFlags & Ci.nsIWebProgressListener + .LOCATION_CHANGE_SAME_DOCUMENT), + "DocShell loaded a document (2)"); + + ok(!(aFlags & Ci.nsIWebProgressListener + .LOCATION_CHANGE_ERROR_PAGE), + "This page is not an error page."); + + ok((document.getElementById("content") + .browsingContext + .secureBrowserUI.state & + Ci.nsIWebProgressListener.STATE_IS_SECURE), + "This is a secure page (2)"); + + /* Go to step 3. */ + setTimeout(step3A, 0); +} + +/***************************************************************************** + * Step 3: Trigger hashchange within a secure page, and confirm UA knows + * it's secure. (Bug 283733) + *****************************************************************************/ + +function step3A() { + gListener.callback = step3B; + content.location += "#foo"; +} + +function step3B(aWebProgress, aRequest, aLocation, aFlags) { + is(aLocation.spec, kSecureURI + "#foo", "hashchange on HTTPS (3)"); + + ok((aFlags & Ci.nsIWebProgressListener + .LOCATION_CHANGE_SAME_DOCUMENT), + "We are in the same document as before (3)"); + + ok(!(aFlags & Ci.nsIWebProgressListener + .LOCATION_CHANGE_ERROR_PAGE), + "This page is not an error page."); + + ok((document.getElementById("content") + .browsingContext + .secureBrowserUI.state & + Ci.nsIWebProgressListener.STATE_IS_SECURE), + "This is a secure page (3)"); + + /* Go to step 4. */ + setTimeout(step4A, 0); +} + +/***************************************************************************** + * Step 4: Go back from a secure page to an error page, and confirm UA knows + * it's not secure. (Bug 307027) + *****************************************************************************/ + +function step4A() { + gListener.callback = step4B; + content.history.go(-2); +} + +function step4B(aWebProgress, aRequest, aLocation, aFlags) { + is(aLocation.spec, kDNSErrorURI, "Go back to the error URI (4)"); + + ok(!(aFlags & Ci.nsIWebProgressListener + .LOCATION_CHANGE_SAME_DOCUMENT), + "DocShell loaded a document (4)"); + + ok((aFlags & Ci.nsIWebProgressListener + .LOCATION_CHANGE_ERROR_PAGE), + "This page is an error page."); + + ok(!(document.getElementById("content") + .browsingContext + .secureBrowserUI.state & + Ci.nsIWebProgressListener.STATE_IS_SECURE), + "This is not a secure page (4)"); + + /* End. */ + document.getElementById("content") + .webProgress.removeProgressListener(gListener); + gListener = null; + finish(); +} + ]]></script> + + <browser type="content" primary="true" flex="1" id="content" src="about:blank"/> +</window> diff --git a/docshell/test/chrome/bug321671_window.xhtml b/docshell/test/chrome/bug321671_window.xhtml new file mode 100644 index 0000000000..60ab5e80d0 --- /dev/null +++ b/docshell/test/chrome/bug321671_window.xhtml @@ -0,0 +1,128 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> + +<window id="321671Test" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + width="600" + height="600" + onload="setTimeout(runTest, 0);" + title="bug 321671 test"> + + <script type="application/javascript" src="chrome://mochikit/content/chrome-harness.js" /> + <script type="application/javascript" src="docshell_helpers.js" /> + <script type="application/javascript"><![CDATA[ + Services.prefs.setBoolPref("browser.navigation.requireUserInteraction", false); + + // Maximum number of entries in the bfcache for this session history. + // This number is hardcoded in docshell code. In the test, we'll + // navigate through enough pages so that we hit one that's been + // evicted from the bfcache because it's farther from the current + // page than this number. + const MAX_BFCACHE_PAGES = 3; + + //// + // Bug 321671: Scroll position should be retained when moving backwards and + // forwards through pages when bfcache is enabled. + // + async function runTest() + { + // Variable to hold the scroll positions of the test pages. + var scrollPositions = []; + + // Make sure bfcache is on. + enableBFCache(true); + + // Load enough test pages that so the first one is evicted from the + // bfcache, scroll down on each page, and save the + // current scroll position before continuing. Verify that each + // page we're navigating away from is initially put into the bfcache. + for (var i = 0; i <= MAX_BFCACHE_PAGES + 1; i++) { + let eventsToListenFor = ["pageshow"]; + let expectedEvents = [ { type: "pageshow", + title: "bug321671 page" + (i + 1) } ]; + if (i > 0) { + eventsToListenFor.push("pagehide"); + expectedEvents.unshift({ type: "pagehide", + persisted: true, + title: "bug321671 page" + i }); + } + await promisePageNavigation( { + uri: "data:text/html,<html><head><title>bug321671 page" + (i + 1) + + "</title></head>" + + "<body><table border='1' width='300' height='1000'>" + + "<tbody><tr><td>" + + " page " + (i + 1) + ": foobar foobar foobar foobar " + + "</td></tr></tbody></table> " + + "</body></html>", + eventsToListenFor, + expectedEvents, + } ); + + let { initialScrollY, scrollY } = await SpecialPowers.spawn(TestWindow.getBrowser(), [i], (i) => { + let initialScrollY = content.scrollY; + content.scrollByLines(10 + (2 * i)); + return { initialScrollY, scrollY: content.scrollY }; + }); + is(initialScrollY, 0, + "Page initially has non-zero scrollY position"); + ok(scrollY > 0, + "Page has zero scrollY position after scrolling"); + scrollPositions[i] = scrollY; + } + + // Go back to the first page, one page at a time. For each 'back' + // action, verify that its vertical scroll position is restored + // correctly. Verify that the last page in the sequence + // does not come from the bfcache. Again verify that all pages + // that we navigate away from are initially + // stored in the bfcache. + for (i = MAX_BFCACHE_PAGES + 1; i > 0; i--) { + await promisePageNavigation( { + back: true, + eventsToListenFor: ["pageshow", "pagehide"], + expectedEvents: [ { type: "pagehide", + title: "bug321671 page" + (i+1), + persisted: true }, + { type: "pageshow", + title: "bug321671 page" + i, + persisted: i > 1 } ], + } ); + + is(await SpecialPowers.spawn(TestWindow.getBrowser(), [], () => { + return content.scrollY; + }), scrollPositions[i-1], + "Scroll position not restored while going back!"); + } + + // Traverse history forward now, and verify scroll position is still + // restored. Similar to the backward traversal, verify that all + // but the last page in the sequence comes from the bfcache. Also + // verify that all of the pages get stored in the bfcache when we + // navigate away from them. + for (i = 1; i <= MAX_BFCACHE_PAGES + 1; i++) { + await promisePageNavigation( { + forward: true, + eventsToListenFor: ["pageshow", "pagehide"], + expectedEvents: [ { type: "pagehide", + persisted: true, + title: "bug321671 page" + i }, + { type: "pageshow", + persisted: i < MAX_BFCACHE_PAGES + 1, + title: "bug321671 page" + (i + 1) } ], + } ); + + is(await SpecialPowers.spawn(TestWindow.getBrowser(), [], () => { + return content.scrollY; + }), scrollPositions[i], + "Scroll position not restored while going forward!"); + } + + Services.prefs.clearUserPref("browser.navigation.requireUserInteraction"); + // Tell the framework the test is finished. + finish(); + } + + ]]></script> + + <browser type="content" primary="true" flex="1" id="content" remote="true" maychangeremoteness="true" /> +</window> diff --git a/docshell/test/chrome/bug360511_case1.html b/docshell/test/chrome/bug360511_case1.html new file mode 100644 index 0000000000..cca043bb66 --- /dev/null +++ b/docshell/test/chrome/bug360511_case1.html @@ -0,0 +1,15 @@ +<!DOCTYPE html> +<html style="height: 100%"> +<head> + <title> + bug360511 case 1 + </title> + </head> +<body style="height: 100%"> +<a id="link1" href="#bottom">jump to bottom</a> +<div id="div1" style="height: 200%; border: thin solid black;"> + hello large div + </div> + <a name="bottom">here's the bottom of the page</a> +</body> +</html> diff --git a/docshell/test/chrome/bug360511_case2.html b/docshell/test/chrome/bug360511_case2.html new file mode 100644 index 0000000000..217f47724e --- /dev/null +++ b/docshell/test/chrome/bug360511_case2.html @@ -0,0 +1,15 @@ +<!DOCTYPE html> +<html style="height: 100%"> +<head> + <title> + bug360511 case 2 + </title> + </head> +<body style="height: 100%"> +<a id="link1" href="#bottom">jump to bottom</a> +<div id="div1" style="height: 200%; border: thin solid black;"> + hello large div + </div> + <a name="bottom">here's the bottom of the page</a> +</body> +</html> diff --git a/docshell/test/chrome/bug360511_window.xhtml b/docshell/test/chrome/bug360511_window.xhtml new file mode 100644 index 0000000000..cfb0845ef7 --- /dev/null +++ b/docshell/test/chrome/bug360511_window.xhtml @@ -0,0 +1,127 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> + +<window id="360511Test" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + width="600" + height="600" + onload="setTimeout(runTest, 0);" + title="bug 360511 test"> + + <script type="application/javascript" src= "chrome://mochikit/content/chrome-harness.js" /> + <script type="application/javascript" src="docshell_helpers.js" /> + <script type="application/javascript"><![CDATA[ + Services.prefs.setBoolPref("browser.navigation.requireUserInteraction", false); + + function getScrollY() + { + return SpecialPowers.spawn(TestWindow.getBrowser(), [], () => { + return content.scrollY; + }); + } + function getLocation() + { + return SpecialPowers.spawn(TestWindow.getBrowser(), [], () => { + return content.location.href; + }); + } + + //// + // Bug 360511: Fragment uri's in session history should be restored correctly + // upon back navigation. + // + async function runTest() + { + // Case 1: load a page containing a fragment link; the page should be + // stored in the bfcache. + // Case 2: load a page containing a fragment link; the page should NOT + // be stored in the bfcache. + for (var i = 1; i < 3; i++) + { + var url = "bug360511_case" + i + ".html"; + await promisePageNavigation( { + uri: getHttpUrl(url), + preventBFCache: i != 1 + } ); + + // Store the original url for later comparison. + var originalUrl = TestWindow.getBrowser().currentURI.spec; + var originalDocLocation = await getLocation(); + + // Verify we're at the top of the page. + is(await getScrollY(), 0, "Page initially has a non-zero scrollY property"); + + // Click the on the fragment link in the browser, and use setTimeout + // to give the event a chance to be processed. + await SpecialPowers.spawn(TestWindow.getBrowser(), [], () => { + var event = content.document.createEvent('MouseEvent'); + event.initMouseEvent("click", true, true, content, 0, + 0, 0, 0, 0, + false, false, false, false, 0, null); + content.document.getElementById("link1").dispatchEvent(event); + }); + await promiseNextPaint(); + + // Verify we're no longer at the top of the page. + await promiseTrue(async function() { + return await getScrollY() > 0; + }, 20); + + // Store the fragment url for later comparison. + var fragmentUrl = TestWindow.getBrowser().currentURI.spec; + let fragDocLocation = await getLocation(); + + // Now navigate to any other page + var expectedPageTitle = "bug360511 case " + i; + await promisePageNavigation( { + uri: getHttpUrl("generic.html"), + eventsToListenFor: ["pagehide", "pageshow"], + expectedEvents: [ {type: "pagehide", title: expectedPageTitle, + persisted: i == 1}, + {type: "pageshow"} ], + } ); + + // Go back + await promisePageNavigation( { + back: true, + eventsToListenFor: ["pageshow"], + expectedEvents: [ {type: "pageshow", title: expectedPageTitle, + persisted: i == 1} ], + } ); + + // Verify the current url is the fragment url + is(TestWindow.getBrowser().currentURI.spec, fragmentUrl, + "current url is not the previous fragment url"); + is(await getLocation(), fragDocLocation, + "document.location is not the previous fragment url"); + + // Go back again. Since we're just going from a fragment url to + // parent url, no pageshow event is fired, so don't wait for any + // events. Rather, just wait for the page's scrollY property to + // change. + var originalScrollY = await getScrollY(); + doPageNavigation( { + back: true, + eventsToListenFor: [] + } ); + await promiseTrue( + async function() { + return (await getScrollY() != originalScrollY); + }, 20); + + // Verify the current url is the original url without fragment + is(TestWindow.getBrowser().currentURI.spec, originalUrl, + "current url is not the original url"); + is(await getLocation(), originalDocLocation, + "document.location is not the original url"); + } + + Services.prefs.clearUserPref("browser.navigation.requireUserInteraction"); + // Tell the framework the test is finished. + finish(); + } + + ]]></script> + + <browser type="content" primary="true" flex="1" id="content" remote="true" maychangeremoteness="true" /> +</window> diff --git a/docshell/test/chrome/bug364461_window.xhtml b/docshell/test/chrome/bug364461_window.xhtml new file mode 100644 index 0000000000..938a015e73 --- /dev/null +++ b/docshell/test/chrome/bug364461_window.xhtml @@ -0,0 +1,253 @@ +<?xml version="1.0"?> + +<!-- This Source Code Form is subject to the terms of the Mozilla Public + - License, v. 2.0. If a copy of the MPL was not distributed with this + - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> + +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> + +<window id="364461Test" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + width="600" + height="600" + onload="runTest();" + title="364461 test"> + + <script src="chrome://mochikit/content/chrome-harness.js" /> + <script type="application/javascript" src="docshell_helpers.js" /> + <script type="application/javascript"><![CDATA[ + Services.prefs.setBoolPref("browser.navigation.requireUserInteraction", false); + + var gBrowser; + + async function runTest() { + gBrowser = document.getElementById("content"); + + // Tests 1 + 2: + // Back/forward between two simple documents. Bfcache will be used. + + var test1Doc = "data:text/html,<html><head><title>test1</title></head>" + + "<body>test1</body></html>"; + + await promisePageNavigation({ + uri: test1Doc, + eventsToListenFor: ["load", "pageshow"], + expectedEvents: [{type: "load", title: "test1"}, + {type: "pageshow", title: "test1", persisted: false}], + }); + + var test2Doc = "data:text/html,<html><head><title>test2</title></head>" + + "<body>test2</body></html>"; + + await promisePageNavigation({ + uri: test2Doc, + eventsToListenFor: ["load", "pageshow", "pagehide"], + expectedEvents: [{type: "pagehide", title: "test1", persisted: true}, + {type: "load", title: "test2"}, + {type: "pageshow", title: "test2", persisted: false}], + }); + + await promisePageNavigation({ + back: true, + eventsToListenFor: ["pageshow", "pagehide"], + expectedEvents: [{type: "pagehide", title: "test2", persisted: true}, + {type: "pageshow", title: "test1", persisted: true}], + }); + + await promisePageNavigation({ + forward: true, + eventsToListenFor: ["pageshow", "pagehide"], + expectedEvents: [{type: "pagehide", title: "test1", persisted: true}, + {type: "pageshow", title: "test2", persisted: true}], + }); + + // Tests 3 + 4: + // Back/forward between a two-level deep iframed document and a simple + // document. Bfcache will be used and events should be dispatched to + // all frames. + + var test3Doc = "data:text/html,<html><head><title>test3</title>" + + "</head><body>" + + "<iframe src='data:text/html," + + "<html><head><title>test3-nested1</title></head>" + + "<body>test3-nested1" + + "<iframe src=\"data:text/html," + + "<html><head><title>test3-nested2</title></head>" + + "<body>test3-nested2</body></html>\">" + + "</iframe>" + + "</body></html>'>" + + "</iframe>" + + "</body></html>"; + + await promisePageNavigation({ + uri: test3Doc, + eventsToListenFor: ["load", "pageshow", "pagehide"], + expectedEvents: [{type: "pagehide", title: "test2", persisted: true}, + {type: "load", title: "test3-nested2"}, + {type: "pageshow", title: "test3-nested2", persisted: false}, + {type: "load", title: "test3-nested1"}, + {type: "pageshow", title: "test3-nested1", persisted: false}, + {type: "load", title: "test3"}, + {type: "pageshow", title: "test3", persisted: false}], + }); + + var test4Doc = "data:text/html,<html><head><title>test4</title></head>" + + "<body>test4</body></html>"; + + await promisePageNavigation({ + uri: test4Doc, + eventsToListenFor: ["load", "pageshow", "pagehide"], + expectedEvents: [{type: "pagehide", title: "test3", persisted: true}, + {type: "pagehide", title: "test3-nested1", persisted: true}, + {type: "pagehide", title: "test3-nested2", persisted: true}, + {type: "load", title: "test4"}, + {type: "pageshow", title: "test4", persisted: false}], + }); + + await promisePageNavigation({ + back: true, + eventsToListenFor: ["pageshow", "pagehide"], + expectedEvents: [{type: "pagehide", title: "test4", persisted: true}, + {type: "pageshow", title: "test3-nested2", persisted: true}, + {type: "pageshow", title: "test3-nested1", persisted: true}, + {type: "pageshow", title: "test3", persisted: true}], + }); + + // This is where the two nested pagehide are not dispatched in bug 364461 + await promisePageNavigation({ + forward: true, + eventsToListenFor: ["pageshow", "pagehide"], + expectedEvents: [{type: "pagehide", title: "test3", persisted: true}, + {type: "pagehide", title: "test3-nested1", persisted: true}, + {type: "pagehide", title: "test3-nested2", persisted: true}, + {type: "pageshow", title: "test4", persisted: true}], + }); + + // Tests 5 + 6: + // Back/forward between a document containing an unload handler and a + // a simple document. Bfcache won't be used for the first one (see + // http://developer.mozilla.org/en/docs/Using_Firefox_1.5_caching). + + var test5Doc = "data:text/html,<html><head><title>test5</title></head>" + + "<body onunload='while(false) { /* nop */ }'>" + + "test5</body></html>"; + + await promisePageNavigation({ + uri: test5Doc, + eventsToListenFor: ["load", "pageshow", "pagehide"], + expectedEvents: [{type: "pagehide", title: "test4", persisted: true}, + {type: "load", title: "test5"}, + {type: "pageshow", title: "test5", persisted: false}], + }); + + var test6Doc = "data:text/html,<html><head><title>test6</title></head>" + + "<body>test6</body></html>"; + + await promisePageNavigation({ + uri: test6Doc, + eventsToListenFor: ["load", "unload", "pageshow", "pagehide"], + expectedEvents: [{type: "pagehide", title: "test5", persisted: false}, + {type: "unload", title: "test5"}, + {type: "load", title: "test6"}, + {type: "pageshow", title: "test6", persisted: false}], + }); + + await promisePageNavigation({ + back: true, + eventsToListenFor: ["load", "pageshow", "pagehide"], + expectedEvents: [{type: "pagehide", title: "test6", persisted: true}, + {type: "load", title: "test5"}, + {type: "pageshow", title: "test5", persisted: false}], + }); + + await promisePageNavigation({ + forward: true, + eventsToListenFor: ["unload", "pageshow", "pagehide"], + expectedEvents: [{type: "pagehide", title: "test5", persisted: false}, + {type: "unload", title: "test5"}, + {type: "pageshow", title: "test6", persisted: true}], + }); + + // Test 7: + // Testcase from https://bugzilla.mozilla.org/show_bug.cgi?id=384977#c10 + // Check that navigation is not blocked after a document is restored + // from bfcache + + var test7Doc = "data:text/html,<html><head><title>test7</title>" + + "</head><body>" + + "<iframe src='data:text/html," + + "<html><head><title>test7-nested1</title></head>" + + "<body>test7-nested1<br/>" + + "<a href=\"data:text/plain,aaa\" target=\"_top\">" + + "Click me, hit back, click me again</a>" + + "</body></html>'>" + + "</iframe>" + + "</body></html>"; + + await promisePageNavigation({ + uri: test7Doc, + eventsToListenFor: ["load", "pageshow", "pagehide"], + expectedEvents: [{type: "pagehide", title: "test6", persisted: true}, + {type: "load", title: "test7-nested1"}, + {type: "pageshow", title: "test7-nested1", persisted: false}, + {type: "load", title: "test7"}, + {type: "pageshow", title: "test7", persisted: false}], + }); + + // Simulates a click on the link inside the iframe + function clickIframeLink() { + SpecialPowers.spawn(TestWindow.getBrowser(), [], () => { + var iframe = content.document.getElementsByTagName("iframe")[0]; + var w = iframe.contentWindow; + var d = iframe.contentDocument; + + var evt = d.createEvent("MouseEvents"); + evt.initMouseEvent("click", true, true, w, + 0, 0, 0, 0, 0, false, false, false, false, 0, null); + d.getElementsByTagName("a")[0].dispatchEvent(evt); + }); + } + + let clicked = promisePageNavigation({ + eventsToListenFor: ["load", "pageshow", "pagehide"], + expectedEvents: [{type: "pagehide", title: "test7", persisted: true}, + {type: "pagehide", title: "test7-nested1", persisted: true}, + {type: "load"}, + {type: "pageshow", persisted: false}], + waitForEventsOnly: true, + }); + clickIframeLink(); + await clicked; + + is(gBrowser.currentURI.spec, "data:text/plain,aaa", + "Navigation is blocked when clicking link"); + + await promisePageNavigation({ + back: true, + eventsToListenFor: ["pageshow", "pagehide"], + expectedEvents: [{type: "pagehide", persisted: true}, + {type: "pageshow", title: "test7-nested1", persisted: true}, + {type: "pageshow", title: "test7", persisted: true}], + }); + + clicked = promisePageNavigation({ + eventsToListenFor: ["load", "pageshow", "pagehide"], + expectedEvents: [{type: "pagehide", title: "test7", persisted: true}, + {type: "pagehide", title: "test7-nested1", persisted: true}, + {type: "load"}, + {type: "pageshow", persisted: false}], + waitForEventsOnly: true, + }); + clickIframeLink(); + await clicked; + + is(gBrowser.currentURI.spec, "data:text/plain,aaa", + "Navigation is blocked when clicking link"); + + Services.prefs.clearUserPref("browser.navigation.requireUserInteraction"); + finish(); + } + ]]></script> + + <browser type="content" primary="true" flex="1" id="content" remote="true" maychangeremoteness="true" /> +</window> diff --git a/docshell/test/chrome/bug396519_window.xhtml b/docshell/test/chrome/bug396519_window.xhtml new file mode 100644 index 0000000000..a5ecbeb3e8 --- /dev/null +++ b/docshell/test/chrome/bug396519_window.xhtml @@ -0,0 +1,132 @@ +<?xml version="1.0"?> + +<!-- This Source Code Form is subject to the terms of the Mozilla Public + - License, v. 2.0. If a copy of the MPL was not distributed with this + - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> + +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> + +<window id="396519Test" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + width="600" + height="600" + onload="runTest();" + title="396519 test"> + + <script src="chrome://mochikit/content/chrome-harness.js" /> + <script type="application/javascript" src="docshell_helpers.js" /> + <script type="application/javascript"><![CDATA[ + Services.prefs.setBoolPref("browser.navigation.requireUserInteraction", false); + + var gTestCount = 0; + + async function navigateAndTest(params, expected) { + await promisePageNavigation(params); + ++gTestCount; + await doTest(expected); + } + + async function doTest(expected) { + function check(testCount, expected) { + let history; + if (SpecialPowers.Services.appinfo.sessionHistoryInParent) { + history = this.browsingContext.sessionHistory; + } else { + history = this.content.browsingContext.childSessionHistory.legacySHistory; + } + if (history.count == expected.length) { + for (let i = 0; i < history.count; i++) { + var shEntry = history.getEntryAtIndex(i). + QueryInterface(Ci.nsISHEntry); + is(shEntry.isInBFCache, expected[i], `BFCache for shentry[${i}], test ${testCount}`); + } + + // Make sure none of the SHEntries share bfcache entries with one + // another. + for (let i = 0; i < history.count; i++) { + for (let j = 0; j < history.count; j++) { + if (j == i) + continue; + + let shentry1 = history.getEntryAtIndex(i) + .QueryInterface(Ci.nsISHEntry); + let shentry2 = history.getEntryAtIndex(j) + .QueryInterface(Ci.nsISHEntry); + ok(!shentry1.sharesDocumentWith(shentry2), + 'Test ' + testCount + ': shentry[' + i + "] shouldn't " + + "share document with shentry[" + j + ']'); + } + } + } + else { + is(history.count, expected.length, "Wrong history length in test "+testCount); + } + } + + if (SpecialPowers.Services.appinfo.sessionHistoryInParent) { + check.call(TestWindow.getBrowser(), gTestCount, expected); + } else { + await SpecialPowers.spawn(TestWindow.getBrowser(), [gTestCount, expected], check); + } + } + + async function runTest() { + // Tests 1 + 2: + // Back/forward between two simple documents. Bfcache will be used. + + var test1Doc = "data:text/html,<html><head><title>test1</title></head>" + + "<body>test1</body></html>"; + + await navigateAndTest({ + uri: test1Doc, + }, [false]); + + var test2Doc = test1Doc.replace(/1/,"2"); + + await navigateAndTest({ + uri: test2Doc, + }, [true, false]); + + await navigateAndTest({ + uri: test1Doc, + }, [true, true, false]); + + await navigateAndTest({ + uri: test2Doc, + }, [true, true, true, false]); + + await navigateAndTest({ + uri: test1Doc, + }, [false, true, true, true, false]); + + await navigateAndTest({ + uri: test2Doc, + }, [false, false, true, true, true, false]); + + await navigateAndTest({ + back: true, + }, [false, false, true, true, false, true]); + + await navigateAndTest({ + forward: true, + }, [false, false, true, true, true, false]); + + await navigateAndTest({ + gotoIndex: 1, + }, [false, false, true, true, true, false]); + + await navigateAndTest({ + back: true, + }, [false, true, true, true, false, false]); + + await navigateAndTest({ + gotoIndex: 5, + }, [false, false, true, true, false, false]); + + Services.prefs.clearUserPref("browser.navigation.requireUserInteraction"); + finish(); + } + ]]></script> + + <browser type="content" primary="true" flex="1" id="content" remote="true" maychangeremoteness="true" /> +</window> diff --git a/docshell/test/chrome/bug396649_window.xhtml b/docshell/test/chrome/bug396649_window.xhtml new file mode 100644 index 0000000000..c378f11dc3 --- /dev/null +++ b/docshell/test/chrome/bug396649_window.xhtml @@ -0,0 +1,119 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> + +<window id="396649Test" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + width="600" + height="600" + onload="setTimeout(nextTest, 0);" + title="bug 396649 test"> + + <script type="application/javascript" src= "chrome://mochikit/content/chrome-harness.js" /> + <script type="application/javascript" src="docshell_helpers.js" /> + <script type="application/javascript"><![CDATA[ + Services.prefs.setBoolPref("browser.navigation.requireUserInteraction", false); + + // Define the generator-iterator for the tests. + var tests = testIterator(); + + // Maximum number of entries in the bfcache for this session history. + // This number is hardcoded in docshell code. In the test, we'll + // navigate through enough pages so that we hit one that's been + // evicted from the bfcache because it's farther from the current + // page than this number. + const MAX_BFCACHE_PAGES = 3; + + //// + // Execute the next test in the generator function. + // + function nextTest() { + tests.next(); + } + + //// + // Generator function for test steps for bug 396649: Content + // viewers should be evicted from bfcache when going back if more + // than MAX_BFCACHE_PAGES from the current index. + // + function* testIterator() + { + // Make sure bfcache is on. + enableBFCache(true); + + // Load enough pages so that the first loaded is eviced from + // the bfcache, since it is greater the MAX_BFCACHE_PAGES from + // the current position in the session history. Verify all + // of the pages are initially stored in the bfcache when + // they're unloaded. + for (var i = 0; i <= MAX_BFCACHE_PAGES + 1; i++) { + let eventsToListenFor = ["pageshow"]; + let expectedEvents = [ { type: "pageshow", + title: "bug396649 page" + i } ]; + if (i > 0) { + eventsToListenFor.push("pagehide"); + expectedEvents.unshift({ type: "pagehide", + title: "bug396649 page" + (i-1) }); + } + doPageNavigation( { + uri: "data:text/html,<!DOCTYPE html><html>" + + "<head><title>bug396649 page" + i + + "</title></head>" + + "<body>" + + "test page " + i + + "</body></html>", + eventsToListenFor, + expectedEvents, + onNavComplete: nextTest + } ); + yield undefined; + } + + // Go back to the first page, one page at a time. The first + // MAX_BFCACHE_PAGES pages loaded via back should come from the bfcache, + // the last should not, since it should have been evicted during the + // previous navigation sequence. Verify all pages are initially stored + // in the bfcache when they're unloaded. + for (i = MAX_BFCACHE_PAGES + 1; i > 0; i--) { + doPageNavigation( { + back: true, + eventsToListenFor: ["pageshow", "pagehide"], + expectedEvents: [ { type: "pagehide", + title: "bug396649 page" + i, + persisted: true }, + { type: "pageshow", + title: "bug396649 page" + (i - 1), + persisted: i > 1 } ], + onNavComplete: nextTest + } ); + yield undefined; + } + + // Traverse history forward now. Again, the first MAX_BFCACHE_PAGES + // pages should come from the bfcache, the last should not, + // since it should have been evicted during the backwards + // traversal above. Verify all pages are initially stored + // in the bfcache when they're unloaded. + for (i = 1; i <= MAX_BFCACHE_PAGES + 1; i++) { + doPageNavigation( { + forward: true, + eventsToListenFor: ["pageshow", "pagehide"], + expectedEvents: [ { type: "pagehide", + title: "bug396649 page" + (i-1), + persisted: true }, + { type: "pageshow", + title: "bug396649 page" + i, + persisted: i < MAX_BFCACHE_PAGES + 1 } ], + onNavComplete: nextTest + } ); + yield undefined; + } + + Services.prefs.clearUserPref("browser.navigation.requireUserInteraction"); + // Tell the framework the test is finished. + finish(); + } + + ]]></script> + + <browser type="content" primary="true" flex="1" id="content" remote="true" maychangeremoteness="true" /> +</window> diff --git a/docshell/test/chrome/bug449778_window.xhtml b/docshell/test/chrome/bug449778_window.xhtml new file mode 100644 index 0000000000..3197b7acf4 --- /dev/null +++ b/docshell/test/chrome/bug449778_window.xhtml @@ -0,0 +1,107 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<window title="Mozilla Bug 449778" onload="doTheTest()" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + + <hbox id="parent"> + </hbox> + + <!-- test code goes here --> + <script type="application/javascript"><![CDATA[ + /* globals SimpleTest, is */ + var imports = [ "SimpleTest", "is" ]; + for (var name of imports) { + window[name] = window.arguments[0][name]; + } + + function $(id) { + return document.getElementById(id); + } + + function addBrowser(parent, id, width, height) { + var b = + document.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul", "browser"); + b.setAttribute("type", "content"); + b.setAttribute("id", id); + b.setAttribute("width", width); + b.setAttribute("height", height); + $(parent).appendChild(b); + } + addBrowser("parent", "f1", 300, 200); + addBrowser("parent", "f2", 300, 200); + + /** Test for Bug 449778 */ + var doc1 = "data:text/html,<html><body>This is a test</body></html>"; + var doc2 = "data:text/html,<html><body>This is a second test</body></html>"; + var doc3 = "data:text/html,<html><body>This is a <script>var evt = document.createEvent('Events'); evt.initEvent('testEvt', true, true); document.dispatchEvent(evt);</script>third test</body></html>"; + + + $("f1").setAttribute("src", doc1); + $("f2").setAttribute("src", doc2); + + function doTheTest() { + var strs = { "f1": "", "f2" : "" }; + function attachListener(node, type) { + var listener = function(e) { + if (strs[node.id]) strs[node.id] += " "; + strs[node.id] += node.id + ".page" + type; + } + node.addEventListener("page" + type, listener); + + listener.detach = function() { + node.removeEventListener("page" + type, listener); + } + return listener; + } + + var l1 = attachListener($("f1"), "show"); + var l2 = attachListener($("f1"), "hide"); + var l3 = attachListener($("f2"), "show"); + var l4 = attachListener($("f2"), "hide"); + + $("f1").swapDocShells($("f2")); + + is(strs.f1, "f1.pagehide f1.pageshow", + "Expected hide then show on first loaded page"); + is(strs.f2, "f2.pagehide f2.pageshow", + "Expected hide then show on second loaded page"); + + function listener2() { + $("f2").removeEventListener("testEvt", listener2); + + strs = { "f1": "", "f2" : "" }; + + $("f1").swapDocShells($("f2")); + is(strs.f1, "f1.pagehide", + "Expected hide on already-loaded page, then nothing"); + is(strs.f2, "f2.pageshow f2.pagehide f2.pageshow", + "Expected show on still-loading page, then hide on it, then show " + + "on already-loaded page"); + + strs = { "f1": "", "f2" : "" }; + + $("f1").addEventListener("pageshow", listener3); + } + + function listener3() { + $("f1").removeEventListener("pageshow", listener3); + + is(strs.f1, "f1.pageshow", + "Expected show as our page finishes loading"); + is(strs.f2, "", "Expected no more events here."); + + l1.detach(); + l2.detach(); + l3.detach(); + l4.detach(); + + window.close(); + SimpleTest.finish(); + } + + $("f2").addEventListener("testEvt", listener2, false, true); + $("f2").setAttribute("src", doc3); + } + + ]]></script> +</window> diff --git a/docshell/test/chrome/bug449780_window.xhtml b/docshell/test/chrome/bug449780_window.xhtml new file mode 100644 index 0000000000..c37bc096b2 --- /dev/null +++ b/docshell/test/chrome/bug449780_window.xhtml @@ -0,0 +1,83 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<window title="Mozilla Bug 449780" onload="setTimeout(doTheTest, 0);" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + + <hbox id="parent"> + </hbox> + + <!-- test code goes here --> + <script type="application/javascript" src="chrome://mochikit/content/chrome-harness.js" /> + <script type="application/javascript" src="docshell_helpers.js" /> + <script type="application/javascript"><![CDATA[ + function addBrowser(parent, width, height) { + var b = + document.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul", "browser"); + b.setAttribute("type", "content"); + b.setAttribute("id", "content"); + b.setAttribute("width", width); + b.setAttribute("height", height); + b.setAttribute("remote", SpecialPowers.Services.appinfo.sessionHistoryInParent); + if (SpecialPowers.Services.appinfo.sessionHistoryInParent) { + b.setAttribute("maychangeremoteness", "true"); + } + document.getElementById("parent").appendChild(b); + return b; + } + + let f1 = addBrowser("parent", 300, 200); + + /** Test for Bug 449780 */ + var doc1 = "data:text/html,<html><body>This is a test</body></html>"; + var doc2 = "data:text/html,<html><body>This is a second test</body></html>"; + + async function doTheTest() { + await promisePageNavigation({ + uri: doc1, + }); + let { origDOM, modifiedDOM } = await SpecialPowers.spawn(f1, [], () => { + var origDOM = content.document.documentElement.innerHTML; + content.document.body.textContent = "Modified"; + var modifiedDOM = content.document.documentElement.innerHTML; + isnot(origDOM, modifiedDOM, "DOM should be different"); + return { origDOM, modifiedDOM }; + }); + + await promisePageNavigation({ + uri: doc2, + }); + + await promisePageNavigation({ + back: true, + }); + + await SpecialPowers.spawn(f1, [modifiedDOM], (modifiedDOM) => { + is(content.document.documentElement.innerHTML, modifiedDOM, "Should have been bfcached"); + }); + + await promisePageNavigation({ + forward: true, + }); + + f1.removeAttribute("id"); + let f2 = addBrowser("parent", 300, 200); + + // Make sure there's a document or the swap will fail. + await promisePageNavigation({ + uri: "about:blank", + }); + + f1.swapDocShells(f2); + + await promisePageNavigation({ + back: true, + }); + + await SpecialPowers.spawn(f2, [origDOM], (origDOM) => { + is(content.document.documentElement.innerHTML, origDOM, "Should not have been bfcached"); + }); + + finish(); + } + ]]></script> +</window> diff --git a/docshell/test/chrome/bug454235-subframe.xhtml b/docshell/test/chrome/bug454235-subframe.xhtml new file mode 100644 index 0000000000..a8b6178e65 --- /dev/null +++ b/docshell/test/chrome/bug454235-subframe.xhtml @@ -0,0 +1,7 @@ +<window title="Mozilla Bug 454235 SubFrame" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <deck flex="1"> + <browser id="topBrowser" src="about:mozilla"/> + <browser id="burriedBrowser" src="about:mozilla"/> + </deck> +</window> diff --git a/docshell/test/chrome/bug582176_window.xhtml b/docshell/test/chrome/bug582176_window.xhtml new file mode 100644 index 0000000000..b43220a2fe --- /dev/null +++ b/docshell/test/chrome/bug582176_window.xhtml @@ -0,0 +1,74 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> + +<window id="303267Test" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + width="600" + height="600" + onload="runTest();" + title="bug 582176 test"> + + <script type="application/javascript" src="chrome://mochikit/content/chrome-harness.js" /> + <script type="application/javascript" src="docshell_helpers.js" /> + <script type="application/javascript"><![CDATA[ + //// + // Bug 582176. + // + async function runTest() + { + enableBFCache(true); + + var notificationCount = 0; + + let onGlobalCreation = () => { + ++notificationCount; + }; + + await promisePageNavigation({ + uri: "http://mochi.test:8888/chrome/docshell/test/chrome/582176_dummy.html", + onGlobalCreation, + }); + is(await SpecialPowers.spawn(TestWindow.getBrowser(), [], () => { + let testVar = content.testVar; + content.testVar = 1; + return testVar; + }), undefined, + "variable unexpectedly there already"); + is(notificationCount, 1, "Should notify on first navigation"); + + await promisePageNavigation({ + uri: "http://mochi.test:8888/chrome/docshell/test/chrome/582176_dummy.html?2", + onGlobalCreation, + }); + is(await SpecialPowers.spawn(TestWindow.getBrowser(), [], () => { + return content.testVar; + }), undefined, + "variable should no longer be there"); + is(notificationCount, 2, "Should notify on second navigation"); + + await promisePageNavigation({ + back: true, + }); + is(await SpecialPowers.spawn(TestWindow.getBrowser(), [], () => { + return content.testVar; + }), 1, + "variable should still be there"); + is(notificationCount, 2, "Should not notify on back navigation"); + + await promisePageNavigation({ + uri: "http://mochi.test:8888/chrome/docshell/test/chrome/582176_xml.xml", + onGlobalCreation, + }); + is(await SpecialPowers.spawn(TestWindow.getBrowser(), [], () => { + return content.document.body.textContent; + }), "xslt result", + "Transform performed successfully"); + is(notificationCount, 3, "Should notify only once on XSLT navigation"); + + // Tell the framework the test is finished. + finish(); + } + + ]]></script> + <browser type="content" primary="true" flex="1" id="content" remote="true" maychangeremoteness="true" /> +</window> diff --git a/docshell/test/chrome/bug608669.xhtml b/docshell/test/chrome/bug608669.xhtml new file mode 100644 index 0000000000..993f24051c --- /dev/null +++ b/docshell/test/chrome/bug608669.xhtml @@ -0,0 +1,14 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<window title="Mozilla Bug 608669 - Blank page" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + onload="notifyOpener();"> + <description flex="1" value="This window is intentionally left blank"/> + <script type="application/javascript"> + function notifyOpener() { + if (opener) { + opener.postMessage("load", "*"); + } + } + </script> +</window> diff --git a/docshell/test/chrome/bug662200_window.xhtml b/docshell/test/chrome/bug662200_window.xhtml new file mode 100644 index 0000000000..7c6f656f26 --- /dev/null +++ b/docshell/test/chrome/bug662200_window.xhtml @@ -0,0 +1,119 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> + +<window id="303267Test" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + width="600" + height="600" + onload="setTimeout(runTest, 0);" + title="bug 662200 test"> + + <script type="application/javascript" src="chrome://mochikit/content/chrome-harness.js" /> + <script type="application/javascript" src="docshell_helpers.js" /> + <script type="application/javascript"><![CDATA[ + Services.prefs.setBoolPref("browser.navigation.requireUserInteraction", false); + + //// + // Bug 662200 + // + async function runTest() + { + // Load the first test page + var navData = { + uri: getHttpUrl("662200a.html"), + eventsToListenFor: ["pageshow"], + expectedEvents: [ {type: "pageshow", title: "A"} ], + }; + await promisePageNavigation(navData); + + // Load the second test page. + navData = { + eventsToListenFor: ["pageshow", "pagehide"], + expectedEvents: [ {type: "pagehide", + title: "A"}, + {type: "pageshow", + title: "B"} ], + } + let clicked = promisePageEvents(navData); + SpecialPowers.spawn(TestWindow.getBrowser(), [], () => { + var link = content.document.getElementById("link"); + var event = content.document.createEvent("MouseEvents"); + event.initMouseEvent("click", true, true, content, + 0, 0, 0, 0, 0, false, false, false, false, 0, null); + link.dispatchEvent(event); + }); + await clicked; + + // Load the third test page. + navData = { + eventsToListenFor: ["pageshow", "pagehide"], + expectedEvents: [ {type: "pagehide", + title: "B"}, + {type: "pageshow", + title: "C"} ], + }; + clicked = promisePageEvents(navData); + SpecialPowers.spawn(TestWindow.getBrowser(), [], () => { + var link = content.document.getElementById("link"); + var event = content.document.createEvent("MouseEvents"); + event.initMouseEvent("click", true, true, content, + 0, 0, 0, 0, 0, false, false, false, false, 0, null); + link.dispatchEvent(event); + }); + await clicked; + + // Go back. + navData = { + back: true, + eventsToListenFor: ["pageshow", "pagehide"], + expectedEvents: [ {type: "pagehide", + title: "C"}, + {type: "pageshow", + title: "B"} ], + }; + await promisePageNavigation(navData); + + // Reload. + navData = { + eventsToListenFor: ["pageshow", "pagehide"], + expectedEvents: [ {type: "pagehide", + title: "B"}, + {type: "pageshow", + title: "B"} ], + }; + // Asking the docshell harness to reload for us will call reload on + // nsDocShell which has different behavior than the reload on nsSHistory + // so we call reloadCurrentEntry() (which is equivalent to reload(0) and + // visible from JS) explicitly here. + let reloaded = promisePageEvents(navData); + if (SpecialPowers.Services.appinfo.sessionHistoryInParent) { + TestWindow.getBrowser().browsingContext.sessionHistory.reloadCurrentEntry(); + } else { + SpecialPowers.spawn(TestWindow.getBrowser(), [], () => { + docShell.QueryInterface(Ci.nsIWebNavigation).sessionHistory.legacySHistory.reloadCurrentEntry(); + }); + } + await reloaded; + + // After this sequence of events, we should be able to go back and forward + is(TestWindow.getBrowser().canGoBack, true, "Should be able to go back!"); + is(TestWindow.getBrowser().canGoForward, true, "Should be able to go forward!"); + let requestedIndex; + if (SpecialPowers.Services.appinfo.sessionHistoryInParent) { + requestedIndex = TestWindow.getBrowser().browsingContext.sessionHistory.requestedIndex; + } else { + requestedIndex = await SpecialPowers.spawn(TestWindow.getBrowser(), [], () => { + return docShell.sessionHistory.legacySHistory.requestedIndex; + }) + } + is(requestedIndex, -1, "Requested index should be cleared!"); + + Services.prefs.clearUserPref("browser.navigation.requireUserInteraction"); + // Tell the framework the test is finished. + finish(); + } + + ]]></script> + + <browser type="content" primary="true" flex="1" id="content" remote="true" /> +</window> diff --git a/docshell/test/chrome/bug690056_window.xhtml b/docshell/test/chrome/bug690056_window.xhtml new file mode 100644 index 0000000000..fb5dfaea40 --- /dev/null +++ b/docshell/test/chrome/bug690056_window.xhtml @@ -0,0 +1,171 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> + +<window id="690056Test" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + width="600" + height="600" + onload="setTimeout(nextTest, 0);" + title="bug 6500056 test"> + + <script type="application/javascript" src= "chrome://mochikit/content/chrome-harness.js" /> + <script type="application/javascript" src="docshell_helpers.js" /> + <script type="application/javascript"><![CDATA[ + var tests = testIterator(); + + function nextTest() { + tests.next(); + } + + // Makes sure that we fire the visibilitychange events + function* testIterator() { + // Enable bfcache + enableBFCache(8); + + // Load something for a start + doPageNavigation({ + uri: 'data:text/html,<title>initial load</title>', + onNavComplete: nextTest + }); + yield undefined; + + // Now load a new page + doPageNavigation({ + uri: 'data:text/html,<title>new load</title>', + eventsToListenFor: [ "pageshow", "pagehide", "visibilitychange" ], + expectedEvents: [ { type: "pagehide", + title: "initial load", + persisted: true }, + { type: "visibilitychange", + title: "initial load", + visibilityState: "hidden", + hidden: true }, + // No visibilitychange events fired for initial pageload + { type: "pageshow", + title: "new load", + persisted: false }, // false on initial load + ], + onNavComplete: nextTest + }); + yield undefined; + + // Now go back + doPageNavigation({ + back: true, + eventsToListenFor: [ "pageshow", "pagehide", "visibilitychange" ], + expectedEvents: [ { type: "pagehide", + title: "new load", + persisted: true }, + { type: "visibilitychange", + title: "new load", + visibilityState: "hidden", + hidden: true }, + { type: "visibilitychange", + title: "initial load", + visibilityState: "visible", + hidden: false }, + { type: "pageshow", + title: "initial load", + persisted: true }, + ], + onNavComplete: nextTest + }); + yield undefined; + + // And forward + doPageNavigation({ + forward: true, + eventsToListenFor: [ "pageshow", "pagehide", "visibilitychange" ], + expectedEvents: [ { type: "pagehide", + title: "initial load", + persisted: true }, + { type: "visibilitychange", + title: "initial load", + visibilityState: "hidden", + hidden: true }, + { type: "visibilitychange", + title: "new load", + visibilityState: "visible", + hidden: false }, + { type: "pageshow", + title: "new load", + persisted: true }, + ], + onNavComplete: nextTest + }); + yield undefined; + + waitForPageEvents({ + eventsToListenFor: [ "visibilitychange" ], + expectedEvents: [ { type: "visibilitychange", + title: "new load", + visibilityState: "hidden", + hidden: true }, + ], + onNavComplete: nextTest + }); + + // Now flip our docshell to not active + TestWindow.getBrowser().docShellIsActive = false; + yield undefined; + + // And navigate back; there should be no visibility state transitions + doPageNavigation({ + back: true, + eventsToListenFor: [ "pageshow", "pagehide", "visibilitychange" ], + expectedEvents: [ { type: "pagehide", + title: "new load", + persisted: true }, + { type: "pageshow", + title: "initial load", + persisted: true }, + ], + unexpectedEvents: [ "visibilitychange" ], + onNavComplete: nextTest + }); + yield undefined; + + waitForPageEvents({ + eventsToListenFor: [ "visibilitychange" ], + expectedEvents: [ { type: "visibilitychange", + title: "initial load", + visibilityState: "visible", + hidden: false }, + ], + onNavComplete: nextTest + }); + + // Now set the docshell active again + TestWindow.getBrowser().docShellIsActive = true; + yield undefined; + + // And forward + doPageNavigation({ + forward: true, + eventsToListenFor: [ "pageshow", "pagehide", "visibilitychange" ], + expectedEvents: [ { type: "pagehide", + title: "initial load", + persisted: true }, + { type: "visibilitychange", + title: "initial load", + visibilityState: "hidden", + hidden: true }, + { type: "visibilitychange", + title: "new load", + visibilityState: "visible", + hidden: false }, + { type: "pageshow", + title: "new load", + persisted: true }, + ], + onNavComplete: nextTest + }); + yield undefined; + + // Tell the framework the test is finished. + finish(); + } + ]]></script> + + <browser type="content" primary="true" flex="1" id="content" remote="true" maychangeremoteness="true" /> +</window> diff --git a/docshell/test/chrome/bug846906.html b/docshell/test/chrome/bug846906.html new file mode 100644 index 0000000000..a289417ea8 --- /dev/null +++ b/docshell/test/chrome/bug846906.html @@ -0,0 +1,10 @@ +<html> + <head> + <title> + </title> + </head> + <body> + <div id="div1" style="width:1024px; height:768px; border:none;"> + </div> + </body> +</html> diff --git a/docshell/test/chrome/bug89419.sjs b/docshell/test/chrome/bug89419.sjs new file mode 100644 index 0000000000..7172690a9a --- /dev/null +++ b/docshell/test/chrome/bug89419.sjs @@ -0,0 +1,12 @@ +function handleRequest(request, response) { + var redirectstate = "/docshell/test/chrome/bug89419.sjs"; + response.setStatusLine("1.1", 302, "Found"); + if (getState(redirectstate) == "") { + response.setHeader("Location", "red.png", false); + setState(redirectstate, "red"); + } else { + response.setHeader("Location", "blue.png", false); + setState(redirectstate, ""); + } + response.setHeader("Cache-Control", "no-cache", false); +} diff --git a/docshell/test/chrome/bug89419_window.xhtml b/docshell/test/chrome/bug89419_window.xhtml new file mode 100644 index 0000000000..12b9dec650 --- /dev/null +++ b/docshell/test/chrome/bug89419_window.xhtml @@ -0,0 +1,69 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> + +<window id="89419Test" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + width="600" + height="600" + onload="setTimeout(runTests, 0);" + title="bug 89419 test"> + + <script type="application/javascript" src= "chrome://mochikit/content/chrome-harness.js" /> + <script type="application/javascript" src="docshell_helpers.js" /> + <script src="chrome://mochikit/content/tests/SimpleTest/WindowSnapshot.js"></script> + + <script type="application/javascript"><![CDATA[ + //// + // A visited link should have the :visited style applied + // to it when displayed on a page which was fetched from + // the bfcache. + // + async function runTests() { + // Disable rcwn to make cache behavior deterministic. + var {SpecialPowers} = window.arguments[0]; + await SpecialPowers.pushPrefEnv({"set":[["network.http.rcwn.enabled", false]]}); + + // Load a test page containing an image referring to the sjs that returns + // a different redirect every time it's loaded. + await new Promise(resolve => { + doPageNavigation({ + uri: getHttpUrl("89419.html"), + onNavComplete: resolve, + preventBFCache: true, + }); + }) + + var first = await snapshotWindow(TestWindow.getWindow()); + + await new Promise(resolve => { + doPageNavigation({ + uri: "about:blank", + onNavComplete: resolve, + }); + }); + + var second = await snapshotWindow(TestWindow.getWindow()); + function snapshotsEqual(snap1, snap2) { + return compareSnapshots(snap1, snap2, true)[0]; + } + ok(!snapshotsEqual(first, second), "about:blank should not be the same as the image web page"); + + await new Promise(resolve => { + doPageNavigation({ + back: true, + onNavComplete: resolve, + }); + }); + + var third = await snapshotWindow(TestWindow.getWindow()); + ok(!snapshotsEqual(third, second), "going back should not be the same as about:blank"); + ok(snapshotsEqual(first, third), "going back should be the same as the initial load"); + + // Tell the framework the test is finished. + finish(); + } + + ]]></script> + + <browser type="content" primary="true" flex="1" id="content" src="about:blank"/> +</window> diff --git a/docshell/test/chrome/bug909218.html b/docshell/test/chrome/bug909218.html new file mode 100644 index 0000000000..a11fa6000d --- /dev/null +++ b/docshell/test/chrome/bug909218.html @@ -0,0 +1,11 @@ +<html>
+<head>
+ <link rel="stylesheet" type="text/css" href="http://mochi.test:8888/tests/SimpleTest/test.css">
+ <script src="bug909218.js"></script>
+</head>
+<body>
+ <img src="http://mochi.test:8888/tests/docshell/test/chrome/red.png">
+ <!-- an iframe so we can check these too get the correct flags -->
+ <iframe src="generic.html"/>
+</body>
+</html>
diff --git a/docshell/test/chrome/bug909218.js b/docshell/test/chrome/bug909218.js new file mode 100644 index 0000000000..2222480cd3 --- /dev/null +++ b/docshell/test/chrome/bug909218.js @@ -0,0 +1,2 @@ +// This file exists just to ensure that we load it with the correct flags. +dump("bug909218.js loaded\n"); diff --git a/docshell/test/chrome/bug92598_window.xhtml b/docshell/test/chrome/bug92598_window.xhtml new file mode 100644 index 0000000000..bad91f3df6 --- /dev/null +++ b/docshell/test/chrome/bug92598_window.xhtml @@ -0,0 +1,89 @@ +<?xml version="1.0"?> + +<!-- This Source Code Form is subject to the terms of the Mozilla Public + - License, v. 2.0. If a copy of the MPL was not distributed with this + - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> + +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> + +<window id="92598Test" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + width="600" + height="600" + onload="onLoad();" + title="92598 test"> + + <script src="chrome://mochikit/content/chrome-harness.js" /> + <script type="application/javascript" src="docshell_helpers.js" /> + <script type="application/javascript"><![CDATA[ + var gBrowser; + var gTestsIterator; + + function onLoad() { + gBrowser = document.getElementById("content"); + gTestsIterator = testsIterator(); + nextTest(); + } + + function nextTest() { + gTestsIterator.next(); + } + + function* testsIterator() { + // Load a page with a no-cache header, followed by a simple page + // On pagehide, first page should report it is not being persisted + var test1DocURI = "http://mochi.test:8888/chrome/docshell/test/chrome/92598_nostore.html"; + + doPageNavigation({ + uri: test1DocURI, + eventsToListenFor: ["load", "pageshow"], + expectedEvents: [ { type: "load", + title: "test1" }, + { type: "pageshow", + title: "test1", + persisted: false } ], + onNavComplete: nextTest + }); + yield undefined; + + var test2Doc = "data:text/html,<html><head><title>test2</title></head>" + + "<body>test2</body></html>"; + + doPageNavigation({ + uri: test2Doc, + eventsToListenFor: ["load", "pageshow", "pagehide"], + expectedEvents: [ { type: "pagehide", + title: "test1", + persisted: false }, + { type: "load", + title: "test2" }, + { type: "pageshow", + title: "test2", + persisted: false } ], + onNavComplete: nextTest + }); + yield undefined; + + // Now go back in history. First page should not have been cached. + // Check persisted property to confirm + doPageNavigation({ + back: true, + eventsToListenFor: ["load", "pageshow", "pagehide"], + expectedEvents: [ { type: "pagehide", + title: "test2", + persisted: true }, + { type: "load", + title: "test1" }, + { type: "pageshow", + title: "test1", + persisted: false } ], + onNavComplete: nextTest + }); + yield undefined; + + finish(); + } + ]]></script> + + <browser type="content" primary="true" flex="1" id="content" remote="true" maychangeremoteness="true" /> +</window> diff --git a/docshell/test/chrome/chrome.ini b/docshell/test/chrome/chrome.ini new file mode 100644 index 0000000000..e6294dbb8c --- /dev/null +++ b/docshell/test/chrome/chrome.ini @@ -0,0 +1,107 @@ +[DEFAULT] +skip-if = os == 'android' +support-files = + 662200a.html + 662200b.html + 662200c.html + 89419.html + bug113934_window.xhtml + bug215405_window.xhtml + bug293235.html + bug293235_p2.html + bug293235_window.xhtml + bug294258_testcase.html + bug294258_window.xhtml + bug298622_window.xhtml + bug301397_1.html + bug301397_2.html + bug301397_3.html + bug301397_4.html + bug301397_window.xhtml + bug303267.html + bug303267_window.xhtml + bug311007_window.xhtml + bug321671_window.xhtml + bug360511_case1.html + bug360511_case2.html + bug360511_window.xhtml + bug364461_window.xhtml + bug396519_window.xhtml + bug396649_window.xhtml + bug449778_window.xhtml + bug449780_window.xhtml + bug454235-subframe.xhtml + bug608669.xhtml + bug662200_window.xhtml + bug690056_window.xhtml + bug846906.html + bug89419_window.xhtml + bug909218.html + bug909218.js + docshell_helpers.js + DocShellHelpers.sys.mjs + file_viewsource_forbidden_in_iframe.html + generic.html + mozFrameType_window.xhtml + test_docRedirect.sjs + +[test_allowContentRetargeting.html] +[test_bug112564.xhtml] +support-files = + bug112564_window.xhtml + 112564_nocache.html + 112564_nocache.html^headers^ +[test_bug113934.xhtml] +[test_bug215405.xhtml] +[test_bug293235.xhtml] +skip-if = true # bug 1393441 +[test_bug294258.xhtml] +[test_bug298622.xhtml] +[test_bug301397.xhtml] +skip-if = (os == 'win' && processor == 'aarch64') # bug 1533819 +[test_bug303267.xhtml] +[test_bug311007.xhtml] +[test_bug321671.xhtml] +skip-if = + (os == "mac" && !debug) # Bug 1784831 +[test_bug360511.xhtml] +skip-if = (os == 'win' && processor == 'x86') +[test_bug364461.xhtml] +skip-if = (os == 'win' && processor == 'aarch64') # bug 1533814 +[test_bug396519.xhtml] +[test_bug396649.xhtml] +[test_bug428288.html] +[test_bug449778.xhtml] +[test_bug449780.xhtml] +[test_bug453650.xhtml] +[test_bug454235.xhtml] +[test_bug456980.xhtml] +[test_bug565388.xhtml] +skip-if = true # Bug 1026815,Bug 1546159 +[test_bug582176.xhtml] +support-files = + 582176_dummy.html + 582176_xml.xml + 582176_xslt.xsl + bug582176_window.xhtml +[test_bug608669.xhtml] +[test_bug662200.xhtml] +[test_bug690056.xhtml] +[test_bug789773.xhtml] +[test_bug846906.xhtml] +[test_bug89419.xhtml] +[test_bug909218.html] +[test_bug92598.xhtml] +support-files = + 92598_nostore.html + 92598_nostore.html^headers^ + bug92598_window.xhtml +[test_open_and_immediately_close_opener.html] +# This bug only manifests in the non-e10s window open codepath. The test +# should be updated to make sure it still opens a new window in the parent +# process if and when we start running chrome mochitests with e10s enabled. +skip-if = e10s +[test_mozFrameType.xhtml] +[test_viewsource_forbidden_in_iframe.xhtml] +skip-if = true # bug 1019315 +[test_docRedirect.xhtml] diff --git a/docshell/test/chrome/docshell_helpers.js b/docshell/test/chrome/docshell_helpers.js new file mode 100644 index 0000000000..4af1a3f9ea --- /dev/null +++ b/docshell/test/chrome/docshell_helpers.js @@ -0,0 +1,759 @@ +if (!window.opener && window.arguments) { + window.opener = window.arguments[0]; +} +/** + * Import common SimpleTest methods so that they're usable in this window. + */ +/* globals SimpleTest, is, isnot, ok, onerror, todo, todo_is, todo_isnot */ +var imports = [ + "SimpleTest", + "is", + "isnot", + "ok", + "onerror", + "todo", + "todo_is", + "todo_isnot", +]; +for (var name of imports) { + window[name] = window.opener.wrappedJSObject[name]; +} +const { BrowserTestUtils } = ChromeUtils.importESModule( + "resource://testing-common/BrowserTestUtils.sys.mjs" +); + +const ACTOR_MODULE_URI = + "chrome://mochitests/content/chrome/docshell/test/chrome/DocShellHelpers.sys.mjs"; +const { DocShellHelpersParent } = ChromeUtils.importESModule(ACTOR_MODULE_URI); +// Some functions assume chrome-harness.js has been loaded. +/* import-globals-from ../../../testing/mochitest/chrome-harness.js */ + +/** + * Define global constants and variables. + */ +const NAV_NONE = 0; +const NAV_BACK = 1; +const NAV_FORWARD = 2; +const NAV_GOTOINDEX = 3; +const NAV_URI = 4; +const NAV_RELOAD = 5; + +var gExpectedEvents; // an array of events which are expected to +// be triggered by this navigation +var gUnexpectedEvents; // an array of event names which are NOT expected +// to be triggered by this navigation +var gFinalEvent; // true if the last expected event has fired +var gUrisNotInBFCache = []; // an array of uri's which shouldn't be stored +// in the bfcache +var gNavType = NAV_NONE; // defines the most recent navigation type +// executed by doPageNavigation +var gOrigMaxTotalViewers = undefined; // original value of max_total_viewers, // to be restored at end of test + +var gExtractedPath = null; // used to cache file path for extracting files from a .jar file + +/** + * The doPageNavigation() function performs page navigations asynchronously, + * listens for specified events, and compares actual events with a list of + * expected events. When all expected events have occurred, an optional + * callback can be notified. The parameter passed to this function is an + * object with the following properties: + * + * uri: if !undefined, the browser will navigate to this uri + * + * back: if true, the browser will execute goBack() + * + * forward: if true, the browser will execute goForward() + * + * gotoIndex: if a number, the browser will execute gotoIndex() with + * the number as index + * + * reload: if true, the browser will execute reload() + * + * eventsToListenFor: an array containing one or more of the following event + * types to listen for: "pageshow", "pagehide", "onload", + * "onunload". If this property is undefined, only a + * single "pageshow" events will be listened for. If this + * property is explicitly empty, [], then no events will + * be listened for. + * + * expectedEvents: an array of one or more expectedEvent objects, + * corresponding to the events which are expected to be + * fired for this navigation. Each object has the + * following properties: + * + * type: one of the event type strings + * title (optional): the title of the window the + * event belongs to + * persisted (optional): the event's expected + * .persisted attribute + * + * This function will verify that events with the + * specified properties are fired in the same order as + * specified in the array. If .title or .persisted + * properties for an expectedEvent are undefined, those + * properties will not be verified for that particular + * event. + * + * This property is ignored if eventsToListenFor is + * undefined or []. + * + * preventBFCache: if true, an RTCPeerConnection will be added to the loaded + * page to prevent it from being bfcached. This property + * has no effect when eventsToListenFor is []. + * + * onNavComplete: a callback which is notified after all expected events + * have occurred, or after a timeout has elapsed. This + * callback is not notified if eventsToListenFor is []. + * onGlobalCreation: a callback which is notified when a DOMWindow is created + * (implemented by observing + * "content-document-global-created") + * + * There must be an expectedEvent object for each event of the types in + * eventsToListenFor which is triggered by this navigation. For example, if + * eventsToListenFor = [ "pagehide", "pageshow" ], then expectedEvents + * must contain an object for each pagehide and pageshow event which occurs as + * a result of this navigation. + */ +// eslint-disable-next-line complexity +function doPageNavigation(params) { + // Parse the parameters. + let back = params.back ? params.back : false; + let forward = params.forward ? params.forward : false; + let gotoIndex = params.gotoIndex ? params.gotoIndex : false; + let reload = params.reload ? params.reload : false; + let uri = params.uri ? params.uri : false; + let eventsToListenFor = + typeof params.eventsToListenFor != "undefined" + ? params.eventsToListenFor + : ["pageshow"]; + gExpectedEvents = + typeof params.eventsToListenFor == "undefined" || !eventsToListenFor.length + ? undefined + : params.expectedEvents; + gUnexpectedEvents = + typeof params.eventsToListenFor == "undefined" || !eventsToListenFor.length + ? undefined + : params.unexpectedEvents; + let preventBFCache = + typeof [params.preventBFCache] == "undefined" + ? false + : params.preventBFCache; + let waitOnly = + typeof params.waitForEventsOnly == "boolean" && params.waitForEventsOnly; + + // Do some sanity checking on arguments. + let navigation = ["back", "forward", "gotoIndex", "reload", "uri"].filter(k => + params.hasOwnProperty(k) + ); + if (navigation.length > 1) { + throw new Error(`Can't specify both ${navigation[0]} and ${navigation[1]}`); + } else if (!navigation.length && !waitOnly) { + throw new Error( + "Must specify back or forward or gotoIndex or reload or uri" + ); + } + if (params.onNavComplete && !eventsToListenFor.length) { + throw new Error("Can't use onNavComplete when eventsToListenFor == []"); + } + if (params.preventBFCache && !eventsToListenFor.length) { + throw new Error("Can't use preventBFCache when eventsToListenFor == []"); + } + if (params.preventBFCache && waitOnly) { + throw new Error("Can't prevent bfcaching when only waiting for events"); + } + if (waitOnly && typeof params.onNavComplete == "undefined") { + throw new Error( + "Must specify onNavComplete when specifying waitForEventsOnly" + ); + } + if (waitOnly && navigation.length) { + throw new Error( + "Can't specify a navigation type when using waitForEventsOnly" + ); + } + for (let anEventType of eventsToListenFor) { + let eventFound = false; + if (anEventType == "pageshow" && !gExpectedEvents) { + eventFound = true; + } + if (gExpectedEvents) { + for (let anExpectedEvent of gExpectedEvents) { + if (anExpectedEvent.type == anEventType) { + eventFound = true; + } + } + } + if (gUnexpectedEvents) { + for (let anExpectedEventType of gUnexpectedEvents) { + if (anExpectedEventType == anEventType) { + eventFound = true; + } + } + } + if (!eventFound) { + throw new Error( + `Event type ${anEventType} is specified in ` + + "eventsToListenFor, but not in expectedEvents" + ); + } + } + + // If the test explicitly sets .eventsToListenFor to [], don't wait for any + // events. + gFinalEvent = !eventsToListenFor.length; + + // Add observers as needed. + let observers = new Map(); + if (params.hasOwnProperty("onGlobalCreation")) { + observers.set("content-document-global-created", params.onGlobalCreation); + } + + // Add an event listener for each type of event in the .eventsToListenFor + // property of the input parameters, and add an observer for all the topics + // in the observers map. + let cleanup; + let useActor = TestWindow.getBrowser().isRemoteBrowser; + if (useActor) { + ChromeUtils.registerWindowActor("DocShellHelpers", { + parent: { + esModuleURI: ACTOR_MODULE_URI, + }, + child: { + esModuleURI: ACTOR_MODULE_URI, + events: { + pageshow: { createActor: true, capture: true }, + pagehide: { createActor: true, capture: true }, + load: { createActor: true, capture: true }, + unload: { createActor: true, capture: true }, + visibilitychange: { createActor: true, capture: true }, + }, + observers: observers.keys(), + }, + allFrames: true, + }); + DocShellHelpersParent.eventsToListenFor = eventsToListenFor; + DocShellHelpersParent.observers = observers; + + cleanup = () => { + DocShellHelpersParent.eventsToListenFor = null; + DocShellHelpersParent.observers = null; + ChromeUtils.unregisterWindowActor("DocShellHelpers"); + }; + } else { + for (let eventType of eventsToListenFor) { + dump("TEST: registering a listener for " + eventType + " events\n"); + TestWindow.getBrowser().addEventListener( + eventType, + pageEventListener, + true + ); + } + if (observers.size > 0) { + let observer = (_, topic) => { + observers.get(topic).call(); + }; + for (let topic of observers.keys()) { + Services.obs.addObserver(observer, topic); + } + + // We only need to do cleanup for the observer, the event listeners will + // go away with the window. + cleanup = () => { + for (let topic of observers.keys()) { + Services.obs.removeObserver(observer, topic); + } + }; + } + } + + if (cleanup) { + // Register a cleanup function on domwindowclosed, to avoid contaminating + // other tests if we bail out early because of an error. + Services.ww.registerNotification(function windowClosed( + subject, + topic, + data + ) { + if (topic == "domwindowclosed" && subject == window) { + Services.ww.unregisterNotification(windowClosed); + cleanup(); + } + }); + } + + // Perform the specified navigation. + if (back) { + gNavType = NAV_BACK; + TestWindow.getBrowser().goBack(); + } else if (forward) { + gNavType = NAV_FORWARD; + TestWindow.getBrowser().goForward(); + } else if (typeof gotoIndex == "number") { + gNavType = NAV_GOTOINDEX; + TestWindow.getBrowser().gotoIndex(gotoIndex); + } else if (uri) { + gNavType = NAV_URI; + BrowserTestUtils.loadURIString(TestWindow.getBrowser(), uri); + } else if (reload) { + gNavType = NAV_RELOAD; + TestWindow.getBrowser().reload(); + } else if (waitOnly) { + gNavType = NAV_NONE; + } else { + throw new Error("No valid navigation type passed to doPageNavigation!"); + } + + // If we're listening for events and there is an .onNavComplete callback, + // wait for all events to occur, and then call doPageNavigation_complete(). + if (eventsToListenFor.length && params.onNavComplete) { + waitForTrue( + function () { + return gFinalEvent; + }, + function () { + doPageNavigation_complete( + eventsToListenFor, + params.onNavComplete, + preventBFCache, + useActor, + cleanup + ); + } + ); + } else if (cleanup) { + cleanup(); + } +} + +/** + * Finish doPageNavigation(), by removing event listeners, adding an unload + * handler if appropriate, and calling the onNavComplete callback. This + * function is called after all the expected events for this navigation have + * occurred. + */ +function doPageNavigation_complete( + eventsToListenFor, + onNavComplete, + preventBFCache, + useActor, + cleanup +) { + if (useActor) { + if (preventBFCache) { + let actor = + TestWindow.getBrowser().browsingContext.currentWindowGlobal.getActor( + "DocShellHelpers" + ); + actor.sendAsyncMessage("docshell_helpers:preventBFCache"); + } + } else { + // Unregister our event listeners. + dump("TEST: removing event listeners\n"); + for (let eventType of eventsToListenFor) { + TestWindow.getBrowser().removeEventListener( + eventType, + pageEventListener, + true + ); + } + + // If the .preventBFCache property was set, add an RTCPeerConnection to + // prevent the page from being bfcached. + if (preventBFCache) { + let win = TestWindow.getWindow(); + win.blockBFCache = new win.RTCPeerConnection(); + } + } + + if (cleanup) { + cleanup(); + } + + let uri = TestWindow.getBrowser().currentURI.spec; + if (preventBFCache) { + // Save the current uri in an array of uri's which shouldn't be + // stored in the bfcache, for later verification. + if (!(uri in gUrisNotInBFCache)) { + gUrisNotInBFCache.push(uri); + } + } else if (gNavType == NAV_URI) { + // If we're navigating to a uri and .preventBFCache was not + // specified, splice it out of gUrisNotInBFCache if it's there. + gUrisNotInBFCache.forEach(function (element, index, array) { + if (element == uri) { + array.splice(index, 1); + } + }, this); + } + + // Notify the callback now that we're done. + onNavComplete.call(); +} + +function promisePageNavigation(params) { + if (params.hasOwnProperty("onNavComplete")) { + throw new Error( + "Can't use a onNavComplete completion callback with promisePageNavigation." + ); + } + return new Promise(resolve => { + params.onNavComplete = resolve; + doPageNavigation(params); + }); +} + +/** + * Allows a test to wait for page navigation events, and notify a + * callback when they've all been received. This works exactly the + * same as doPageNavigation(), except that no navigation is initiated. + */ +function waitForPageEvents(params) { + params.waitForEventsOnly = true; + doPageNavigation(params); +} + +function promisePageEvents(params) { + if (params.hasOwnProperty("onNavComplete")) { + throw new Error( + "Can't use a onNavComplete completion callback with promisePageEvents." + ); + } + return new Promise(resolve => { + params.waitForEventsOnly = true; + params.onNavComplete = resolve; + doPageNavigation(params); + }); +} + +/** + * The event listener which listens for expectedEvents. + */ +function pageEventListener( + event, + originalTargetIsHTMLDocument = HTMLDocument.isInstance(event.originalTarget) +) { + try { + dump( + "TEST: eventListener received a " + + event.type + + " event for page " + + event.originalTarget.title + + ", persisted=" + + event.persisted + + "\n" + ); + } catch (e) { + // Ignore any exception. + } + + // If this page shouldn't be in the bfcache because it was previously + // loaded with .preventBFCache, make sure that its pageshow event + // has .persisted = false, even if the test doesn't explicitly test + // for .persisted. + if ( + event.type == "pageshow" && + (gNavType == NAV_BACK || + gNavType == NAV_FORWARD || + gNavType == NAV_GOTOINDEX) + ) { + let uri = TestWindow.getBrowser().currentURI.spec; + if (uri in gUrisNotInBFCache) { + ok( + !event.persisted, + "pageshow event has .persisted = false, even " + + "though it was loaded with .preventBFCache previously\n" + ); + } + } + + if (typeof gUnexpectedEvents != "undefined") { + is( + gUnexpectedEvents.indexOf(event.type), + -1, + "Should not get unexpected event " + event.type + ); + } + + // If no expected events were specified, mark the final event as having been + // triggered when a pageshow event is fired; this will allow + // doPageNavigation() to return. + if (typeof gExpectedEvents == "undefined" && event.type == "pageshow") { + waitForNextPaint(function () { + gFinalEvent = true; + }); + return; + } + + // If there are explicitly no expected events, but we receive one, it's an + // error. + if (!gExpectedEvents.length) { + ok(false, "Unexpected event (" + event.type + ") occurred"); + return; + } + + // Grab the next expected event, and compare its attributes against the + // actual event. + let expected = gExpectedEvents.shift(); + + is( + event.type, + expected.type, + "A " + + expected.type + + " event was expected, but a " + + event.type + + " event occurred" + ); + + if (typeof expected.title != "undefined") { + ok( + originalTargetIsHTMLDocument, + "originalTarget for last " + event.type + " event not an HTMLDocument" + ); + is( + event.originalTarget.title, + expected.title, + "A " + + event.type + + " event was expected for page " + + expected.title + + ", but was fired for page " + + event.originalTarget.title + ); + } + + if (typeof expected.persisted != "undefined") { + is( + event.persisted, + expected.persisted, + "The persisted property of the " + + event.type + + " event on page " + + event.originalTarget.location + + " had an unexpected value" + ); + } + + if ("visibilityState" in expected) { + is( + event.originalTarget.visibilityState, + expected.visibilityState, + "The visibilityState property of the document on page " + + event.originalTarget.location + + " had an unexpected value" + ); + } + + if ("hidden" in expected) { + is( + event.originalTarget.hidden, + expected.hidden, + "The hidden property of the document on page " + + event.originalTarget.location + + " had an unexpected value" + ); + } + + // If we're out of expected events, let doPageNavigation() return. + if (!gExpectedEvents.length) { + waitForNextPaint(function () { + gFinalEvent = true; + }); + } +} + +DocShellHelpersParent.eventListener = pageEventListener; + +/** + * End a test. + */ +function finish() { + // Work around bug 467960. + let historyPurged; + if (SpecialPowers.Services.appinfo.sessionHistoryInParent) { + let history = TestWindow.getBrowser().browsingContext?.sessionHistory; + history.purgeHistory(history.count); + historyPurged = Promise.resolve(); + } else { + historyPurged = SpecialPowers.spawn(TestWindow.getBrowser(), [], () => { + let history = docShell.QueryInterface(Ci.nsIWebNavigation).sessionHistory + .legacySHistory; + history.purgeHistory(history.count); + }); + } + + // If the test changed the value of max_total_viewers via a call to + // enableBFCache(), then restore it now. + if (typeof gOrigMaxTotalViewers != "undefined") { + Services.prefs.setIntPref( + "browser.sessionhistory.max_total_viewers", + gOrigMaxTotalViewers + ); + } + + // Close the test window and signal the framework that the test is done. + let opener = window.opener; + let SimpleTest = opener.wrappedJSObject.SimpleTest; + + // Wait for the window to be closed before finishing the test + Services.ww.registerNotification(function observer(subject, topic, data) { + if (topic == "domwindowclosed") { + Services.ww.unregisterNotification(observer); + SimpleTest.waitForFocus(SimpleTest.finish, opener); + } + }); + + historyPurged.then(_ => { + window.close(); + }); +} + +/** + * Helper function which waits until another function returns true, or until a + * timeout occurs, and then notifies a callback. + * + * Parameters: + * + * fn: a function which is evaluated repeatedly, and when it turns true, + * the onWaitComplete callback is notified. + * + * onWaitComplete: a callback which will be notified when fn() returns + * true, or when a timeout occurs. + * + * timeout: a timeout, in seconds or ms, after which waitForTrue() will + * fail an assertion and then return, even if the fn function never + * returns true. If timeout is undefined, waitForTrue() will never + * time out. + */ +function waitForTrue(fn, onWaitComplete, timeout) { + promiseTrue(fn, timeout).then(() => { + onWaitComplete.call(); + }); +} + +function promiseTrue(fn, timeout) { + if (typeof timeout != "undefined") { + // If timeoutWait is less than 500, assume it represents seconds, and + // convert to ms. + if (timeout < 500) { + timeout *= 1000; + } + } + + // Loop until the test function returns true, or until a timeout occurs, + // if a timeout is defined. + let intervalid, timeoutid; + let condition = new Promise(resolve => { + intervalid = setInterval(async () => { + if (await fn.call()) { + resolve(); + } + }, 20); + }); + if (typeof timeout != "undefined") { + condition = Promise.race([ + condition, + new Promise((_, reject) => { + timeoutid = setTimeout(() => { + reject(); + }, timeout); + }), + ]); + } + return condition + .finally(() => { + clearInterval(intervalid); + }) + .then(() => { + clearTimeout(timeoutid); + }); +} + +function waitForNextPaint(cb) { + requestAnimationFrame(_ => requestAnimationFrame(cb)); +} + +function promiseNextPaint() { + return new Promise(resolve => { + waitForNextPaint(resolve); + }); +} + +/** + * Enable or disable the bfcache. + * + * Parameters: + * + * enable: if true, set max_total_viewers to -1 (the default); if false, set + * to 0 (disabled), if a number, set it to that specific number + */ +function enableBFCache(enable) { + // If this is the first time the test called enableBFCache(), + // store the original value of max_total_viewers, so it can + // be restored at the end of the test. + if (typeof gOrigMaxTotalViewers == "undefined") { + gOrigMaxTotalViewers = Services.prefs.getIntPref( + "browser.sessionhistory.max_total_viewers" + ); + } + + if (typeof enable == "boolean") { + if (enable) { + Services.prefs.setIntPref("browser.sessionhistory.max_total_viewers", -1); + } else { + Services.prefs.setIntPref("browser.sessionhistory.max_total_viewers", 0); + } + } else if (typeof enable == "number") { + Services.prefs.setIntPref( + "browser.sessionhistory.max_total_viewers", + enable + ); + } +} + +/* + * get http root for local tests. Use a single extractJarToTmp instead of + * extracting for each test. + * Returns a file://path if we have a .jar file + */ +function getHttpRoot() { + var location = window.location.href; + location = getRootDirectory(location); + var jar = getJar(location); + if (jar != null) { + if (gExtractedPath == null) { + var resolved = extractJarToTmp(jar); + gExtractedPath = resolved.path; + } + } else { + return null; + } + return "file://" + gExtractedPath + "/"; +} + +/** + * Returns the full HTTP url for a file in the mochitest docshell test + * directory. + */ +function getHttpUrl(filename) { + var root = getHttpRoot(); + if (root == null) { + root = "http://mochi.test:8888/chrome/docshell/test/chrome/"; + } + return root + filename; +} + +/** + * A convenience object with methods that return the current test window, + * browser, and document. + */ +var TestWindow = {}; +TestWindow.getWindow = function () { + return document.getElementById("content").contentWindow; +}; +TestWindow.getBrowser = function () { + return document.getElementById("content"); +}; +TestWindow.getDocument = function () { + return document.getElementById("content").contentDocument; +}; diff --git a/docshell/test/chrome/file_viewsource_forbidden_in_iframe.html b/docshell/test/chrome/file_viewsource_forbidden_in_iframe.html new file mode 100644 index 0000000000..fdecbbdfe1 --- /dev/null +++ b/docshell/test/chrome/file_viewsource_forbidden_in_iframe.html @@ -0,0 +1,11 @@ +<!DOCTYPE HTML> +<html> +<head> +<meta charset="utf-8"> +<title>Test ifranes for view-source forbidden in iframe tests</title> +</head> +<body> + <iframe id="testIframe"></iframe> + <iframe id="refIframe"></iframe> +</body> +</html> diff --git a/docshell/test/chrome/gen_template.pl b/docshell/test/chrome/gen_template.pl new file mode 100644 index 0000000000..109d6161cd --- /dev/null +++ b/docshell/test/chrome/gen_template.pl @@ -0,0 +1,39 @@ +#!/usr/bin/perl + +# This script makes docshell test case templates. It takes one argument: +# +# -b: a bugnumber +# +# For example, this command: +# +# perl gen_template.pl -b 303267 +# +# Writes test case template files test_bug303267.xhtml and bug303267_window.xhtml +# to the current directory. + +use FindBin; +use Getopt::Long; +GetOptions("b=i"=> \$bug_number); + +$template = "$FindBin::RealBin/test.template.txt"; + +open(IN,$template) or die("Failed to open input file for reading."); +open(OUT, ">>test_bug" . $bug_number . ".xhtml") or die("Failed to open output file for appending."); +while((defined(IN)) && ($line = <IN>)) { + $line =~ s/{BUGNUMBER}/$bug_number/g; + print OUT $line; +} +close(IN); +close(OUT); + +$template = "$FindBin::RealBin/window.template.txt"; + +open(IN,$template) or die("Failed to open input file for reading."); +open(OUT, ">>bug" . $bug_number . "_window.xhtml") or die("Failed to open output file for appending."); +while((defined(IN)) && ($line = <IN>)) { + $line =~ s/{BUGNUMBER}/$bug_number/g; + print OUT $line; +} +close(IN); +close(OUT); + diff --git a/docshell/test/chrome/generic.html b/docshell/test/chrome/generic.html new file mode 100644 index 0000000000..569a78c05a --- /dev/null +++ b/docshell/test/chrome/generic.html @@ -0,0 +1,12 @@ +<html> +<head> + <title> + generic page + </title> + </head> +<body> +<div id="div1" style="height: 1000px; border: thin solid black;"> + A generic page which can be used any time a test needs to load an arbitrary page via http. + </div> +</body> +</html> diff --git a/docshell/test/chrome/mozFrameType_window.xhtml b/docshell/test/chrome/mozFrameType_window.xhtml new file mode 100644 index 0000000000..e5d0126d22 --- /dev/null +++ b/docshell/test/chrome/mozFrameType_window.xhtml @@ -0,0 +1,49 @@ +<?xml version="1.0"?> +<!-- Any copyright is dedicated to the Public Domain. + - http://creativecommons.org/publicdomain/zero/1.0/ --> +<window title="Test mozFrameType attribute" + xmlns:html="http://www.w3.org/1999/xhtml" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + onload="runTests();"> + + <html:iframe id="normalFrame"/> + <html:iframe id="typeContentFrame" mozframetype="content"/> + + <script type="application/javascript"><![CDATA[ + function runTests() { + let opener = window.arguments[0]; + let SimpleTest = opener.SimpleTest; + + function getDocShellType(frame) { + return frame.contentWindow.docShell.itemType; + } + + var normalFrame = document.getElementById("normalFrame"); + var typeContentFrame = document.getElementById("typeContentFrame"); + + SimpleTest.is(getDocShellType(normalFrame), Ci.nsIDocShellTreeItem.typeChrome, + "normal iframe in chrome document is typeChrome"); + SimpleTest.is(getDocShellType(typeContentFrame), Ci.nsIDocShellTreeItem.typeContent, + "iframe with mozFrameType='content' in chrome document is typeContent"); + + SimpleTest.executeSoon(function () { + // First focus the parent window and then close this one. + SimpleTest.waitForFocus(function() { + let ww = SpecialPowers.Services.ww; + ww.registerNotification(function windowObs(subject, topic, data) { + if (topic == "domwindowclosed") { + ww.unregisterNotification(windowObs); + + // Don't start the next test synchronously! + SimpleTest.executeSoon(function() { + SimpleTest.finish(); + }); + } + }); + + window.close(); + }, opener); + }); + } + ]]></script> +</window> diff --git a/docshell/test/chrome/red.png b/docshell/test/chrome/red.png Binary files differnew file mode 100644 index 0000000000..aa9ce25263 --- /dev/null +++ b/docshell/test/chrome/red.png diff --git a/docshell/test/chrome/test.template.txt b/docshell/test/chrome/test.template.txt new file mode 100644 index 0000000000..b7dd5e5c23 --- /dev/null +++ b/docshell/test/chrome/test.template.txt @@ -0,0 +1,41 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet + href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id={BUGNUMBER}.xul +--> +<window title="Mozilla Bug {BUGNUMBER}" + xmlns:html="http://www.w3.org/1999/xhtml" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + + <title>Test for Bug {BUGNUMBER}</title> + <script type="application/javascript" + src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + +<body xmlns="http://www.w3.org/1999/xhtml"> +<a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id={BUGNUMBER}"> + Mozilla Bug {BUGNUMBER}</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +</body> + +<script class="testbody" type="application/javascript"> +<![CDATA[ + +/** Test for Bug {BUGNUMBER} **/ + +SimpleTest.waitForExplicitFinish(); +window.open("bug{BUGNUMBER}_window.xul", "bug{BUGNUMBER}", + "chrome,width=600,height=600"); + +]]> +</script> + +</window> diff --git a/docshell/test/chrome/test_allowContentRetargeting.html b/docshell/test/chrome/test_allowContentRetargeting.html new file mode 100644 index 0000000000..b6b830138f --- /dev/null +++ b/docshell/test/chrome/test_allowContentRetargeting.html @@ -0,0 +1,76 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + +SimpleTest.waitForExplicitFinish(); +addLoadEvent(runNextTest); + +var TEST_URL = "http://mochi.test:8888/tests/docshell/test/chrome/allowContentRetargeting.sjs"; + +function runNextTest() { + var test = tests.shift(); + if (!test) { + SimpleTest.finish(); + return; + } + test(); +} + +var tests = [ + + // Set allowContentRetargeting = false, load a downloadable URL, verify the + // downloadable stops loading. + function basic() { + var iframe = insertIframe(); + iframe.contentWindow.docShell.allowContentRetargeting = false; + loadIframe(iframe); + }, + + // Set allowContentRetargeting = false on parent docshell, load a downloadable + // URL, verify the downloadable stops loading. + function inherit() { + var docshell = window.docShell; + docshell.allowContentRetargeting = false; + loadIframe(insertIframe()); + }, +]; + +function insertIframe() { + var iframe = document.createElement("iframe"); + document.body.appendChild(iframe); + return iframe; +} + +function loadIframe(iframe) { + iframe.setAttribute("src", TEST_URL); + iframe.contentWindow.docShell. + QueryInterface(Ci.nsIInterfaceRequestor). + getInterface(Ci.nsIWebProgress). + addProgressListener(progressListener, + Ci.nsIWebProgress.NOTIFY_STATE_DOCUMENT); +} + +var progressListener = { + onStateChange(webProgress, req, flags, status) { + if (!(flags & Ci.nsIWebProgressListener.STATE_STOP)) + return; + is(Components.isSuccessCode(status), false, + "Downloadable should have failed to load"); + document.querySelector("iframe").remove(); + runNextTest(); + }, + + QueryInterface: ChromeUtils.generateQI(["nsIWebProgressListener", "nsISupportsWeakReference"]), +}; + + </script> +</head> +<body> +<p id="display"> +</p> +</body> +</html> diff --git a/docshell/test/chrome/test_bug112564.xhtml b/docshell/test/chrome/test_bug112564.xhtml new file mode 100644 index 0000000000..83a087b6d9 --- /dev/null +++ b/docshell/test/chrome/test_bug112564.xhtml @@ -0,0 +1,37 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet + href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=112564 +--> +<window title="Mozilla Bug 112564" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + +<body xmlns="http://www.w3.org/1999/xhtml"> +<a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=112564">Mozilla Bug 112564</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +</body> + +<script class="testbody" type="application/javascript"> +<![CDATA[ + +/** Test for Bug 112564 */ + +SimpleTest.waitForExplicitFinish(); +window.openDialog("bug112564_window.xhtml", "bug112564", + "chrome,width=600,height=600,noopener", window); + +]]> +</script> + +</window> diff --git a/docshell/test/chrome/test_bug113934.xhtml b/docshell/test/chrome/test_bug113934.xhtml new file mode 100644 index 0000000000..99b8ae253c --- /dev/null +++ b/docshell/test/chrome/test_bug113934.xhtml @@ -0,0 +1,29 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=113934 +--> +<window title="Mozilla Bug 113934" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + <script src="chrome://mochikit/content/tests/SimpleTest/WindowSnapshot.js"></script> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=113934" + target="_blank">Mozilla Bug 396519</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"><![CDATA[ + SimpleTest.waitForExplicitFinish(); + + addLoadEvent(function() { + window.openDialog("bug113934_window.xhtml?content", "bug113934", + "chrome,width=800,height=800,noopener", window); + }); + + ]]></script> +</window> diff --git a/docshell/test/chrome/test_bug215405.xhtml b/docshell/test/chrome/test_bug215405.xhtml new file mode 100644 index 0000000000..e9511a6ed1 --- /dev/null +++ b/docshell/test/chrome/test_bug215405.xhtml @@ -0,0 +1,37 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet + href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=215405 +--> +<window title="Mozilla Bug 215405" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + +<body xmlns="http://www.w3.org/1999/xhtml"> +<a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=215405">Mozilla Bug 215405</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +</body> + +<script class="testbody" type="application/javascript"> +<![CDATA[ + +/** Test for Bug 215405 */ + +SimpleTest.waitForExplicitFinish(); +window.openDialog("bug215405_window.xhtml", "bug215405", + "chrome,width=600,height=600,noopener", window); + +]]> +</script> + +</window> diff --git a/docshell/test/chrome/test_bug293235.xhtml b/docshell/test/chrome/test_bug293235.xhtml new file mode 100644 index 0000000000..4696c37557 --- /dev/null +++ b/docshell/test/chrome/test_bug293235.xhtml @@ -0,0 +1,38 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet + href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=293235.xul +--> +<window title="Mozilla Bug 293235" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + +<body xmlns="http://www.w3.org/1999/xhtml"> +<a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=293235"> + Mozilla Bug 293235</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +</body> + +<script class="testbody" type="application/javascript"> +<![CDATA[ + +/** Test for Bug 293235 */ + +SimpleTest.waitForExplicitFinish(); +window.openDialog("bug293235_window.xhtml", "bug293235", + "chrome,width=600,height=600,noopener", window); + +]]> +</script> + +</window> diff --git a/docshell/test/chrome/test_bug294258.xhtml b/docshell/test/chrome/test_bug294258.xhtml new file mode 100644 index 0000000000..8f61a6c299 --- /dev/null +++ b/docshell/test/chrome/test_bug294258.xhtml @@ -0,0 +1,38 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet + href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=294258.xul +--> +<window title="Mozilla Bug 294258" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + +<body xmlns="http://www.w3.org/1999/xhtml"> +<a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=294258"> + Mozilla Bug 294258</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +</body> + +<script class="testbody" type="application/javascript"> +<![CDATA[ + +/** Test for Bug 294258 */ + +SimpleTest.waitForExplicitFinish(); +window.openDialog("bug294258_window.xhtml", "bug294258", + "chrome,width=600,height=600,noopener", window); + +]]> +</script> + +</window> diff --git a/docshell/test/chrome/test_bug298622.xhtml b/docshell/test/chrome/test_bug298622.xhtml new file mode 100644 index 0000000000..8a154b5145 --- /dev/null +++ b/docshell/test/chrome/test_bug298622.xhtml @@ -0,0 +1,38 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet + href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=298622.xul +--> +<window title="Mozilla Bug 298622" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + +<body xmlns="http://www.w3.org/1999/xhtml"> +<a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=298622"> + Mozilla Bug 298622</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +</body> + +<script class="testbody" type="application/javascript"> +<![CDATA[ + +/** Test for Bug 298622 */ + +SimpleTest.waitForExplicitFinish(); +window.openDialog("bug298622_window.xhtml", "bug298622", + "chrome,width=600,height=600,noopener", window); + +]]> +</script> + +</window> diff --git a/docshell/test/chrome/test_bug301397.xhtml b/docshell/test/chrome/test_bug301397.xhtml new file mode 100644 index 0000000000..3da88ecf53 --- /dev/null +++ b/docshell/test/chrome/test_bug301397.xhtml @@ -0,0 +1,38 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet + href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=301397.xul +--> +<window title="Mozilla Bug 301397" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + +<body xmlns="http://www.w3.org/1999/xhtml"> +<a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=301397"> + Mozilla Bug 301397</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +</body> + +<script class="testbody" type="application/javascript"> +<![CDATA[ + +/** Test for Bug 301397 */ + +SimpleTest.waitForExplicitFinish(); +window.openDialog("bug301397_window.xhtml", "bug301397", + "chrome,width=600,height=600,noopener", window); + +]]> +</script> + +</window> diff --git a/docshell/test/chrome/test_bug303267.xhtml b/docshell/test/chrome/test_bug303267.xhtml new file mode 100644 index 0000000000..03af56d344 --- /dev/null +++ b/docshell/test/chrome/test_bug303267.xhtml @@ -0,0 +1,39 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet + href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=303267.xul +--> +<window title="Mozilla Bug 303267" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + +<body xmlns="http://www.w3.org/1999/xhtml"> +<a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=303267">Mozilla Bug 303267</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +</body> + +<script class="testbody" type="application/javascript"> +<![CDATA[ + +SimpleTest.expectAssertions(0, 1); + +/** Test for Bug 303267 */ + +SimpleTest.waitForExplicitFinish(); +window.openDialog("bug303267_window.xhtml", "bug303267", + "chrome,width=600,height=600,noopener", window); + +]]> +</script> + +</window> diff --git a/docshell/test/chrome/test_bug311007.xhtml b/docshell/test/chrome/test_bug311007.xhtml new file mode 100644 index 0000000000..4601c6ec20 --- /dev/null +++ b/docshell/test/chrome/test_bug311007.xhtml @@ -0,0 +1,42 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet + href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=311007.xul +--> +<window title="Mozilla Bug 311007" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + +<body xmlns="http://www.w3.org/1999/xhtml"> +<a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=311007"> + Mozilla Bug 311007</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +</body> + +<script class="testbody" type="application/javascript"> +<![CDATA[ + +if (navigator.platform.startsWith("Win")) { + SimpleTest.expectAssertions(0, 1); +} + +/** Test for Bug 311007 */ + +SimpleTest.waitForExplicitFinish(); +window.openDialog("bug311007_window.xhtml", "bug311007", + "chrome,width=600,height=600,noopener", window); + +]]> +</script> + +</window> diff --git a/docshell/test/chrome/test_bug321671.xhtml b/docshell/test/chrome/test_bug321671.xhtml new file mode 100644 index 0000000000..7855db6f13 --- /dev/null +++ b/docshell/test/chrome/test_bug321671.xhtml @@ -0,0 +1,38 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet + href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=321671.xul +--> +<window title="Mozilla Bug 321671" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + +<body xmlns="http://www.w3.org/1999/xhtml"> +<a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=321671"> + Mozilla Bug 321671</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +</body> + +<script class="testbody" type="application/javascript"> +<![CDATA[ + +/** Test for Bug 321671 */ + +SimpleTest.waitForExplicitFinish(); +window.openDialog("bug321671_window.xhtml", "bug321671", + "chrome,width=600,height=600,scrollbars,noopener", window); + +]]> +</script> + +</window> diff --git a/docshell/test/chrome/test_bug360511.xhtml b/docshell/test/chrome/test_bug360511.xhtml new file mode 100644 index 0000000000..99b9d180f4 --- /dev/null +++ b/docshell/test/chrome/test_bug360511.xhtml @@ -0,0 +1,39 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet + href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=360511.xul +--> +<window title="Mozilla Bug 360511" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"> + </script> + +<body xmlns="http://www.w3.org/1999/xhtml"> +<a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=360511"> + Mozilla Bug 360511</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +</body> + +<script class="testbody" type="application/javascript"> +<![CDATA[ + +/** Test for Bug 360511 */ + +SimpleTest.waitForExplicitFinish(); +window.openDialog("bug360511_window.xhtml", "bug360511", + "chrome,scrollbars,width=600,height=600,noopener", window); + +]]> +</script> + +</window> diff --git a/docshell/test/chrome/test_bug364461.xhtml b/docshell/test/chrome/test_bug364461.xhtml new file mode 100644 index 0000000000..9bdc016ae7 --- /dev/null +++ b/docshell/test/chrome/test_bug364461.xhtml @@ -0,0 +1,43 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet + href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=364461 +--> +<window title="Mozilla Bug 364461" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + +<body xmlns="http://www.w3.org/1999/xhtml"> +<a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=364461">Mozilla Bug 364461</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +</body> + +<script class="testbody" type="application/javascript"> +<![CDATA[ + +/** Test for Bug 364461 */ + +SimpleTest.waitForExplicitFinish(); + +SpecialPowers.pushPrefEnv({ + "set":[["security.data_uri.block_toplevel_data_uri_navigations", false]] +}, runTests); + +function runTests() { + window.openDialog("bug364461_window.xhtml", "bug364461", + "chrome,width=600,height=600,noopener", window); +} +]]> +</script> + +</window> diff --git a/docshell/test/chrome/test_bug396519.xhtml b/docshell/test/chrome/test_bug396519.xhtml new file mode 100644 index 0000000000..7c99bf4a32 --- /dev/null +++ b/docshell/test/chrome/test_bug396519.xhtml @@ -0,0 +1,28 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=396519 +--> +<window title="Mozilla Bug 396519" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=396519" + target="_blank">Mozilla Bug 396519</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"><![CDATA[ + + /** Test for Bug 396519 */ + + SimpleTest.waitForExplicitFinish(); + window.openDialog("bug396519_window.xhtml", "bug396519", + "chrome,width=600,height=600,noopener", window); + + ]]></script> +</window> diff --git a/docshell/test/chrome/test_bug396649.xhtml b/docshell/test/chrome/test_bug396649.xhtml new file mode 100644 index 0000000000..8ac05eee85 --- /dev/null +++ b/docshell/test/chrome/test_bug396649.xhtml @@ -0,0 +1,41 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet + href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=396649.xul +--> +<window title="Mozilla Bug 396649" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + + <script type="application/javascript" + src= + "chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"> + </script> + +<body xmlns="http://www.w3.org/1999/xhtml"> +<a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=396649"> + Mozilla Bug 396649</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +</body> + +<script class="testbody" type="application/javascript"> +<![CDATA[ + +/** Test for Bug 396649 */ + +SimpleTest.waitForExplicitFinish(); +window.openDialog("bug396649_window.xhtml", "bug396649", + "chrome,width=600,height=600,scrollbars,noopener", window); + +]]> +</script> + +</window> diff --git a/docshell/test/chrome/test_bug428288.html b/docshell/test/chrome/test_bug428288.html new file mode 100644 index 0000000000..4697aed515 --- /dev/null +++ b/docshell/test/chrome/test_bug428288.html @@ -0,0 +1,37 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=428288 +--> +<head> + <title>Test for Bug 428288</title> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=428288">Mozilla Bug 428288</a> +<p id="display"></p> +<div id="content" style="display: none"> + <iframe name="target"></iframe> + <a id="crashy" target="target" href="about:blank">crash me</a> +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +/** Test for Bug 428288 */ + +function makeClick() { + var event = document.createEvent("MouseEvents"); + event.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, + false, false, false, false, 0, null); + document.getElementById("crashy").dispatchEvent(event); + return true; +} + +ok(makeClick(), "Crashes if bug 428288 is present"); + +</script> +</pre> +</body> +</html> + diff --git a/docshell/test/chrome/test_bug449778.xhtml b/docshell/test/chrome/test_bug449778.xhtml new file mode 100644 index 0000000000..67e17164ea --- /dev/null +++ b/docshell/test/chrome/test_bug449778.xhtml @@ -0,0 +1,29 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=449778 +--> +<window title="Mozilla Bug 449778" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + <script src="chrome://mochikit/content/tests/SimpleTest/WindowSnapshot.js"></script> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=449778" + target="_blank">Mozilla Bug 396519</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"><![CDATA[ + SimpleTest.waitForExplicitFinish(); + + addLoadEvent(function() { + window.openDialog("bug449778_window.xhtml", "bug449778", + "chrome,width=800,height=800,noopener", window); + }); + + ]]></script> +</window> diff --git a/docshell/test/chrome/test_bug449780.xhtml b/docshell/test/chrome/test_bug449780.xhtml new file mode 100644 index 0000000000..43ed3ce25d --- /dev/null +++ b/docshell/test/chrome/test_bug449780.xhtml @@ -0,0 +1,29 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=449780 +--> +<window title="Mozilla Bug 449780" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + <script src="chrome://mochikit/content/tests/SimpleTest/WindowSnapshot.js"></script> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=449780" + target="_blank">Mozilla Bug 396519</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"><![CDATA[ + SimpleTest.waitForExplicitFinish(); + + addLoadEvent(function() { + window.openDialog("bug449780_window.xhtml", "bug449780", + "chrome,width=800,height=800,noopener", window); + }); + + ]]></script> +</window> diff --git a/docshell/test/chrome/test_bug453650.xhtml b/docshell/test/chrome/test_bug453650.xhtml new file mode 100644 index 0000000000..2283e29206 --- /dev/null +++ b/docshell/test/chrome/test_bug453650.xhtml @@ -0,0 +1,120 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=453650 +--> +<window title="Mozilla Bug 453650" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + + <!-- test code goes here --> + <script type="application/javascript"> + <![CDATA[ + + /** Test for Bug 453650 */ + SimpleTest.waitForExplicitFinish(); + + var iter = runTests(); + nextTest(); + + function* runTests() { + var iframe = document.createXULElement("iframe"); + iframe.style.width = "300px"; + iframe.style.height = "300px"; + iframe.setAttribute("src", "data:text/html,<h1 id='h'>hello</h1>"); + + document.documentElement.appendChild(iframe); + yield whenLoaded(iframe); + info("iframe loaded"); + + var h1 = iframe.contentDocument.getElementById("h"); + let myCallback = function() { h1.style.width = "400px"; }; + info("Calling waitForInterruptibleReflow"); + yield waitForInterruptibleReflow(iframe.docShell, myCallback); + info("got past top-level waitForInterruptibleReflow"); + + myCallback = function() { h1.style.width = "300px"; }; + info("Calling waitForReflow"); + waitForReflow(iframe.docShell, myCallback); + info("got past top-level waitForReflow"); + yield is(300, h1.offsetWidth, "h1 has correct width"); + + SimpleTest.finish(); + } + + function waitForInterruptibleReflow(docShell, + callbackThatShouldTriggerReflow) { + waitForReflow(docShell, callbackThatShouldTriggerReflow, true); + } + + function waitForReflow(docShell, callbackThatShouldTriggerReflow, + interruptible = false) { + info("Entering waitForReflow"); + function done() { + info("Entering done (inside of waitForReflow)"); + + docShell.removeWeakReflowObserver(observer); + SimpleTest.executeSoon(nextTest); + } + + var observer = { + reflow (start, end) { + info("Entering observer.reflow"); + if (interruptible) { + ok(false, "expected interruptible reflow"); + } else { + ok(true, "observed uninterruptible reflow"); + } + + info("times: " + start + ", " + end); + ok(start <= end, "reflow start time lower than end time"); + done(); + }, + + reflowInterruptible (start, end) { + info("Entering observer.reflowInterruptible"); + if (!interruptible) { + ok(false, "expected uninterruptible reflow"); + } else { + ok(true, "observed interruptible reflow"); + } + + info("times: " + start + ", " + end); + ok(start <= end, "reflow start time lower than end time"); + done(); + }, + + QueryInterface: ChromeUtils.generateQI([ + "nsIReflowObserver", + "nsISupportsWeakReference", + ]), + }; + + info("waitForReflow is adding a reflow observer"); + docShell.addWeakReflowObserver(observer); + callbackThatShouldTriggerReflow(); + } + + function whenLoaded(iframe) { + info("entering whenLoaded"); + iframe.addEventListener("load", function() { + SimpleTest.executeSoon(nextTest); + }, { once: true }); + } + + function nextTest() { + info("entering nextTest"); + iter.next(); + } + + ]]> + </script> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=453650" + target="_blank">Mozilla Bug 453650</a> + </body> +</window> diff --git a/docshell/test/chrome/test_bug454235.xhtml b/docshell/test/chrome/test_bug454235.xhtml new file mode 100644 index 0000000000..d64f701f8e --- /dev/null +++ b/docshell/test/chrome/test_bug454235.xhtml @@ -0,0 +1,40 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=454235 +--> +<window title="Mozilla Bug 454235" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=454235" + target="_blank">Mozilla Bug 454235</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"><![CDATA[ + + /** Test for Bug 454235 */ +SimpleTest.waitForExplicitFinish(); + +SimpleTest.waitForFocus(doTest); + +function doTest() { + var hiddenBrowser = document.getElementById("hiddenBrowser"); + + hiddenBrowser.contentWindow.focus(); + ok(!hiddenBrowser.contentDocument.hasFocus(), "hidden browser is unfocusable"); + + SimpleTest.finish(); +} + + + + ]]></script> + <box flex="1" style="visibility: hidden; border:5px black solid"> + <browser style="border:5px blue solid" id="hiddenBrowser" src="bug454235-subframe.xhtml"/> + </box> +</window> diff --git a/docshell/test/chrome/test_bug456980.xhtml b/docshell/test/chrome/test_bug456980.xhtml new file mode 100644 index 0000000000..d1741209c6 --- /dev/null +++ b/docshell/test/chrome/test_bug456980.xhtml @@ -0,0 +1,29 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=456980 +--> +<window title="Mozilla Bug 456980" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + <script src="chrome://mochikit/content/tests/SimpleTest/WindowSnapshot.js"></script> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=456980" + target="_blank">Mozilla Bug 396519</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"><![CDATA[ + SimpleTest.waitForExplicitFinish(); + + addLoadEvent(function() { + window.openDialog("bug113934_window.xhtml?chrome", "bug456980", + "chrome,width=800,height=800,noopener", window); + }); + + ]]></script> +</window> diff --git a/docshell/test/chrome/test_bug565388.xhtml b/docshell/test/chrome/test_bug565388.xhtml new file mode 100644 index 0000000000..23af2c146d --- /dev/null +++ b/docshell/test/chrome/test_bug565388.xhtml @@ -0,0 +1,79 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=565388 +--> +<window title="Mozilla Bug 565388" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + + <!-- test code goes here --> + <script type="application/javascript"> + <![CDATA[ + + /** Test for Bug 565388 */ + SimpleTest.waitForExplicitFinish(); + +function test() { + var progressListener = { + add(docShell, callback) { + this.callback = callback; + this.docShell = docShell; + docShell. + QueryInterface(Ci.nsIInterfaceRequestor). + getInterface(Ci.nsIWebProgress). + addProgressListener(this, Ci.nsIWebProgress.NOTIFY_STATE_WINDOW); + }, + + finish() { + this.docShell. + QueryInterface(Ci.nsIInterfaceRequestor). + getInterface(Ci.nsIWebProgress). + removeProgressListener(this); + this.callback(); + }, + + onStateChange (webProgress, req, flags, status) { + if (req.name.startsWith("data:application/vnd.mozilla.xul")) { + if (flags & Ci.nsIWebProgressListener.STATE_STOP) + this.finish(); + } + }, + + QueryInterface: ChromeUtils.generateQI([ + "nsIWebProgressListener", + "nsISupportsWeakReference", + ]), + } + + var systemPrincipal = Cc["@mozilla.org/systemprincipal;1"] + .getService(Ci.nsIPrincipal); + var webNav = SpecialPowers.Services.appShell.createWindowlessBrowser(true); + var docShell = webNav.docShell; + docShell.createAboutBlankContentViewer(systemPrincipal, systemPrincipal); + var win = docShell.contentViewer.DOMDocument.defaultView; + + progressListener.add(docShell, function(){ + is(win.document.documentURI, "data:application/xhtml+xml;charset=utf-8,<window/>"); + webNav.close(); + SimpleTest.finish(); + }); + + win.location = "data:application/xhtml+xml;charset=utf-8,<window/>"; +} + +addLoadEvent(function onLoad() { + test(); +}); + + ]]> + </script> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=565388" + target="_blank">Mozilla Bug 565388</a> + </body> +</window> diff --git a/docshell/test/chrome/test_bug582176.xhtml b/docshell/test/chrome/test_bug582176.xhtml new file mode 100644 index 0000000000..5f189ae87b --- /dev/null +++ b/docshell/test/chrome/test_bug582176.xhtml @@ -0,0 +1,38 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet + href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=582176.xul +--> +<window title="Mozilla Bug 582176" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + +<body xmlns="http://www.w3.org/1999/xhtml"> +<a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=582176"> + Mozilla Bug 582176</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +</body> + +<script class="testbody" type="application/javascript"> +<![CDATA[ + +/** Test for Bug 582176 */ + +SimpleTest.waitForExplicitFinish(); +window.openDialog("bug582176_window.xhtml", "bug582176", + "chrome,width=600,height=600,noopener", window); + +]]> +</script> + +</window> diff --git a/docshell/test/chrome/test_bug608669.xhtml b/docshell/test/chrome/test_bug608669.xhtml new file mode 100644 index 0000000000..f6a62b0802 --- /dev/null +++ b/docshell/test/chrome/test_bug608669.xhtml @@ -0,0 +1,80 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=608669 +--> +<window title="Mozilla Bug 608669" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=608669" + target="_blank">Mozilla Bug 608669</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"><![CDATA[ + +/** Test for Bug 608669 */ +SimpleTest.waitForExplicitFinish(); + +addLoadEvent(nextTest); + +let gen = doTest(); + +function nextTest() { + gen.next(); +} + +let chromeWindow = window.browsingContext.topChromeWindow; + +function* doTest() { + var notificationCount = 0; + var observer = { + observe(aSubject, aTopic, aData) { + is(aTopic, "chrome-document-global-created", + "correct topic"); + is(aData, "null", + "correct data"); + notificationCount++; + } + }; + + var os = SpecialPowers.Services.obs; + os.addObserver(observer, "chrome-document-global-created"); + os.addObserver(observer, "content-document-global-created"); + + is(notificationCount, 0, "initial count"); + + // create a new window + var testWin = chromeWindow.open("", "bug 608669", "chrome,width=600,height=600"); + testWin.x = "y"; + is(notificationCount, 1, "after created window"); + + // Try loading in the window + testWin.location = "bug608669.xhtml"; + chromeWindow.onmessage = nextTest; + yield undefined; + is(notificationCount, 1, "after first load"); + is(testWin.x, "y", "reused window"); + + // Try loading again in the window + testWin.location = "bug608669.xhtml?x"; + chromeWindow.onmessage = nextTest; + yield undefined; + is(notificationCount, 2, "after second load"); + is("x" in testWin, false, "didn't reuse window"); + + chromeWindow.onmessage = null; + + testWin.close(); + + os.removeObserver(observer, "chrome-document-global-created"); + os.removeObserver(observer, "content-document-global-created"); + SimpleTest.finish(); +} + + ]]></script> +</window> diff --git a/docshell/test/chrome/test_bug662200.xhtml b/docshell/test/chrome/test_bug662200.xhtml new file mode 100644 index 0000000000..19a386ba97 --- /dev/null +++ b/docshell/test/chrome/test_bug662200.xhtml @@ -0,0 +1,38 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet + href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=662200.xul +--> +<window title="Mozilla Bug 662200" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + +<body xmlns="http://www.w3.org/1999/xhtml"> +<a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=662200"> + Mozilla Bug 662200</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +</body> + +<script class="testbody" type="application/javascript"> +<![CDATA[ + +/** Test for Bug 662200 */ + +SimpleTest.waitForExplicitFinish(); +window.openDialog("bug662200_window.xhtml", "bug662200", + "chrome,width=600,height=600,noopener", window); + +]]> +</script> + +</window> diff --git a/docshell/test/chrome/test_bug690056.xhtml b/docshell/test/chrome/test_bug690056.xhtml new file mode 100644 index 0000000000..5f7a2b9534 --- /dev/null +++ b/docshell/test/chrome/test_bug690056.xhtml @@ -0,0 +1,26 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=690056 +--> +<window title="Mozilla Bug 690056" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=690056" + target="_blank">Mozilla Bug 690056</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"> + <![CDATA[ + /** Test for Bug 690056 */ +SimpleTest.waitForExplicitFinish(); +window.openDialog("bug690056_window.xhtml", "bug690056", + "chrome,width=600,height=600,noopener", window); + ]]> + </script> +</window> diff --git a/docshell/test/chrome/test_bug789773.xhtml b/docshell/test/chrome/test_bug789773.xhtml new file mode 100644 index 0000000000..0f4a67fc10 --- /dev/null +++ b/docshell/test/chrome/test_bug789773.xhtml @@ -0,0 +1,67 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=789773 +--> +<window title="Mozilla Bug 789773" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=789773" + target="_blank">Mozilla Bug 789773</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"> + <![CDATA[ + /* Test for Bug 789773. + * + * See comment 50 for the situation we're testing against here. + * + * Note that the failure mode of this test is to hang, and hang the browser on quit. + * This is an unfortunate occurance, but that's why we're testing it. + */ + SimpleTest.waitForExplicitFinish(); + + const {AppConstants} = ChromeUtils.import("resource://gre/modules/AppConstants.jsm"); + + var calledListenerForBrowserChromeURL = false; + var testProgressListener = { + START_DOC: Ci.nsIWebProgressListener.STATE_START | Ci.nsIWebProgressListener.STATE_IS_DOCUMENT, + onStateChange(wp, req, stateFlags, status) { + let browserChromeFileName = AppConstants.BROWSER_CHROME_URL.split("/").reverse()[0]; + if (req.name.includes(browserChromeFileName)) { + wp.DOMWindow; // Force the lazy creation of a DOM window. + calledListenerForBrowserChromeURL = true; + } + if (req.name.includes("mozilla.html") && (stateFlags & Ci.nsIWebProgressListener.STATE_STOP)) + finishTest(); + }, + QueryInterface: ChromeUtils.generateQI([ + "nsIWebProgressListener", + "nsISupportsWeakReference", + ]), + } + + // Add our progress listener + var webProgress = Cc['@mozilla.org/docloaderservice;1'].getService(Ci.nsIWebProgress); + webProgress.addProgressListener(testProgressListener, Ci.nsIWebProgress.NOTIFY_STATE_REQUEST); + + // Open the window. + var popup = window.open("about:mozilla", "_blank", "width=640,height=400"); + + // Wait for the window to load. + function finishTest() { + webProgress.removeProgressListener(testProgressListener); + ok(true, "Loaded the popup window without spinning forever in the event loop!"); + ok(calledListenerForBrowserChromeURL, "Should have called the progress listener for browser.xhtml"); + popup.close(); + SimpleTest.finish(); + } + + ]]> + </script> +</window> diff --git a/docshell/test/chrome/test_bug846906.xhtml b/docshell/test/chrome/test_bug846906.xhtml new file mode 100644 index 0000000000..74bfdf7036 --- /dev/null +++ b/docshell/test/chrome/test_bug846906.xhtml @@ -0,0 +1,94 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=846906 +--> +<window title="Mozilla Bug 846906" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + + <!-- test code goes here --> + <script type="application/javascript"> + <![CDATA[ + + /** Test for Bug 846906 */ + SimpleTest.waitForExplicitFinish(); + + var appShellService = SpecialPowers.Services.appShell; + ok(appShellService, "Should be able to get app shell service"); + + var windowlessBrowser = appShellService.createWindowlessBrowser(); + ok(windowlessBrowser, "Should be able to create windowless browser"); + + ok(windowlessBrowser instanceof Ci.nsIWindowlessBrowser, + "Windowless browser should implement nsIWindowlessBrowser"); + + var webNavigation = windowlessBrowser.QueryInterface(Ci.nsIWebNavigation); + ok(webNavigation, "Windowless browser should implement nsIWebNavigation"); + + var interfaceRequestor = windowlessBrowser.QueryInterface(Ci.nsIInterfaceRequestor); + ok(interfaceRequestor, "Should be able to query interface requestor interface"); + + var docShell = windowlessBrowser.docShell; + ok(docShell, "Should be able to get doc shell interface"); + + var document = webNavigation.document; + ok(document, "Should be able to get document"); + + var iframe = document.createXULElement("iframe"); + ok(iframe, "Should be able to create iframe"); + + iframe.onload = function () { + ok(true, "Should receive initial onload event"); + + iframe.onload = function () { + ok(true, "Should receive onload event"); + + var contentDocument = iframe.contentDocument; + ok(contentDocument, "Should be able to get content document"); + + var div = contentDocument.getElementById("div1"); + ok(div, "Should be able to get element by id"); + + var rect = div.getBoundingClientRect(); + ok(rect, "Should be able to get bounding client rect"); + + // xxx: can we do better than hardcoding these values here? + is(rect.width, 1024); + is(rect.height, 768); + + windowlessBrowser.close(); + + // Once the browser is closed, nsIWebNavigation and + // nsIInterfaceRequestor methods should no longer be accessible. + try { + windowlessBrowser.getInterface(Ci.nsIDocShell); + ok(false); + } catch (e) { + is(e.result, Cr.NS_ERROR_NULL_POINTER); + } + + try { + windowlessBrowser.document; + ok(false); + } catch (e) { + is(e.result, Cr.NS_ERROR_NULL_POINTER); + } + + SimpleTest.finish(); + }; + iframe.setAttribute("src", "http://mochi.test:8888/chrome/docshell/test/chrome/bug846906.html"); + }; + document.documentElement.appendChild(iframe); + + ]]> + </script> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=846906" + target="_blank">Mozilla Bug 846906</a> + </body> +</window> diff --git a/docshell/test/chrome/test_bug89419.xhtml b/docshell/test/chrome/test_bug89419.xhtml new file mode 100644 index 0000000000..848982180f --- /dev/null +++ b/docshell/test/chrome/test_bug89419.xhtml @@ -0,0 +1,38 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet + href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=89419.xul +--> +<window title="Mozilla Bug 89419" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + +<body xmlns="http://www.w3.org/1999/xhtml"> +<a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=89419"> + Mozilla Bug 89419</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +</body> + +<script class="testbody" type="application/javascript"> +<![CDATA[ + +/** Test for Bug 89419 */ + +SimpleTest.waitForExplicitFinish(); +window.openDialog("bug89419_window.xhtml", "bug89419", + "chrome,width=600,height=600,noopener", window); + +]]> +</script> + +</window> diff --git a/docshell/test/chrome/test_bug909218.html b/docshell/test/chrome/test_bug909218.html new file mode 100644 index 0000000000..bcbcc176eb --- /dev/null +++ b/docshell/test/chrome/test_bug909218.html @@ -0,0 +1,117 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + +SimpleTest.waitForExplicitFinish(); +addLoadEvent(test); + +// The default flags we will stick on the docShell - every request made by the +// docShell should include those flags. +const TEST_FLAGS = Ci.nsIRequest.LOAD_ANONYMOUS | + Ci.nsIRequest.LOAD_BYPASS_CACHE | + Ci.nsIRequest.INHIBIT_CACHING; + +var TEST_URL = "http://mochi.test:8888/chrome/docshell/test/chrome/bug909218.html"; + +// These are the requests we expect to see loading TEST_URL into our iframe. + +// The test entry-point. The basic outline is: +// * Create an iframe and set defaultLoadFlags on its docShell. +// * Add a web progress listener to observe each request as the iframe is +// loaded, and check that each request has the flags we specified. +// * Load our test URL into the iframe and wait for the load to complete. +function test() { + var iframe = document.createElement("iframe"); + document.body.appendChild(iframe); + var docShell = iframe.contentWindow.docShell; + // Add our progress listener - when it notices the top-level document is + // complete, the test will end. + RequestWatcher.init(docShell, SimpleTest.finish); + // Set the flags we care about, then load our test URL. + docShell.defaultLoadFlags = TEST_FLAGS; + iframe.setAttribute("src", TEST_URL); +} + +// an nsIWebProgressListener that checks all requests made by the docShell +// have the flags we expect. +var RequestWatcher = { + init(docShell, callback) { + this.callback = callback; + this.docShell = docShell; + docShell. + QueryInterface(Ci.nsIInterfaceRequestor). + getInterface(Ci.nsIWebProgress). + addProgressListener(this, Ci.nsIWebProgress.NOTIFY_STATE_REQUEST | + Ci.nsIWebProgress.NOTIFY_STATE_DOCUMENT); + // These are the requests we expect to see - initialize each to have a + // count of zero. + this.requestCounts = {}; + for (var url of [ + TEST_URL, + // content loaded by the above test html. + "http://mochi.test:8888/chrome/docshell/test/chrome/bug909218.js", + "http://mochi.test:8888/tests/SimpleTest/test.css", + "http://mochi.test:8888/tests/docshell/test/chrome/red.png", + // the content of an iframe in the test html. + "http://mochi.test:8888/chrome/docshell/test/chrome/generic.html", + ]) { + this.requestCounts[url] = 0; + } + }, + + // Finalize the test after we detect a completed load. We check we saw the + // correct requests and make a callback to exit. + finalize() { + ok(Object.keys(this.requestCounts).length, "we expected some requests"); + for (var url in this.requestCounts) { + var count = this.requestCounts[url]; + // As we are looking at all request states, we expect more than 1 for + // each URL - 0 or 1 would imply something went wrong - >1 just means + // multiple states for each request were recorded, which we don't care + // about (we do care they all have the correct flags though - but we + // do that in onStateChange) + ok(count > 1, url + " saw " + count + " requests"); + } + this.docShell. + QueryInterface(Ci.nsIInterfaceRequestor). + getInterface(Ci.nsIWebProgress). + removeProgressListener(this); + this.callback(); + }, + + onStateChange(webProgress, req, flags, status) { + // We are checking requests - if there isn't one, ignore it. + if (!req) { + return; + } + // We will usually see requests for 'about:document-onload-blocker' not + // have the flag, so we just ignore them. + // We also see, eg, resource://gre-resources/loading-image.png, so + // skip resource:// URLs too. + // We may also see, eg, chrome://global/skin/icons/chevron.svg, so + // skip chrome:// URLs too. + if (req.name.startsWith("about:") || req.name.startsWith("resource:") || + req.name.startsWith("chrome:") || req.name.startsWith("documentchannel:")) { + return; + } + is(req.loadFlags & TEST_FLAGS, TEST_FLAGS, "request " + req.name + " has the expected flags"); + this.requestCounts[req.name] += 1; + var stopFlags = Ci.nsIWebProgressListener.STATE_STOP | + Ci.nsIWebProgressListener.STATE_IS_DOCUMENT; + if (req.name == TEST_URL && (flags & stopFlags) == stopFlags) { + this.finalize(); + } + }, + QueryInterface: ChromeUtils.generateQI([ + "nsIWebProgressListener", + "nsISupportsWeakReference", + ]), +}; + +</script> +</head> +</html> diff --git a/docshell/test/chrome/test_bug92598.xhtml b/docshell/test/chrome/test_bug92598.xhtml new file mode 100644 index 0000000000..1b89e3eeb3 --- /dev/null +++ b/docshell/test/chrome/test_bug92598.xhtml @@ -0,0 +1,37 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet + href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=92598 +--> +<window title="Mozilla Bug 92598" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + +<body xmlns="http://www.w3.org/1999/xhtml"> +<a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=92598">Mozilla Bug 92598</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +</body> + +<script class="testbody" type="application/javascript"> +<![CDATA[ + +/** Test for Bug 92598 */ + +SimpleTest.waitForExplicitFinish(); +window.openDialog("bug92598_window.xhtml", "bug92598", + "chrome,width=600,height=600,noopener", window); + +]]> +</script> + +</window> diff --git a/docshell/test/chrome/test_docRedirect.sjs b/docshell/test/chrome/test_docRedirect.sjs new file mode 100644 index 0000000000..4050eb06d7 --- /dev/null +++ b/docshell/test/chrome/test_docRedirect.sjs @@ -0,0 +1,6 @@ +function handleRequest(request, response) { + response.setStatusLine(request.httpVersion, 301, "Moved Permanently"); + // eslint-disable-next-line @microsoft/sdl/no-insecure-url + response.setHeader("Location", "http://example.org/"); + response.write("Hello world!"); +} diff --git a/docshell/test/chrome/test_docRedirect.xhtml b/docshell/test/chrome/test_docRedirect.xhtml new file mode 100644 index 0000000000..1688d9823e --- /dev/null +++ b/docshell/test/chrome/test_docRedirect.xhtml @@ -0,0 +1,91 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet type="text/css" href="/tests/SimpleTest/test.css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1342989 +--> +<window title="Mozilla Bug 1342989" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/> + + <script type="application/javascript"> + <![CDATA[ + SimpleTest.waitForExplicitFinish(); + + const WEB_PROGRESS_LISTENER_FLAGS = + Object.keys(Ci.nsIWebProgressListener).filter( + propName => propName.startsWith("STATE_") + ); + + function bitFlagsToNames(flags, knownNames, intf) { + return knownNames.map( (F) => { + return (flags & intf[F]) ? F : undefined; + }).filter( (s) => !!s ); + } + + var progressListener = { + add(docShell, callback) { + this.callback = callback; + this.docShell = docShell; + docShell. + QueryInterface(Ci.nsIInterfaceRequestor). + getInterface(Ci.nsIWebProgress). + addProgressListener(this, Ci.nsIWebProgress.NOTIFY_STATE_ALL); + }, + + finish(success) { + this.docShell. + QueryInterface(Ci.nsIInterfaceRequestor). + getInterface(Ci.nsIWebProgress). + removeProgressListener(this); + this.callback(success); + }, + + onStateChange (webProgress, req, flags, status) { + if (!(flags & Ci.nsIWebProgressListener.STATE_IS_DOCUMENT) && + !(flags & Ci.nsIWebProgressListener.STATE_IS_REDIRECTED_DOCUMENT)) + return; + + var channel = req.QueryInterface(Ci.nsIChannel); + + if (flags & Ci.nsIWebProgressListener.STATE_IS_REDIRECTED_DOCUMENT) { + SimpleTest.is(channel.URI.host, "example.org", + "Should be redirected to example.org (see test_docRedirect.sjs)"); + this.finish(true); + } + + // Fail in case we didn't receive document redirection event. + if (flags & Ci.nsIWebProgressListener.STATE_STOP) + this.finish(false); + }, + + QueryInterface: ChromeUtils.generateQI([ + "nsIWebProgressListener", + "nsISupportsWeakReference", + ]), + } + + var webNav = SpecialPowers.Services.appShell.createWindowlessBrowser(true); + let docShell = webNav.docShell; + let system = Cc["@mozilla.org/systemprincipal;1"].getService(Ci.nsIPrincipal); + docShell.createAboutBlankContentViewer(system, system); + + progressListener.add(docShell, function(success) { + webNav.close(); + SimpleTest.is(success, true, "Received document redirect event"); + SimpleTest.finish(); + }); + + var win = docShell.contentViewer.DOMDocument.defaultView; + // eslint-disable-next-line @microsoft/sdl/no-insecure-url + win.location = "http://example.com/chrome/docshell/test/chrome/test_docRedirect.sjs" + + ]]> + </script> + + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1342989" + target="_blank">Mozilla Bug 1342989</a> + </body> +</window> diff --git a/docshell/test/chrome/test_mozFrameType.xhtml b/docshell/test/chrome/test_mozFrameType.xhtml new file mode 100644 index 0000000000..f9740a761b --- /dev/null +++ b/docshell/test/chrome/test_mozFrameType.xhtml @@ -0,0 +1,42 @@ +<?xml version="1.0"?> +<!-- Any copyright is dedicated to the Public Domain. + - http://creativecommons.org/publicdomain/zero/1.0/ --> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet + href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=769771 +--> +<window title="Test mozFrameType attribute" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + +<body xmlns="http://www.w3.org/1999/xhtml"> +<p id="display"></p> +<div id="content" style="display: none"> +</div> +<pre id="test"> +</pre> +</body> + +<script class="testbody" type="application/javascript"> +<![CDATA[ + +if (navigator.platform.startsWith("Win")) { + SimpleTest.expectAssertions(0, 1); +} + +/** Test for Bug 769771 */ +SimpleTest.waitForExplicitFinish(); + +addLoadEvent(function () { + window.openDialog("mozFrameType_window.xhtml", "mozFrameType", + "chrome,width=600,height=600,noopener", window); +}); + +]]> +</script> + +</window> diff --git a/docshell/test/chrome/test_open_and_immediately_close_opener.html b/docshell/test/chrome/test_open_and_immediately_close_opener.html new file mode 100644 index 0000000000..bb5f6f054d --- /dev/null +++ b/docshell/test/chrome/test_open_and_immediately_close_opener.html @@ -0,0 +1,54 @@ +<!DOCTYPE html> +<html> +<head> + <title>Test for Bug 1702678</title> + <meta charset="utf-8"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1702678">Mozilla Bug 1702678</a> + +<script type="application/javascript"> +"use strict"; + +const HTML = ` +<!DOCTYPE html> +<html> +<head> + <meta charset="utf-8"> + <script> + // We need to queue a promise reaction job whilch will close the window + // during the nested event loop spun up by the window opening code. + Promise.resolve().then(() => { + window.close(); + }); + window.open("data:text/html,Hello"); + <\/script> +</head> +</html> +`; + +add_task(async function() { + // This bug only manifests when opening tabs in new windows. + await SpecialPowers.pushPrefEnv({ + set: [["browser.link.open_newwindow", 2]], + }); + + // Create a window in a new BrowsingContextGroup so that it will be the last + // window in the group when it closes, and the group will be destroyed. + window.open(`data:text/html,${encodeURIComponent(HTML)}`, "", "noopener"); + + // Make a few trips through the event loop to ensure we've had a chance to + // open and close the relevant windows. + for (let i = 0; i < 10; i++) { + await new Promise(resolve => setTimeout(resolve, 0)); + } + + ok(true, "We didn't crash"); +}); +</script> + +</body> +</html> + diff --git a/docshell/test/chrome/test_viewsource_forbidden_in_iframe.xhtml b/docshell/test/chrome/test_viewsource_forbidden_in_iframe.xhtml new file mode 100644 index 0000000000..0cc45c7821 --- /dev/null +++ b/docshell/test/chrome/test_viewsource_forbidden_in_iframe.xhtml @@ -0,0 +1,159 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin/global.css"?> +<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=624883 +--> +<window title="Mozilla Bug 624883" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" /> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=624883" + target="_blank">Mozilla Bug 624883</a> + </body> + + <!-- test code goes here --> + <iframe type="content" onload="startTest()" src="file_viewsource_forbidden_in_iframe.html"></iframe> + + <script type="application/javascript"> + <![CDATA[ + + SimpleTest.waitForExplicitFinish(); + + // We create a promise that will resolve with the error message + // on a network error page load and reject on any other load. + function createNetworkErrorMessagePromise(frame) { + return new Promise(function(resolve, reject) { + + // Error pages do not fire "load" events, so use a progressListener. + var originalDocumentURI = frame.contentDocument.documentURI; + var progressListener = { + onLocationChange(aWebProgress, aRequest, aLocation, aFlags) { + // Make sure nothing other than an error page is loaded. + if (!(aFlags & Ci.nsIWebProgressListener.LOCATION_CHANGE_ERROR_PAGE)) { + reject("location change was not to an error page"); + } + }, + + onStateChange(aWebProgress, aRequest, aStateFlags, aStatus) { + // Wait until the documentURI changes (from about:blank) this should + // be the error page URI. + var documentURI = frame.contentDocument.documentURI; + if (documentURI == originalDocumentURI) { + return; + } + + aWebProgress.removeProgressListener(progressListener, + Ci.nsIWebProgress.NOTIFY_ALL); + var matchArray = /about:neterror\?.*&d=([^&]*)/.exec(documentURI); + if (!matchArray) { + reject("no network error message found in URI") + return; + } + + var errorMsg = matchArray[1]; + resolve(decodeURIComponent(errorMsg)); + }, + + QueryInterface: ChromeUtils.generateQI(["nsIWebProgressListener", + "nsISupportsWeakReference"]) + }; + + frame.contentWindow.docShell + .QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIWebProgress) + .addProgressListener(progressListener, + Ci.nsIWebProgress.NOTIFY_LOCATION | + Ci.nsIWebProgress.NOTIFY_STATE_REQUEST); + }); + } + + function startTest() { + // Get a reference message that we know will be an unknown protocol message, + // so we can use it for comparisons in the test cases. + var refIframe = window[0].document.getElementById("refIframe"); + var refErrorPromise = createNetworkErrorMessagePromise(refIframe); + + refErrorPromise.then( + function(msg) { + window.refErrorMsg = msg; + var testIframe = window[0].document.getElementById("testIframe"); + + // Run test cases on load of "about:blank", so that the URI always changes + // and we can detect this in our Promise. + testIframe.onload = runNextTestCase; + testIframe.src = "about:blank"; + }, + function(reason) { + ok(false, "Could not get reference error message", reason); + SimpleTest.finish(); + }) + .catch(function(e) { + ok(false, "Unexpected exception thrown getting reference error message", e); + }); + + refIframe.src = "wibble://example.com"; + } + + function runTestCase(testCase) { + var testIframe = window[0].document.getElementById("testIframe"); + var expectedErrorMsg = window.refErrorMsg.replace("wibble", testCase.expectedProtocolList); + + var testErrorPromise = createNetworkErrorMessagePromise(testIframe); + testErrorPromise.then( + function(actualErrorMsg) { + is(actualErrorMsg, expectedErrorMsg, testCase.desc); + testIframe.src = "about:blank"; + }, + function(reason) { + ok(false, testCase.desc, reason); + testIframe.src = "about:blank"; + }) + .catch(function(e) { + ok(false, testCase.desc + " - unexpected exception thrown", e); + }); + + testIframe.src = testCase.protocols + "://example.com/!/"; + } + + var testCaseIndex = -1; + let testCases = [ + { + desc: "Test 1: view-source should not be allowed in an iframe", + protocols: "view-source:http", + expectedProtocolList: "view-source, http" + }, + { + desc: "Test 2: jar:view-source should not be allowed in an iframe", + protocols: "jar:view-source:http", + expectedProtocolList: "jar, view-source, http" + }, + { + desc: "Test 3: if invalid protocol first should report before view-source", + protocols: "wibble:view-source:http", + // Nothing after the invalid protocol gets set as a proper nested URI, + // so the list stops there. + expectedProtocolList: "wibble" + }, + { + desc: "Test 4: if view-source first should report before invalid protocol", + protocols: "view-source:wibble:http", + expectedProtocolList: "view-source, wibble" + } + ]; + + function runNextTestCase() { + ++testCaseIndex; + if (testCaseIndex == testCases.length) { + SimpleTest.finish(); + return; + } + + runTestCase(testCases[testCaseIndex]); + } + + ]]> + </script> +</window> diff --git a/docshell/test/chrome/window.template.txt b/docshell/test/chrome/window.template.txt new file mode 100644 index 0000000000..4c520dc075 --- /dev/null +++ b/docshell/test/chrome/window.template.txt @@ -0,0 +1,44 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> + +<window id="{BUGNUMBER}Test" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + width="600" + height="600" + onload="setTimeout(nextTest,0);" + title="bug {BUGNUMBER} test"> + + <script type="application/javascript" + src="docshell_helpers.js"> + </script> + + <script type="application/javascript"><![CDATA[ + + // Define the generator-iterator for the tests. + var tests = testIterator(); + + //// + // Execute the next test in the generator function. + // + function nextTest() { + tests.next(); + } + + //// + // Generator function for test steps for bug {BUGNUMBER}: + // Description goes here. + // + function testIterator() + { + // Test steps go here. See bug303267_window.xhtml for an example. + + // Tell the framework the test is finished. Include the final 'yield' + // statement to prevent a StopIteration exception from being thrown. + finish(); + yield undefined; + } + + ]]></script> + + <browser type="content" primary="true" flex="1" id="content" src="about:blank"/> +</window> |