summaryrefslogtreecommitdiffstats
path: root/browser/components/sessionstore/test/browser_frametree.js
diff options
context:
space:
mode:
Diffstat (limited to 'browser/components/sessionstore/test/browser_frametree.js')
-rw-r--r--browser/components/sessionstore/test/browser_frametree.js131
1 files changed, 131 insertions, 0 deletions
diff --git a/browser/components/sessionstore/test/browser_frametree.js b/browser/components/sessionstore/test/browser_frametree.js
new file mode 100644
index 000000000..a342f8c66
--- /dev/null
+++ b/browser/components/sessionstore/test/browser_frametree.js
@@ -0,0 +1,131 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+const URL = HTTPROOT + "browser_frametree_sample.html";
+const URL_FRAMESET = HTTPROOT + "browser_frametree_sample_frameset.html";
+
+/**
+ * This ensures that loading a page normally, aborting a page load, reloading
+ * a page, navigating using the bfcache, and ignoring frames that were
+ * created dynamically work as expect. We expect the frame tree to be reset
+ * when a page starts loading and we also expect a valid frame tree to exist
+ * when it has stopped loading.
+ */
+add_task(function test_frametree() {
+ const FRAME_TREE_SINGLE = { href: URL };
+ const FRAME_TREE_FRAMESET = {
+ href: URL_FRAMESET,
+ children: [{href: URL}, {href: URL}, {href: URL}]
+ };
+
+ // Create a tab with a single frame.
+ let tab = gBrowser.addTab(URL);
+ let browser = tab.linkedBrowser;
+ yield promiseNewFrameTree(browser);
+ yield checkFrameTree(browser, FRAME_TREE_SINGLE,
+ "loading a page resets and creates the frame tree correctly");
+
+ // Load the frameset and create two frames dynamically, the first on
+ // DOMContentLoaded and the second on load.
+ yield sendMessage(browser, "ss-test:createDynamicFrames", {id: "frames", url: URL});
+ browser.loadURI(URL_FRAMESET);
+ yield promiseNewFrameTree(browser);
+ yield checkFrameTree(browser, FRAME_TREE_FRAMESET,
+ "dynamic frames created on or after the load event are ignored");
+
+ // Go back to the previous single-frame page. There will be no load event as
+ // the page is still in the bfcache. We thus make sure this type of navigation
+ // resets the frame tree.
+ browser.goBack();
+ yield promiseNewFrameTree(browser);
+ yield checkFrameTree(browser, FRAME_TREE_SINGLE,
+ "loading from bfache resets and creates the frame tree correctly");
+
+ // Load the frameset again but abort the load early.
+ // The frame tree should still be reset and created.
+ browser.loadURI(URL_FRAMESET);
+ executeSoon(() => browser.stop());
+ yield promiseNewFrameTree(browser);
+
+ // Load the frameset and check the tree again.
+ yield sendMessage(browser, "ss-test:createDynamicFrames", {id: "frames", url: URL});
+ browser.loadURI(URL_FRAMESET);
+ yield promiseNewFrameTree(browser);
+ yield checkFrameTree(browser, FRAME_TREE_FRAMESET,
+ "reloading a page resets and creates the frame tree correctly");
+
+ // Cleanup.
+ gBrowser.removeTab(tab);
+});
+
+/**
+ * This test ensures that we ignore frames that were created dynamically at or
+ * after the load event. SessionStore can't handle these and will not restore
+ * or collect any data for them.
+ */
+add_task(function test_frametree_dynamic() {
+ // The frame tree as expected. The first two frames are static
+ // and the third one was created on DOMContentLoaded.
+ const FRAME_TREE = {
+ href: URL_FRAMESET,
+ children: [{href: URL}, {href: URL}, {href: URL}]
+ };
+ const FRAME_TREE_REMOVED = {
+ href: URL_FRAMESET,
+ children: [{href: URL}, {href: URL}]
+ };
+
+ // Add an empty tab for a start.
+ let tab = gBrowser.addTab("about:blank");
+ let browser = tab.linkedBrowser;
+ yield promiseBrowserLoaded(browser);
+
+ // Create dynamic frames on "DOMContentLoaded" and on "load".
+ yield sendMessage(browser, "ss-test:createDynamicFrames", {id: "frames", url: URL});
+ browser.loadURI(URL_FRAMESET);
+ yield promiseNewFrameTree(browser);
+
+ // Check that the frame tree does not contain the frame created on "load".
+ // The two static frames and the one created on DOMContentLoaded must be in
+ // the tree.
+ yield checkFrameTree(browser, FRAME_TREE,
+ "frame tree contains first four frames");
+
+ // Remove the last frame in the frameset.
+ yield sendMessage(browser, "ss-test:removeLastFrame", {id: "frames"});
+ // Check that the frame tree didn't change.
+ yield checkFrameTree(browser, FRAME_TREE,
+ "frame tree contains first four frames");
+
+ // Remove the last frame in the frameset.
+ yield sendMessage(browser, "ss-test:removeLastFrame", {id: "frames"});
+ // Check that the frame tree excludes the removed frame.
+ yield checkFrameTree(browser, FRAME_TREE_REMOVED,
+ "frame tree contains first three frames");
+
+ // Cleanup.
+ gBrowser.removeTab(tab);
+});
+
+/**
+ * Checks whether the current frame hierarchy of a given |browser| matches the
+ * |expected| frame hierarchy.
+ */
+function checkFrameTree(browser, expected, msg) {
+ return sendMessage(browser, "ss-test:mapFrameTree").then(tree => {
+ is(JSON.stringify(tree), JSON.stringify(expected), msg);
+ });
+}
+
+/**
+ * Returns a promise that will be resolved when the given |browser| has loaded
+ * and we received messages saying that its frame tree has been reset and
+ * recollected.
+ */
+function promiseNewFrameTree(browser) {
+ let reset = promiseContentMessage(browser, "ss-test:onFrameTreeCollected");
+ let collect = promiseContentMessage(browser, "ss-test:onFrameTreeCollected");
+ return Promise.all([reset, collect]);
+}