summaryrefslogtreecommitdiffstats
path: root/browser/components/sessionstore/test/browser_frame_history.js
diff options
context:
space:
mode:
Diffstat (limited to 'browser/components/sessionstore/test/browser_frame_history.js')
-rw-r--r--browser/components/sessionstore/test/browser_frame_history.js230
1 files changed, 230 insertions, 0 deletions
diff --git a/browser/components/sessionstore/test/browser_frame_history.js b/browser/components/sessionstore/test/browser_frame_history.js
new file mode 100644
index 0000000000..1db32e74ab
--- /dev/null
+++ b/browser/components/sessionstore/test/browser_frame_history.js
@@ -0,0 +1,230 @@
+/* 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/. */
+/* eslint-disable mozilla/no-arbitrary-setTimeout */
+
+/**
+ Ensure that frameset history works properly when restoring a tab,
+ provided that the frameset is static.
+ */
+
+// Loading a toplevel frameset
+add_task(async function () {
+ await SpecialPowers.pushPrefEnv({
+ set: [["browser.navigation.requireUserInteraction", false]],
+ });
+
+ let testURL =
+ getRootDirectory(gTestPath) + "browser_frame_history_index.html";
+ let tab = BrowserTestUtils.addTab(gBrowser, testURL);
+ gBrowser.selectedTab = tab;
+
+ info("Opening a page with three frames, 4 loads should take place");
+ await waitForLoadsInBrowser(tab.linkedBrowser, 4);
+
+ let browser_b =
+ tab.linkedBrowser.contentDocument.getElementsByTagName("frame")[1];
+ let document_b = browser_b.contentDocument;
+ let links = document_b.getElementsByTagName("a");
+
+ // We're going to click on the first link, so listen for another load event
+ info("Clicking on link 1, 1 load should take place");
+ let promise = waitForLoadsInBrowser(tab.linkedBrowser, 1);
+ EventUtils.sendMouseEvent(
+ { type: "click" },
+ links[0],
+ browser_b.contentWindow
+ );
+ await promise;
+
+ info("Clicking on link 2, 1 load should take place");
+ promise = waitForLoadsInBrowser(tab.linkedBrowser, 1);
+ EventUtils.sendMouseEvent(
+ { type: "click" },
+ links[1],
+ browser_b.contentWindow
+ );
+ await promise;
+
+ info("Close then un-close page, 4 loads should take place");
+ await promiseRemoveTabAndSessionState(tab);
+ let newTab = ss.undoCloseTab(window, 0);
+ await waitForLoadsInBrowser(newTab.linkedBrowser, 4);
+
+ info("Go back in time, 1 load should take place");
+ gBrowser.goBack();
+ await waitForLoadsInBrowser(newTab.linkedBrowser, 1);
+
+ let expectedURLEnds = ["a.html", "b.html", "c1.html"];
+ let frames =
+ newTab.linkedBrowser.contentDocument.getElementsByTagName("frame");
+ for (let i = 0; i < frames.length; i++) {
+ is(
+ frames[i].contentDocument.location.href,
+ getRootDirectory(gTestPath) +
+ "browser_frame_history_" +
+ expectedURLEnds[i],
+ "frame " + i + " has the right url"
+ );
+ }
+ gBrowser.removeTab(newTab);
+});
+
+// Loading the frameset inside an iframe
+add_task(async function () {
+ let testURL =
+ getRootDirectory(gTestPath) + "browser_frame_history_index2.html";
+ let tab = BrowserTestUtils.addTab(gBrowser, testURL);
+ gBrowser.selectedTab = tab;
+
+ info(
+ "iframe: Opening a page with an iframe containing three frames, 5 loads should take place"
+ );
+ await waitForLoadsInBrowser(tab.linkedBrowser, 5);
+
+ let browser_b = tab.linkedBrowser.contentDocument
+ .getElementById("iframe")
+ .contentDocument.getElementsByTagName("frame")[1];
+ let document_b = browser_b.contentDocument;
+ let links = document_b.getElementsByTagName("a");
+
+ // We're going to click on the first link, so listen for another load event
+ info("iframe: Clicking on link 1, 1 load should take place");
+ let promise = waitForLoadsInBrowser(tab.linkedBrowser, 1);
+ EventUtils.sendMouseEvent(
+ { type: "click" },
+ links[0],
+ browser_b.contentWindow
+ );
+ await promise;
+
+ info("iframe: Clicking on link 2, 1 load should take place");
+ promise = waitForLoadsInBrowser(tab.linkedBrowser, 1);
+ EventUtils.sendMouseEvent(
+ { type: "click" },
+ links[1],
+ browser_b.contentWindow
+ );
+ await promise;
+
+ info("iframe: Close then un-close page, 5 loads should take place");
+ await promiseRemoveTabAndSessionState(tab);
+ let newTab = ss.undoCloseTab(window, 0);
+ await waitForLoadsInBrowser(newTab.linkedBrowser, 5);
+
+ info("iframe: Go back in time, 1 load should take place");
+ gBrowser.goBack();
+ await waitForLoadsInBrowser(newTab.linkedBrowser, 1);
+
+ let expectedURLEnds = ["a.html", "b.html", "c1.html"];
+ let frames = newTab.linkedBrowser.contentDocument
+ .getElementById("iframe")
+ .contentDocument.getElementsByTagName("frame");
+ for (let i = 0; i < frames.length; i++) {
+ is(
+ frames[i].contentDocument.location.href,
+ getRootDirectory(gTestPath) +
+ "browser_frame_history_" +
+ expectedURLEnds[i],
+ "frame " + i + " has the right url"
+ );
+ }
+ gBrowser.removeTab(newTab);
+});
+
+// Now, test that we don't record history if the iframe is added dynamically
+add_task(async function () {
+ // Start with an empty history
+ let blankState = JSON.stringify({
+ windows: [
+ {
+ tabs: [
+ { entries: [{ url: "about:blank", triggeringPrincipal_base64 }] },
+ ],
+ _closedTabs: [],
+ },
+ ],
+ _closedWindows: [],
+ });
+ await setBrowserState(blankState);
+
+ let testURL =
+ getRootDirectory(gTestPath) + "browser_frame_history_index_blank.html";
+ let tab = BrowserTestUtils.addTab(gBrowser, testURL);
+ gBrowser.selectedTab = tab;
+ await waitForLoadsInBrowser(tab.linkedBrowser, 1);
+
+ info(
+ "dynamic: Opening a page with an iframe containing three frames, 4 dynamic loads should take place"
+ );
+ let doc = tab.linkedBrowser.contentDocument;
+ let iframe = doc.createElement("iframe");
+ iframe.id = "iframe";
+ iframe.src = "browser_frame_history_index.html";
+ doc.body.appendChild(iframe);
+ await waitForLoadsInBrowser(tab.linkedBrowser, 4);
+
+ let browser_b = tab.linkedBrowser.contentDocument
+ .getElementById("iframe")
+ .contentDocument.getElementsByTagName("frame")[1];
+ let document_b = browser_b.contentDocument;
+ let links = document_b.getElementsByTagName("a");
+
+ // We're going to click on the first link, so listen for another load event
+ info("dynamic: Clicking on link 1, 1 load should take place");
+ let promise = waitForLoadsInBrowser(tab.linkedBrowser, 1);
+ EventUtils.sendMouseEvent(
+ { type: "click" },
+ links[0],
+ browser_b.contentWindow
+ );
+ await promise;
+
+ info("dynamic: Clicking on link 2, 1 load should take place");
+ promise = waitForLoadsInBrowser(tab.linkedBrowser, 1);
+ EventUtils.sendMouseEvent(
+ { type: "click" },
+ links[1],
+ browser_b.contentWindow
+ );
+ await promise;
+
+ info("Check in the state that we have not stored this history");
+ let state = ss.getBrowserState();
+ info(JSON.stringify(JSON.parse(state), null, "\t"));
+ is(
+ state.indexOf("c1.html"),
+ -1,
+ "History entry was not stored in the session state"
+ );
+ gBrowser.removeTab(tab);
+});
+
+// helper functions
+function waitForLoadsInBrowser(aBrowser, aLoadCount) {
+ return new Promise(resolve => {
+ let loadCount = 0;
+ aBrowser.addEventListener(
+ "load",
+ function listener(aEvent) {
+ if (++loadCount < aLoadCount) {
+ info(
+ "Got " + loadCount + " loads, waiting until we have " + aLoadCount
+ );
+ return;
+ }
+
+ aBrowser.removeEventListener("load", listener, true);
+ resolve();
+ },
+ true
+ );
+ });
+}
+
+function timeout(delay, task) {
+ return new Promise((resolve, reject) => {
+ setTimeout(() => resolve(true), delay);
+ task.then(() => resolve(false), reject);
+ });
+}