Bug 1572898: Make BrowsingContext tests almost Fission compatible. r=mccr8
authorKris Maglione <maglione.k@gmail.com>
Fri, 09 Aug 2019 18:26:10 -0700
changeset 488073 4546e42005a04b3cb98bbf315bd8a986f772f543
parent 488072 4477d849b72a0cf15159b1f99a8530a250575365
child 488074 5f0660a4dc617fdeae2221bde5b77f2655e109a6
push id36435
push usercbrindusan@mozilla.com
push dateThu, 15 Aug 2019 09:46:49 +0000
treeherdermozilla-central@0db07ff50ab5 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmccr8
bugs1572898
milestone70.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 1572898: Make BrowsingContext tests almost Fission compatible. r=mccr8 The tests currently rely on being able to create new frames in and new windows from cross-origin iframes, which clearly won't work under Fission. This patch changes that logic, but leaves the tests skipped since they also rely on cross-origin window.postMessage, which doesn't work yet. Differential Revision: https://phabricator.services.mozilla.com/D41471
docshell/test/browser/browser.ini
docshell/test/browser/browser_browsingContext-02.js
docshell/test/browser/browser_browsingContext-03.js
testing/specialpowers/content/SpecialPowersChild.jsm
--- a/docshell/test/browser/browser.ini
+++ b/docshell/test/browser/browser.ini
@@ -129,19 +129,19 @@ skip-if = true # Bug 1220415
 [browser_timelineMarkers-03.js]
 [browser_timelineMarkers-04.js]
 [browser_timelineMarkers-05.js]
 [browser_ua_emulation.js]
 [browser_history_triggeringprincipal_viewsource.js]
 [browser_click_link_within_view_source.js]
 [browser_browsingContext-01.js]
 [browser_browsingContext-02.js]
-fail-if = fission
+skip-if = fission # Cross-process postMessage
 [browser_browsingContext-03.js]
-fail-if = fission
+skip-if = fission # Cross-process postMessage
 [browser_browsingContext-embedder.js]
 [browser_csp_uir.js]
 support-files =
   file_csp_uir.html
   file_csp_uir_dummy.html
 [browser_cross_process_csp_inheritance.js]
 fail-if = fission
 skip-if = !e10s # e10s specific test.
--- a/docshell/test/browser/browser_browsingContext-02.js
+++ b/docshell/test/browser/browser_browsingContext-02.js
@@ -27,54 +27,66 @@ add_task(async function() {
         URL + "#seventh",
         true,
         true
       );
       await ContentTask.spawn(
         browser,
         { base1: BASE1, base2: BASE2 },
         async function({ base1, base2 }) {
-          let top = content.window;
+          let top = content;
           top.name = "top";
           top.location.href += "#top";
 
           let contexts = {
             top: top.location.href,
             first: base1 + "dummy_page.html#first",
             third: base2 + "dummy_page.html#third",
             second: base1 + "dummy_page.html#second",
             fourth: base2 + "dummy_page.html#fourth",
             fifth: base1 + "dummy_page.html#fifth",
             sixth: base1 + "onload_message.html#sixth",
             seventh: base1 + "onload_message.html#seventh",
           };
 
           function addFrame(target, name) {
-            let doc = (target.contentWindow || target).document;
-            let frame = doc.createElement("iframe");
-            let p = new Promise(
-              resolve => (frame.onload = () => resolve(frame))
+            return content.SpecialPowers.spawn(
+              target,
+              [name, contexts[name]],
+              async (name, context) => {
+                let doc = this.content.document;
+
+                let frame = doc.createElement("iframe");
+                doc.body.appendChild(frame);
+                frame.name = name;
+                frame.src = context;
+                await new Promise(resolve => {
+                  frame.addEventListener("load", resolve, { once: true });
+                });
+                return frame.browsingContext;
+              }
             );
-            doc.body.appendChild(frame);
-            frame.name = name;
-            frame.src = contexts[name];
-            return p;
           }
 
           function addWindow(target, name, { options, resolve }) {
-            var win = target.contentWindow.open(contexts[name], name, options);
+            return content.SpecialPowers.spawn(
+              target,
+              [name, contexts[name], options, resolve],
+              (name, context, options, resolve) => {
+                let win = this.content.open(context, name, options);
+                let bc = win && win.docShell.browsingContext;
 
-            if (resolve) {
-              return new Promise(resolve =>
-                target.contentWindow.addEventListener("message", () =>
-                  resolve(win)
-                )
-              );
-            }
-            return Promise.resolve({ name });
+                if (resolve) {
+                  return new Promise(resolve =>
+                    this.content.addEventListener("message", () => resolve(bc))
+                  );
+                }
+                return Promise.resolve({ name });
+              }
+            );
           }
 
           // We're going to create a tree that looks like the
           // following.
           //
           //           top          sixth    seventh
           //          /   \
           //         /     \        /
@@ -88,35 +100,31 @@ add_task(async function() {
           //
           // The idea is to have one top level non-auxiliary browsing
           // context, five nested, one top level auxiliary with an
           // opener, and one top level without an opener. Given that
           // set of related and one unrelated browsing contexts we
           // wish to confirm that targeting is able to find
           // appropriate browsing contexts.
 
-          function bc(frame) {
-            return (frame.contentWindow || frame).docShell.browsingContext;
-          }
-
           function reachable(start, targets) {
             for (let target of targets) {
               is(
-                bc(start).findWithName(target.name, bc(start)),
-                bc(target),
-                [bc(start).name, "can reach", target.name].join(" ")
+                start.findWithName(target.name, start),
+                target,
+                [start.name, "can reach", target.name].join(" ")
               );
             }
           }
 
           function unreachable(start, target) {
             is(
-              bc(start).findWithName(target.name, bc(start)),
+              start.findWithName(target.name, start),
               null,
-              [bc(start).name, "can't reach", target.name].join(" ")
+              [start.name, "can't reach", target.name].join(" ")
             );
           }
 
           let first = await addFrame(top, "first");
           info("first");
           let second = await addFrame(top, "second");
           info("second");
           let third = await addFrame(first, "third");
@@ -127,17 +135,25 @@ add_task(async function() {
           info("fifth");
           let sixth = await addWindow(fourth, "sixth", { resolve: true });
           info("sixth");
           let seventh = await addWindow(fourth, "seventh", {
             options: ["noopener"],
           });
           info("seventh");
 
-          let frames = [top, first, second, third, fourth, fifth, sixth];
+          let frames = [
+            BrowsingContext.getFromWindow(top),
+            first,
+            second,
+            third,
+            fourth,
+            fifth,
+            sixth,
+          ];
           for (let start of frames) {
             reachable(start, frames);
             unreachable(start, seventh);
           }
         }
       );
 
       for (let tab of await Promise.all([sixth, seventh])) {
--- a/docshell/test/browser/browser_browsingContext-03.js
+++ b/docshell/test/browser/browser_browsingContext-03.js
@@ -21,49 +21,61 @@ add_task(async function() {
         URL + "#sixth",
         true,
         true
       );
       await ContentTask.spawn(
         browser,
         { base1: BASE1, base2: BASE2 },
         async function({ base1, base2 }) {
-          let top = content.window;
+          let top = content;
           top.name = "top";
           top.location.href += "#top";
 
           let contexts = {
             top: top.location.href,
             first: base1 + "dummy_page.html#first",
             third: base2 + "dummy_page.html#third",
             second: base1 + "dummy_page.html#second",
             fourth: base2 + "dummy_page.html#fourth",
             fifth: base1 + "dummy_page.html#fifth",
             sixth: base1 + "onload_message.html#sixth",
           };
 
           function addFrame(target, name) {
-            let doc = (target.contentWindow || target).document;
-            let frame = doc.createElement("iframe");
-            let p = new Promise(
-              resolve => (frame.onload = () => resolve(frame))
+            return content.SpecialPowers.spawn(
+              target,
+              [name, contexts[name]],
+              async (name, context) => {
+                let doc = this.content.document;
+
+                let frame = doc.createElement("iframe");
+                doc.body.appendChild(frame);
+                frame.name = name;
+                frame.src = context;
+                await new Promise(resolve => {
+                  frame.addEventListener("load", resolve, { once: true });
+                });
+                return frame.browsingContext;
+              }
             );
-            doc.body.appendChild(frame);
-            frame.name = name;
-            frame.src = contexts[name];
-            return p;
           }
 
           function addWindow(target, name) {
-            var win = target.contentWindow.open(contexts[name], name);
+            return content.SpecialPowers.spawn(
+              target,
+              [name, contexts[name]],
+              (name, context) => {
+                let win = this.content.open(context, name);
+                let bc = win && win.docShell.browsingContext;
 
-            return new Promise(resolve =>
-              target.contentWindow.addEventListener("message", () =>
-                resolve(win)
-              )
+                return new Promise(resolve =>
+                  this.content.addEventListener("message", () => resolve(bc))
+                );
+              }
             );
           }
 
           // Generate all lists of length length with every combination of
           // values in input
           function* generate(input, length) {
             let list = new Array(length);
 
@@ -98,29 +110,32 @@ add_task(async function() {
           // context, five nested, one top level auxiliary with an
           // opener. Given that set of related browsing contexts we
           // wish to confirm that targeting is semantically equivalent
           // with how nsIDocShellTreeItem.findItemWithName works. The
           // trick to ensure that is to give all frames the same name!
           // and ensure that the find algorithms return the same nodes
           // in the same order.
 
-          function bc(frame) {
-            return (frame.contentWindow || frame).docShell.browsingContext;
-          }
-
           let first = await addFrame(top, "first");
           let second = await addFrame(top, "second");
           let third = await addFrame(first, "third");
           let fourth = await addFrame(first, "fourth");
           let fifth = await addFrame(fourth, "fifth");
           let sixth = await addWindow(fourth, "sixth");
 
-          let frames = [top, first, second, third, fourth, fifth, sixth];
-          let browsingContexts = frames.map(bc);
+          let browsingContexts = [
+            BrowsingContext.getFromWindow(top),
+            first,
+            second,
+            third,
+            fourth,
+            fifth,
+            sixth,
+          ];
           let docShells = browsingContexts.map(context => context.docShell);
 
           ok(
             top.docShell instanceof Ci.nsIDocShellTreeItem,
             "When we remove nsIDocShellTreeItem this test should be removed"
           );
 
           // For every browsing context we generate all possible
--- a/testing/specialpowers/content/SpecialPowersChild.jsm
+++ b/testing/specialpowers/content/SpecialPowersChild.jsm
@@ -50,16 +50,17 @@ class SpecialPowersChild extends Special
   }
 
   attachToWindow() {
     let window = this.contentWindow;
     if (!window.wrappedJSObject.SpecialPowers) {
       this._windowID = window.windowUtils.currentInnerWindowID;
       this.DOMWindowUtils = bindDOMWindowUtils(window);
 
+      window.SpecialPowers = this;
       window.wrappedJSObject.SpecialPowers = this;
       if (this.IsInNestedFrame) {
         this.addPermission("allowXULXBL", true, window.document);
       }
     }
   }
 
   get window() {