Bug 1555488 - Part 2: Add initial tests for WindowProxy cache clearing, r=mccr8
authorNika Layzell <nika@thelayzells.com>
Thu, 06 Jun 2019 14:57:25 +0000
changeset 477646 269c926a8465e4c07f3cf0024ea8ee8763ac454f
parent 477645 5a2114b7f34004218d948bfe62b95b1e17e2f23c
child 477647 97f9fb2506bd605a346721d090c20381b7ac47f5
push id36119
push userncsoregi@mozilla.com
push dateThu, 06 Jun 2019 21:52:09 +0000
treeherdermozilla-central@6a81efd823db [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmccr8
bugs1555488
milestone69.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1555488 - Part 2: Add initial tests for WindowProxy cache clearing, r=mccr8 Differential Revision: https://phabricator.services.mozilla.com/D33545
dom/tests/browser/browser.ini
dom/tests/browser/browser_windowProxy_transplant.js
dom/tests/browser/file_postMessage_parent.html
--- a/dom/tests/browser/browser.ini
+++ b/dom/tests/browser/browser.ini
@@ -88,9 +88,12 @@ support-files =
 [browser_noopener.js]
 skip-if = (verify && debug && (os == 'linux'))
 support-files =
   test_noopener_source.html
   test_noopener_target.html
 [browser_noopener_null_uri.js]
 [browser_wakelock.js]
 [browser_keypressTelemetry.js]
-skip-if = webrender
\ No newline at end of file
+skip-if = webrender
+[browser_windowProxy_transplant.js]
+support-files =
+  file_postMessage_parent.html
new file mode 100644
--- /dev/null
+++ b/dom/tests/browser/browser_windowProxy_transplant.js
@@ -0,0 +1,117 @@
+"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],
+                                         ["fission.rebuild_frameloaders_on_remoteness_change", 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.loadURI(browser, URL1);
+    await BrowserTestUtils.browserLoaded(browser, false, URL1);
+
+    info("Browser has loaded initial URI.");
+    await ContentTask.spawn(browser, {URL1, URL2, URL3}, async ({URL1, URL2, URL3}) => {
+      let iframe = content.document.createElement("iframe");
+      content.document.body.appendChild(iframe);
+
+      info("iframe created");
+
+      // 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;
+      content.bc1 = iframe.browsingContext;
+
+      is(content.bc0, content.bc1, "same to same-origin BrowsingContext match");
+      ok(content.win0 == content.win1, "same to same-origin WindowProxy match");
+
+      ok(!Cu.isDeadWrapper(content.win1), "win1 shouldn't be a dead wrapper before navigation");
+
+      askLoad(URL2);
+      await waitLoad();
+
+      content.win2 = iframe.contentWindow;
+      content.bc2 = iframe.browsingContext;
+
+      is(content.bc1, content.bc2, "same to cross-origin navigation BrowsingContext match");
+      todo(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");
+
+      // This load still doesn't work for some reason, so we skip it for now.
+      /*
+      askLoad(URL3);
+      await waitLoad();
+
+      content.win3 = iframe.contentWindow;
+      content.bc3 = iframe.browsingContext;
+
+      is(content.bc2, content.bc3, "cross to cross-origin navigation BrowsingContext match");
+      ok(content.win2 == content.win3, "cross to cross-origin navigation WindowProxy match");
+      */
+
+      // It would also be useful and important to handle navigating back into an
+      // in-process URL, but that actually doesn't work yet... so........
+      /*
+      askLoad(URL1);
+      await waitLoad();
+      let win4 = iframe.contentWindow;
+      let bc4 = iframe.browsingContext;
+
+      is(bc3, bc4, "cross to same-origin navigation BrowsingContext match");
+      try {
+        is(win3, win4, "cross to same-origin navigation WindowProxy match");
+      } catch(e) {
+        ok(false, "cross to same-origin navigation WindowProxy exception");
+      }
+      */
+    });
+  } finally {
+    await BrowserTestUtils.closeWindow(win);
+  }
+});
new file mode 100644
--- /dev/null
+++ b/dom/tests/browser/file_postMessage_parent.html
@@ -0,0 +1,31 @@
+<!doctype html>
+<script>
+  dump("Content running top level script " + window.location.href + "\n");
+
+  // Unfortunately, we don't currently fire the onload event on a remote iframe,
+  // so we can't listen for the load event directly on the iframe. Instead, we
+  // postMessage from the iframe when the load event would be fired.
+  window.addEventListener("load", function onload() {
+    dump("Content got load of " + window.location.href + "\n");
+    if (window.parent) {
+      window.parent.postMessage({
+        event: "load",
+        location: window.location.href,
+      }, "*");
+    }
+
+    let h1 = document.createElement("h1");
+    h1.textContent = window.location.href;
+    document.body.appendChild(h1);
+  }, { once: true });
+
+  // In addition, we listen to the message event to trigger navigations of
+  // ourself when requested, as we don't fully support our embedder triggering
+  // us being navigated yet for Totally Not Buggy Reasons.
+  window.addEventListener("message", function onmessage(event) {
+    dump("Content got event " + window.location.href + " " + JSON.stringify(event.data) + "\n");
+    if (event.data.action === "navigate") {
+      window.location = event.data.location;
+    }
+  });
+</script>