summaryrefslogtreecommitdiffstats
path: root/dom/tests/browser/browser_windowProxy_transplant.js
diff options
context:
space:
mode:
Diffstat (limited to 'dom/tests/browser/browser_windowProxy_transplant.js')
-rw-r--r--dom/tests/browser/browser_windowProxy_transplant.js219
1 files changed, 219 insertions, 0 deletions
diff --git a/dom/tests/browser/browser_windowProxy_transplant.js b/dom/tests/browser/browser_windowProxy_transplant.js
new file mode 100644
index 0000000000..6b9e316968
--- /dev/null
+++ b/dom/tests/browser/browser_windowProxy_transplant.js
@@ -0,0 +1,219 @@
+"use strict";
+
+const DIRPATH = getRootDirectory(gTestPath).replace(
+ "chrome://mochitests/content/",
+ ""
+);
+const PATH = DIRPATH + "file_postMessage_parent.html";
+
+const URL1 = `http://mochi.test:8888/${PATH}`;
+const URL2 = `http://example.com/${PATH}`;
+const URL3 = `http://example.org/${PATH}`;
+
+// A bunch of boilerplate which needs to be dealt with.
+add_task(async function () {
+ // Turn on BC preservation and frameloader rebuilding to ensure that the
+ // BrowsingContext is preserved.
+ await SpecialPowers.pushPrefEnv({
+ set: [["fission.preserve_browsing_contexts", true]],
+ });
+
+ // Open a window with fission force-enabled in it.
+ let win = await BrowserTestUtils.openNewBrowserWindow({
+ fission: true,
+ remote: true,
+ });
+ try {
+ // Get the tab & browser to perform the test in.
+ let tab = win.gBrowser.selectedTab;
+ let browser = tab.linkedBrowser;
+
+ // Start loading the original URI, then wait until it is loaded.
+ BrowserTestUtils.startLoadingURIString(browser, URL1);
+ await BrowserTestUtils.browserLoaded(browser, false, URL1);
+
+ info("Chrome script has loaded initial URI.");
+ await SpecialPowers.spawn(
+ browser,
+ [{ URL1, URL2, URL3 }],
+ async ({ URL1, URL2, URL3 }) => {
+ let iframe = content.document.createElement("iframe");
+ content.document.body.appendChild(iframe);
+
+ info("Chrome script created iframe");
+
+ // Here and below, we have to store references to things in the
+ // iframes on the content window, because all chrome references
+ // to content will be turned into dead wrappers when the iframes
+ // are closed.
+ content.win0 = iframe.contentWindow;
+ content.bc0 = iframe.browsingContext;
+
+ ok(
+ !Cu.isDeadWrapper(content.win0),
+ "win0 shouldn't be a dead wrapper before navigation"
+ );
+
+ // Helper for waiting for a load.
+ function waitLoad() {
+ return new Promise(resolve => {
+ iframe.addEventListener(
+ "load",
+ event => {
+ info("Got an iframe load event!");
+ resolve();
+ },
+ { once: true }
+ );
+ });
+ }
+
+ function askLoad(url) {
+ info("Chrome script asking for load of " + url);
+ iframe.contentWindow.postMessage(
+ {
+ action: "navigate",
+ location: url,
+ },
+ "*"
+ );
+ info("Chrome script done calling PostMessage");
+ }
+
+ // Check that BC and WindowProxy are preserved across navigations.
+ iframe.contentWindow.location = URL1;
+ await waitLoad();
+
+ content.win1 = iframe.contentWindow;
+ let chromeWin1 = iframe.contentWindow;
+ let chromeWin1x = Cu.waiveXrays(iframe.contentWindow);
+ content.win1x = Cu.waiveXrays(iframe.contentWindow);
+
+ Assert.notEqual(
+ chromeWin1,
+ chromeWin1x,
+ "waiving xrays creates a new thing?"
+ );
+
+ content.bc1 = iframe.browsingContext;
+
+ is(
+ content.bc0,
+ content.bc1,
+ "same to same-origin BrowsingContext match"
+ );
+ is(content.win0, content.win1, "same to same-origin WindowProxy match");
+
+ ok(
+ !Cu.isDeadWrapper(content.win1),
+ "win1 shouldn't be a dead wrapper before navigation"
+ );
+ ok(
+ !Cu.isDeadWrapper(chromeWin1),
+ "chromeWin1 shouldn't be a dead wrapper before navigation"
+ );
+
+ askLoad(URL2);
+ await waitLoad();
+
+ content.win2 = iframe.contentWindow;
+ content.bc2 = iframe.browsingContext;
+
+ // When chrome accesses a remote window proxy in content, the result
+ // should be a remote outer window proxy in the chrome compartment, not an
+ // Xray wrapper around the content remote window proxy. The former will
+ // throw a security error, because @@toPrimitive can't be called cross
+ // process, while the latter will result in an opaque wrapper, because
+ // XPConnect doesn't know what to do when trying to create an Xray wrapper
+ // around a remote outer window proxy. See bug 1556845.
+ Assert.throws(
+ () => {
+ dump("content.win1 " + content.win1 + "\n");
+ },
+ /SecurityError: Permission denied to access property Symbol.toPrimitive on cross-origin object/,
+ "Should get a remote outer window proxy when accessing old window proxy"
+ );
+ Assert.throws(
+ () => {
+ dump("content.win2 " + content.win2 + "\n");
+ },
+ /SecurityError: Permission denied to access property Symbol.toPrimitive on cross-origin object/,
+ "Should get a remote outer window proxy when accessing new window proxy"
+ );
+
+ // If we fail to transplant existing non-remote outer window proxies, then
+ // after we navigate the iframe existing chrome references to the window will
+ // become dead wrappers. Also check content.win1 for thoroughness, though
+ // we don't nuke content-content references.
+ ok(
+ !Cu.isDeadWrapper(content.win1),
+ "win1 shouldn't be a dead wrapper after navigation"
+ );
+ ok(
+ !Cu.isDeadWrapper(chromeWin1),
+ "chromeWin1 shouldn't be a dead wrapper after navigation"
+ );
+ ok(
+ Cu.isDeadWrapper(chromeWin1x),
+ "chromeWin1x should be a dead wrapper after navigation"
+ );
+ ok(
+ Cu.isDeadWrapper(content.win1x),
+ "content.win1x should be a dead wrapper after navigation"
+ );
+
+ is(
+ content.bc1,
+ content.bc2,
+ "same to cross-origin navigation BrowsingContext match"
+ );
+ is(
+ content.win1,
+ content.win2,
+ "same to cross-origin navigation WindowProxy match"
+ );
+
+ ok(
+ !Cu.isDeadWrapper(content.win1),
+ "win1 shouldn't be a dead wrapper after navigation"
+ );
+
+ askLoad(URL3);
+ await waitLoad();
+
+ content.win3 = iframe.contentWindow;
+ content.bc3 = iframe.browsingContext;
+
+ is(
+ content.bc2,
+ content.bc3,
+ "cross to cross-origin navigation BrowsingContext match"
+ );
+ is(
+ content.win2,
+ content.win3,
+ "cross to cross-origin navigation WindowProxy match"
+ );
+
+ askLoad(URL1);
+ await waitLoad();
+
+ content.win4 = iframe.contentWindow;
+ content.bc4 = iframe.browsingContext;
+
+ is(
+ content.bc3,
+ content.bc4,
+ "cross to same-origin navigation BrowsingContext match"
+ );
+ is(
+ content.win3,
+ content.win4,
+ "cross to same-origin navigation WindowProxy match"
+ );
+ }
+ );
+ } finally {
+ await BrowserTestUtils.closeWindow(win);
+ }
+});