5 <title>Bug
1326251</title>
7 var bc
= new BroadcastChannel("file_bug1326251");
8 bc
.onmessage = function(event
) {
9 if ("nextTest" in event
.data
) {
10 testSteps
[event
.data
.nextTest
]();
14 function is(val1
, val2
, msg
) {
15 bc
.postMessage({type
: "is", value1
: val1
, value2
: val2
, message
: msg
});
18 function ok(val
, msg
) {
19 bc
.postMessage({type
: "ok", value
: val
, message
: msg
});
22 const BASE_URL
= "http://mochi.test:8888/tests/docshell/test/navigation/";
25 // Test 1: Create dynamic iframe with bfcache enabled.
26 // Navigate static / dynamic iframes, then navigate top level window
27 // and navigate back. Both iframes should still exist with history
29 window
.onunload
= null; // enable bfcache
30 await
createDynamicFrame(document
);
31 await
loadUriInFrame(document
.getElementById("staticFrame"), "frame1.html");
32 await
loadUriInFrame(document
.getElementById("dynamicFrame"), "frame1.html");
33 await
loadUriInFrame(document
.getElementById("staticFrame"), "frame2.html");
34 await
loadUriInFrame(document
.getElementById("dynamicFrame"), "frame2.html");
35 is(history
.length
, 5, "history.length");
36 window
.location
= "goback.html";
39 let webNav
= SpecialPowers
.wrap(window
)
41 .QueryInterface(SpecialPowers
.Ci
.nsIWebNavigation
);
42 let shistory
= webNav
.sessionHistory
;
43 is(webNav
.canGoForward
, true, "canGoForward");
44 is(shistory
.index
, 4, "shistory.index");
45 is(history
.length
, 6, "history.length");
46 is(document
.getElementById("staticFrame").contentWindow
.location
.href
, BASE_URL
+ "frame2.html", "staticFrame location");
47 is(document
.getElementById("dynamicFrame").contentWindow
.location
.href
, BASE_URL
+ "frame2.html", "dynamicFrame location");
49 // Test 2: Load another page in dynamic iframe, canGoForward should be
51 await
loadUriInFrame(document
.getElementById("dynamicFrame"), "frame3.html");
52 is(webNav
.canGoForward
, false, "canGoForward");
53 is(shistory
.index
, 5, "shistory.index");
54 is(history
.length
, 6, "history.length");
56 // Test 3: Navigate to antoher page with bfcache disabled, all dynamic
57 // iframe entries should be removed.
58 window
.onunload = function() {}; // disable bfcache
59 window
.location
= "goback.html";
62 let windowWrap
= SpecialPowers
.wrap(window
);
63 let docShell
= windowWrap
.docShell
;
64 let shistory
= docShell
.QueryInterface(SpecialPowers
.Ci
.nsIWebNavigation
)
66 // Now staticFrame has frame0 -> frame1 -> frame2.
67 if (!SpecialPowers
.Services
.appinfo
.sessionHistoryInParent
) {
68 // *EntryIndex attributes aren't meaningful when the session history
69 // lives in the parent process.
70 is(docShell
.previousEntryIndex
, 3, "docShell.previousEntryIndex");
71 is(docShell
.loadedEntryIndex
, 2, "docShell.loadedEntryIndex");
73 is(shistory
.index
, 2, "shistory.index");
74 is(history
.length
, 4, "history.length");
75 is(document
.getElementById("staticFrame").contentWindow
.location
.href
, BASE_URL
+ "frame2.html", "staticFrame location");
76 ok(!document
.getElementById("dynamicFrame"), "dynamicFrame should not exist");
78 // Test 4: Load a nested frame in the static frame, navigate the inner
79 // static frame, add a inner dynamic frame and navigate the dynamic
80 // frame. Then navigate the outer static frame and go back. The inner
81 // iframe should show the last entry of inner static frame.
82 let staticFrame
= document
.getElementById("staticFrame");
83 staticFrame
.width
= "320px";
84 staticFrame
.height
= "360px";
85 await
loadUriInFrame(staticFrame
, "iframe_static.html");
86 let innerStaticFrame
= staticFrame
.contentDocument
.getElementById("staticFrame");
87 await
loadUriInFrame(innerStaticFrame
, "frame1.html");
88 let innerDynamicFrame
= await
createDynamicFrame(staticFrame
.contentDocument
, "frame2.html");
89 await
loadUriInFrame(innerDynamicFrame
, "frame3.html");
90 // staticFrame: frame0 -> frame1 -> frame2 -> iframe_static
91 // innerStaticFrame: frame0 -> frame1
92 // innerDynamicFrame: frame2 -> frame3
93 is(shistory
.index
, 5, "shistory.index");
94 is(history
.length
, 6, "history.length");
96 // Wait for 2 load events - navigation and goback.
97 let onloadPromise
= awaitOnload(staticFrame
, 2);
98 await
loadUriInFrame(staticFrame
, "goback.html");
100 // staticFrame: frame0 -> frame1 -> frame2 -> iframe_static -> goback
101 // innerStaticFrame: frame0 -> frame1
102 is(shistory
.index
, 4, "shistory.index");
103 is(history
.length
, 6, "history.length");
104 innerStaticFrame
= staticFrame
.contentDocument
.getElementById("staticFrame");
105 is(innerStaticFrame
.contentDocument
.location
.href
, BASE_URL
+ "frame1.html", "innerStaticFrame location");
106 ok(!staticFrame
.contentDocument
.getElementById("dynamicFrame"), "innerDynamicFrame should not exist");
108 // Test 5: Insert and navigate inner dynamic frame again with bfcache
109 // enabled, and navigate top level window to a special page which will
110 // evict bfcache then goback. Verify that dynamic entries are correctly
111 // removed in this case.
112 window
.onunload
= null; // enable bfcache
113 staticFrame
.width
= "320px";
114 staticFrame
.height
= "360px";
115 innerDynamicFrame
= await
createDynamicFrame(staticFrame
.contentDocument
, "frame2.html");
116 await
loadUriInFrame(innerDynamicFrame
, "frame3.html");
117 // staticFrame: frame0 -> frame1 -> frame2 -> iframe_static
118 // innerStaticFrame: frame0 -> frame1
119 // innerDynamicFrame: frame2 -> frame3
120 is(shistory
.index
, 5, "shistory.index");
121 is(history
.length
, 6, "history.length");
122 window
.location
= "file_bug1326251_evict_cache.html";
125 let windowWrap
= SpecialPowers
.wrap(window
);
126 let docShell
= windowWrap
.docShell
;
127 let shistory
= docShell
.QueryInterface(SpecialPowers
.Ci
.nsIWebNavigation
)
129 // staticFrame: frame0 -> frame1 -> frame2 -> iframe_static
130 // innerStaticFrame: frame0 -> frame1
131 if (!SpecialPowers
.Services
.appinfo
.sessionHistoryInParent
) {
132 // *EntryIndex attributes aren't meaningful when the session history
133 // lives in the parent process.
134 is(docShell
.previousEntryIndex
, 5, "docShell.previousEntryIndex");
135 is(docShell
.loadedEntryIndex
, 4, "docShell.loadedEntryIndex");
137 is(shistory
.index
, 4, "shistory.index");
138 is(history
.length
, 6, "history.length");
139 let staticFrame
= document
.getElementById("staticFrame");
140 let innerStaticFrame
= staticFrame
.contentDocument
.getElementById("staticFrame");
141 is(innerStaticFrame
.contentDocument
.location
.href
, BASE_URL
+ "frame1.html", "innerStaticFrame location");
142 ok(!staticFrame
.contentDocument
.getElementById("dynamicFrame"), "innerDynamicFrame should not exist");
144 // Test 6: Insert and navigate inner dynamic frame and then reload outer
145 // frame. Verify that inner dynamic frame entries are all removed.
146 staticFrame
.width
= "320px";
147 staticFrame
.height
= "360px";
148 let innerDynamicFrame
= await
createDynamicFrame(staticFrame
.contentDocument
, "frame2.html");
149 await
loadUriInFrame(innerDynamicFrame
, "frame3.html");
150 // staticFrame: frame0 -> frame1 -> frame2 -> iframe_static
151 // innerStaticFrame: frame0 -> frame1
152 // innerDynamicFrame: frame2 -> frame3
153 is(shistory
.index
, 5, "shistory.index");
154 is(history
.length
, 6, "history.length");
155 let staticFrameLoadPromise
= new Promise(resolve
=> {
156 staticFrame
.onload
= resolve
;
158 staticFrame
.contentWindow
.location
.reload();
159 await staticFrameLoadPromise
;
160 // staticFrame: frame0 -> frame1 -> frame2 -> iframe_static
161 // innerStaticFrame: frame0 -> frame1
162 is(shistory
.index
, 4, "shistory.index");
163 is(history
.length
, 5, "history.length");
164 innerStaticFrame
= staticFrame
.contentDocument
.getElementById("staticFrame");
165 is(innerStaticFrame
.contentDocument
.location
.href
, BASE_URL
+ "frame1.html", "innerStaticFrame location");
166 ok(!staticFrame
.contentDocument
.getElementById("dynamicFrame"), "innerDynamicFrame should not exist");
167 bc
.postMessage("finishTest");
173 function awaitOnload(frame
, occurances
= 1) {
174 return new Promise(function(resolve
, reject
) {
176 frame
.addEventListener("load", function listener(e
) {
177 if (++count
== occurances
) {
178 frame
.removeEventListener("load", listener
);
179 setTimeout(resolve
, 0);
185 async
function createDynamicFrame(targetDocument
, frameSrc
= "frame0.html") {
186 let dynamicFrame
= targetDocument
.createElement("iframe");
187 let onloadPromise
= awaitOnload(dynamicFrame
);
188 dynamicFrame
.id
= "dynamicFrame";
189 dynamicFrame
.src
= frameSrc
;
190 let container
= targetDocument
.getElementById("frameContainer");
191 container
.appendChild(dynamicFrame
);
196 async
function loadUriInFrame(frame
, uri
) {
197 let onloadPromise
= awaitOnload(frame
);
199 return onloadPromise
;
203 bc
.postMessage("requestNextTest");
207 <body onpageshow=
"test();">
208 <div id=
"frameContainer">
209 <iframe id=
"staticFrame" src=
"frame0.html"></iframe>