summaryrefslogtreecommitdiffstats
path: root/docshell/test/navigation/file_bug1326251.html
diff options
context:
space:
mode:
Diffstat (limited to 'docshell/test/navigation/file_bug1326251.html')
-rw-r--r--docshell/test/navigation/file_bug1326251.html212
1 files changed, 212 insertions, 0 deletions
diff --git a/docshell/test/navigation/file_bug1326251.html b/docshell/test/navigation/file_bug1326251.html
new file mode 100644
index 0000000000..57a81f46f1
--- /dev/null
+++ b/docshell/test/navigation/file_bug1326251.html
@@ -0,0 +1,212 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <meta charset="utf-8">
+ <title>Bug 1326251</title>
+ <script>
+ var bc = new BroadcastChannel("file_bug1326251");
+ bc.onmessage = function(event) {
+ if ("nextTest" in event.data) {
+ testSteps[event.data.nextTest]();
+ }
+ }
+
+ function is(val1, val2, msg) {
+ bc.postMessage({type: "is", value1: val1, value2: val2, message: msg});
+ }
+
+ function ok(val, msg) {
+ bc.postMessage({type: "ok", value: val, message: msg});
+ }
+
+ const BASE_URL = "http://mochi.test:8888/tests/docshell/test/navigation/";
+ let testSteps = [
+ async function() {
+ // Test 1: Create dynamic iframe with bfcache enabled.
+ // Navigate static / dynamic iframes, then navigate top level window
+ // and navigate back. Both iframes should still exist with history
+ // entries preserved.
+ window.onunload = null; // enable bfcache
+ await createDynamicFrame(document);
+ await loadUriInFrame(document.getElementById("staticFrame"), "frame1.html");
+ await loadUriInFrame(document.getElementById("dynamicFrame"), "frame1.html");
+ await loadUriInFrame(document.getElementById("staticFrame"), "frame2.html");
+ await loadUriInFrame(document.getElementById("dynamicFrame"), "frame2.html");
+ is(history.length, 5, "history.length");
+ window.location = "goback.html";
+ },
+ async function() {
+ let webNav = SpecialPowers.wrap(window)
+ .docShell
+ .QueryInterface(SpecialPowers.Ci.nsIWebNavigation);
+ let shistory = webNav.sessionHistory;
+ is(webNav.canGoForward, true, "canGoForward");
+ is(shistory.index, 4, "shistory.index");
+ is(history.length, 6, "history.length");
+ is(document.getElementById("staticFrame").contentWindow.location.href, BASE_URL + "frame2.html", "staticFrame location");
+ is(document.getElementById("dynamicFrame").contentWindow.location.href, BASE_URL + "frame2.html", "dynamicFrame location");
+
+ // Test 2: Load another page in dynamic iframe, canGoForward should be
+ // false.
+ await loadUriInFrame(document.getElementById("dynamicFrame"), "frame3.html");
+ is(webNav.canGoForward, false, "canGoForward");
+ is(shistory.index, 5, "shistory.index");
+ is(history.length, 6, "history.length");
+
+ // Test 3: Navigate to antoher page with bfcache disabled, all dynamic
+ // iframe entries should be removed.
+ window.onunload = function() {}; // disable bfcache
+ window.location = "goback.html";
+ },
+ async function() {
+ let windowWrap = SpecialPowers.wrap(window);
+ let docShell = windowWrap.docShell;
+ let shistory = docShell.QueryInterface(SpecialPowers.Ci.nsIWebNavigation)
+ .sessionHistory;
+ // Now staticFrame has frame0 -> frame1 -> frame2.
+ if (!SpecialPowers.Services.appinfo.sessionHistoryInParent) {
+ // *EntryIndex attributes aren't meaningful when the session history
+ // lives in the parent process.
+ is(docShell.previousEntryIndex, 3, "docShell.previousEntryIndex");
+ is(docShell.loadedEntryIndex, 2, "docShell.loadedEntryIndex");
+ }
+ is(shistory.index, 2, "shistory.index");
+ is(history.length, 4, "history.length");
+ is(document.getElementById("staticFrame").contentWindow.location.href, BASE_URL + "frame2.html", "staticFrame location");
+ ok(!document.getElementById("dynamicFrame"), "dynamicFrame should not exist");
+
+ // Test 4: Load a nested frame in the static frame, navigate the inner
+ // static frame, add a inner dynamic frame and navigate the dynamic
+ // frame. Then navigate the outer static frame and go back. The inner
+ // iframe should show the last entry of inner static frame.
+ let staticFrame = document.getElementById("staticFrame");
+ staticFrame.width = "320px";
+ staticFrame.height = "360px";
+ await loadUriInFrame(staticFrame, "iframe_static.html");
+ let innerStaticFrame = staticFrame.contentDocument.getElementById("staticFrame");
+ await loadUriInFrame(innerStaticFrame, "frame1.html");
+ let innerDynamicFrame = await createDynamicFrame(staticFrame.contentDocument, "frame2.html");
+ await loadUriInFrame(innerDynamicFrame, "frame3.html");
+ // staticFrame: frame0 -> frame1 -> frame2 -> iframe_static
+ // innerStaticFrame: frame0 -> frame1
+ // innerDynamicFrame: frame2 -> frame3
+ is(shistory.index, 5, "shistory.index");
+ is(history.length, 6, "history.length");
+
+ // Wait for 2 load events - navigation and goback.
+ let onloadPromise = awaitOnload(staticFrame, 2);
+ await loadUriInFrame(staticFrame, "goback.html");
+ await onloadPromise;
+ // staticFrame: frame0 -> frame1 -> frame2 -> iframe_static -> goback
+ // innerStaticFrame: frame0 -> frame1
+ is(shistory.index, 4, "shistory.index");
+ is(history.length, 6, "history.length");
+ innerStaticFrame = staticFrame.contentDocument.getElementById("staticFrame");
+ is(innerStaticFrame.contentDocument.location.href, BASE_URL + "frame1.html", "innerStaticFrame location");
+ ok(!staticFrame.contentDocument.getElementById("dynamicFrame"), "innerDynamicFrame should not exist");
+
+ // Test 5: Insert and navigate inner dynamic frame again with bfcache
+ // enabled, and navigate top level window to a special page which will
+ // evict bfcache then goback. Verify that dynamic entries are correctly
+ // removed in this case.
+ window.onunload = null; // enable bfcache
+ staticFrame.width = "320px";
+ staticFrame.height = "360px";
+ innerDynamicFrame = await createDynamicFrame(staticFrame.contentDocument, "frame2.html");
+ await loadUriInFrame(innerDynamicFrame, "frame3.html");
+ // staticFrame: frame0 -> frame1 -> frame2 -> iframe_static
+ // innerStaticFrame: frame0 -> frame1
+ // innerDynamicFrame: frame2 -> frame3
+ is(shistory.index, 5, "shistory.index");
+ is(history.length, 6, "history.length");
+ window.location = "file_bug1326251_evict_cache.html";
+ },
+ async function() {
+ let windowWrap = SpecialPowers.wrap(window);
+ let docShell = windowWrap.docShell;
+ let shistory = docShell.QueryInterface(SpecialPowers.Ci.nsIWebNavigation)
+ .sessionHistory;
+ // staticFrame: frame0 -> frame1 -> frame2 -> iframe_static
+ // innerStaticFrame: frame0 -> frame1
+ if (!SpecialPowers.Services.appinfo.sessionHistoryInParent) {
+ // *EntryIndex attributes aren't meaningful when the session history
+ // lives in the parent process.
+ is(docShell.previousEntryIndex, 5, "docShell.previousEntryIndex");
+ is(docShell.loadedEntryIndex, 4, "docShell.loadedEntryIndex");
+ }
+ is(shistory.index, 4, "shistory.index");
+ is(history.length, 6, "history.length");
+ let staticFrame = document.getElementById("staticFrame");
+ let innerStaticFrame = staticFrame.contentDocument.getElementById("staticFrame");
+ is(innerStaticFrame.contentDocument.location.href, BASE_URL + "frame1.html", "innerStaticFrame location");
+ ok(!staticFrame.contentDocument.getElementById("dynamicFrame"), "innerDynamicFrame should not exist");
+
+ // Test 6: Insert and navigate inner dynamic frame and then reload outer
+ // frame. Verify that inner dynamic frame entries are all removed.
+ staticFrame.width = "320px";
+ staticFrame.height = "360px";
+ let innerDynamicFrame = await createDynamicFrame(staticFrame.contentDocument, "frame2.html");
+ await loadUriInFrame(innerDynamicFrame, "frame3.html");
+ // staticFrame: frame0 -> frame1 -> frame2 -> iframe_static
+ // innerStaticFrame: frame0 -> frame1
+ // innerDynamicFrame: frame2 -> frame3
+ is(shistory.index, 5, "shistory.index");
+ is(history.length, 6, "history.length");
+ let staticFrameLoadPromise = new Promise(resolve => {
+ staticFrame.onload = resolve;
+ });
+ staticFrame.contentWindow.location.reload();
+ await staticFrameLoadPromise;
+ // staticFrame: frame0 -> frame1 -> frame2 -> iframe_static
+ // innerStaticFrame: frame0 -> frame1
+ is(shistory.index, 4, "shistory.index");
+ is(history.length, 5, "history.length");
+ innerStaticFrame = staticFrame.contentDocument.getElementById("staticFrame");
+ is(innerStaticFrame.contentDocument.location.href, BASE_URL + "frame1.html", "innerStaticFrame location");
+ ok(!staticFrame.contentDocument.getElementById("dynamicFrame"), "innerDynamicFrame should not exist");
+ bc.postMessage("finishTest");
+ bc.close();
+ window.close();
+ },
+ ];
+
+ function awaitOnload(frame, occurances = 1) {
+ return new Promise(function(resolve, reject) {
+ let count = 0;
+ frame.addEventListener("load", function listener(e) {
+ if (++count == occurances) {
+ frame.removeEventListener("load", listener);
+ setTimeout(resolve, 0);
+ }
+ });
+ });
+ }
+
+ async function createDynamicFrame(targetDocument, frameSrc = "frame0.html") {
+ let dynamicFrame = targetDocument.createElement("iframe");
+ let onloadPromise = awaitOnload(dynamicFrame);
+ dynamicFrame.id = "dynamicFrame";
+ dynamicFrame.src = frameSrc;
+ let container = targetDocument.getElementById("frameContainer");
+ container.appendChild(dynamicFrame);
+ await onloadPromise;
+ return dynamicFrame;
+ }
+
+ async function loadUriInFrame(frame, uri) {
+ let onloadPromise = awaitOnload(frame);
+ frame.src = uri;
+ return onloadPromise;
+ }
+
+ function test() {
+ bc.postMessage("requestNextTest");
+ }
+ </script>
+ </head>
+ <body onpageshow="test();">
+ <div id="frameContainer">
+ <iframe id="staticFrame" src="frame0.html"></iframe>
+ </div>
+ </body>
+</html>