summaryrefslogtreecommitdiffstats
path: root/docshell/test/browser/browser_browsingContext-01.js
diff options
context:
space:
mode:
Diffstat (limited to 'docshell/test/browser/browser_browsingContext-01.js')
-rw-r--r--docshell/test/browser/browser_browsingContext-01.js205
1 files changed, 205 insertions, 0 deletions
diff --git a/docshell/test/browser/browser_browsingContext-01.js b/docshell/test/browser/browser_browsingContext-01.js
new file mode 100644
index 0000000000..d1d6f947ef
--- /dev/null
+++ b/docshell/test/browser/browser_browsingContext-01.js
@@ -0,0 +1,205 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+const URL = "about:blank";
+
+async function getBrowsingContextId(browser, id) {
+ return SpecialPowers.spawn(browser, [id], async function(id) {
+ let contextId = content.window.docShell.browsingContext.id;
+
+ let frames = [content.window];
+ while (frames.length) {
+ let frame = frames.pop();
+ let target = frame.document.getElementById(id);
+ if (target) {
+ contextId = target.docShell.browsingContext.id;
+ break;
+ }
+
+ frames = frames.concat(Array.from(frame.frames));
+ }
+
+ return contextId;
+ });
+}
+
+async function addFrame(browser, id, parentId) {
+ return SpecialPowers.spawn(browser, [{ parentId, id }], async function({
+ parentId,
+ id,
+ }) {
+ let parent = null;
+ if (parentId) {
+ let frames = [content.window];
+ while (frames.length) {
+ let frame = frames.pop();
+ let target = frame.document.getElementById(parentId);
+ if (target) {
+ parent = target.contentWindow.document.body;
+ break;
+ }
+ frames = frames.concat(Array.from(frame.frames));
+ }
+ } else {
+ parent = content.document.body;
+ }
+
+ let frame = await new Promise(resolve => {
+ let frame = content.document.createElement("iframe");
+ frame.id = id || "";
+ frame.url = "about:blank";
+ frame.onload = () => resolve(frame);
+ parent.appendChild(frame);
+ });
+
+ return frame.contentWindow.docShell.browsingContext.id;
+ });
+}
+
+async function removeFrame(browser, id) {
+ return SpecialPowers.spawn(browser, [id], async function(id) {
+ let frames = [content.window];
+ while (frames.length) {
+ let frame = frames.pop();
+ let target = frame.document.getElementById(id);
+ if (target) {
+ target.remove();
+ break;
+ }
+
+ frames = frames.concat(Array.from(frame.frames));
+ }
+ });
+}
+
+function getBrowsingContextById(id) {
+ return BrowsingContext.get(id);
+}
+
+add_task(async function() {
+ await BrowserTestUtils.withNewTab({ gBrowser, url: URL }, async function(
+ browser
+ ) {
+ let topId = await getBrowsingContextId(browser, "");
+ let topContext = getBrowsingContextById(topId);
+ isnot(topContext, null);
+ is(topContext.parent, null);
+ is(
+ topId,
+ browser.browsingContext.id,
+ "<browser> has the correct browsingContext"
+ );
+ is(
+ browser.browserId,
+ topContext.browserId,
+ "browsing context should have a correct <browser> id"
+ );
+
+ let id0 = await addFrame(browser, "frame0");
+ let browsingContext0 = getBrowsingContextById(id0);
+ isnot(browsingContext0, null);
+ is(browsingContext0.parent, topContext);
+
+ await removeFrame(browser, "frame0");
+
+ is(topContext.children.indexOf(browsingContext0), -1);
+
+ // TODO(farre): Handle browsingContext removal [see Bug 1486719].
+ todo_isnot(browsingContext0.parent, topContext);
+ });
+});
+
+add_task(async function() {
+ await BrowserTestUtils.withNewTab(
+ {
+ gBrowser,
+ url:
+ getRootDirectory(gTestPath).replace(
+ "chrome://mochitests/content",
+ "http://example.com"
+ ) + "dummy_page.html",
+ },
+ async function(browser) {
+ let path = getRootDirectory(gTestPath).replace(
+ "chrome://mochitests/content",
+ "http://example.com"
+ );
+ await SpecialPowers.spawn(browser, [path], async function(path) {
+ function waitForMessage(command) {
+ let r;
+ let p = new Promise(resolve => {
+ content.window.addEventListener(
+ "message",
+ e => resolve({ result: r, event: e }),
+ { once: true }
+ );
+ });
+ r = command();
+ return p;
+ }
+
+ // Open a new window and wait for the message.
+ let { result: win, event: e1 } = await waitForMessage(_ =>
+ content.window.open(path + "onpageshow_message.html")
+ );
+
+ is(e1.data, "pageshow");
+
+ {
+ // Create, attach and load an iframe into the window's document.
+ let frame = win.document.createElement("iframe");
+ win.document.body.appendChild(frame);
+ frame.src = "dummy_page.html";
+ await ContentTaskUtils.waitForEvent(frame, "load");
+ }
+
+ is(win.frames.length, 1, "Here we should have an iframe");
+
+ // The frame should have expected browsing context and docshell.
+ let frameBC = win.frames[0].docShell.browsingContext;
+ let winDocShell = win.frames[0].docShell;
+
+ // Navigate the window and wait for the message.
+ let { event: e2 } = await waitForMessage(
+ _ => (win.location = path + "onload_message.html")
+ );
+
+ is(e2.data, "load");
+ is(win.frames.length, 0, "Here there shouldn't be an iframe");
+
+ // Return to the previous document. N.B. we expect to trigger
+ // BFCache here, hence we wait for pageshow.
+ let { event: e3 } = await waitForMessage(_ => win.history.back());
+
+ is(e3.data, "pageshow");
+ is(win.frames.length, 1, "And again there should be an iframe");
+
+ is(winDocShell, win.frames[0].docShell, "BF cache cached docshell");
+ is(
+ frameBC,
+ win.frames[0].docShell.browsingContext,
+ "BF cache cached BC"
+ );
+ is(
+ frameBC.id,
+ win.frames[0].docShell.browsingContext.id,
+ "BF cached BC's have same id"
+ );
+ is(
+ win.docShell.browsingContext.children[0],
+ frameBC,
+ "BF cached BC's should still be a child of its parent"
+ );
+ is(
+ win.docShell.browsingContext,
+ frameBC.parent,
+ "BF cached BC's should still be a connected to its parent"
+ );
+
+ win.close();
+ });
+ }
+ );
+});