forked from mirrors/gecko-dev
		
	
		
			
				
	
	
		
			131 lines
		
	
	
	
		
			4.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			131 lines
		
	
	
	
		
			4.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
/* 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(async 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 = BrowserTestUtils.addTab(gBrowser, URL);
 | 
						|
  let browser = tab.linkedBrowser;
 | 
						|
  await promiseNewFrameTree(browser);
 | 
						|
  await 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.
 | 
						|
  await sendMessage(browser, "ss-test:createDynamicFrames", {id: "frames", url: URL});
 | 
						|
  browser.loadURI(URL_FRAMESET);
 | 
						|
  await promiseNewFrameTree(browser);
 | 
						|
  await 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();
 | 
						|
  await promiseNewFrameTree(browser);
 | 
						|
  await 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());
 | 
						|
  await promiseNewFrameTree(browser);
 | 
						|
 | 
						|
  // Load the frameset and check the tree again.
 | 
						|
  await sendMessage(browser, "ss-test:createDynamicFrames", {id: "frames", url: URL});
 | 
						|
  browser.loadURI(URL_FRAMESET);
 | 
						|
  await promiseNewFrameTree(browser);
 | 
						|
  await 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(async 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 = BrowserTestUtils.addTab(gBrowser, "about:blank");
 | 
						|
  let browser = tab.linkedBrowser;
 | 
						|
  await promiseBrowserLoaded(browser);
 | 
						|
 | 
						|
  // Create dynamic frames on "DOMContentLoaded" and on "load".
 | 
						|
  await sendMessage(browser, "ss-test:createDynamicFrames", {id: "frames", url: URL});
 | 
						|
  browser.loadURI(URL_FRAMESET);
 | 
						|
  await 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.
 | 
						|
  await checkFrameTree(browser, FRAME_TREE,
 | 
						|
    "frame tree contains first four frames");
 | 
						|
 | 
						|
  // Remove the last frame in the frameset.
 | 
						|
  await sendMessage(browser, "ss-test:removeLastFrame", {id: "frames"});
 | 
						|
  // Check that the frame tree didn't change.
 | 
						|
  await checkFrameTree(browser, FRAME_TREE,
 | 
						|
    "frame tree contains first four frames");
 | 
						|
 | 
						|
  // Remove the last frame in the frameset.
 | 
						|
  await sendMessage(browser, "ss-test:removeLastFrame", {id: "frames"});
 | 
						|
  // Check that the frame tree excludes the removed frame.
 | 
						|
  await 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]);
 | 
						|
}
 |