diff options
Diffstat (limited to 'browser/components/sessionstore/test/browser_frametree.js')
-rw-r--r-- | browser/components/sessionstore/test/browser_frametree.js | 131 |
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]); +} |