Bug 1538979 - Part 3: Add testcase to test JSWindowActor's lifecycle; r=nika
authorJohn Dai <jdai@mozilla.com>
Fri, 10 May 2019 15:01:42 +0000
changeset 532227 849fff1c1663f3be35656e771c6e82ec00496fae
parent 532226 0e3d9d0c32602bf7a0847cac48b3622d57a46247
child 532228 9d6ef733639969e2902303aacb3c88ee003e72cf
push id11265
push userffxbld-merge
push dateMon, 13 May 2019 10:53:39 +0000
treeherdermozilla-beta@77e0fe8dbdd3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnika
bugs1538979
milestone68.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 1538979 - Part 3: Add testcase to test JSWindowActor's lifecycle; r=nika Differential Revision: https://phabricator.services.mozilla.com/D30197
dom/ipc/tests/browser_JSWindowActor.js
toolkit/actors/TestChild.jsm
--- a/dom/ipc/tests/browser_JSWindowActor.js
+++ b/dom/ipc/tests/browser_JSWindowActor.js
@@ -401,8 +401,79 @@ declTest("getActor with includeChrome", 
   includeChrome: true,
 
   async test(_browser, win) {
     let parent = win.docShell.browsingContext.currentWindowGlobal;
     let actorParent = parent.getActor("Test");
     ok(actorParent, "JSWindowActorParent should have value.");
   },
 });
+
+declTest("destroy actor by iframe remove", {
+  allFrames: true,
+
+  async test(browser) {
+    await ContentTask.spawn(browser, {}, async function() {
+      // Create and append an iframe into the window's document.
+      let frame = content.document.createElement("iframe");
+      frame.id = "frame";
+      content.document.body.appendChild(frame);
+      await ContentTaskUtils.waitForEvent(frame, "load");
+      is(content.window.frames.length, 1, "There should be an iframe.");
+      let child = frame.contentWindow.window.getWindowGlobalChild();
+      let actorChild = child.getActor("Test");
+      ok(actorChild, "JSWindowActorChild should have value.");
+
+      let willDestroyPromise = new Promise(resolve => {
+        const TOPIC = "test-js-window-actor-willdestroy";
+        Services.obs.addObserver(function obs(subject, topic, data) {
+          ok(data, "willDestroyCallback data should be true.");
+
+          Services.obs.removeObserver(obs, TOPIC);
+          resolve();
+        }, TOPIC);
+      });
+
+      let didDestroyPromise = new Promise(resolve => {
+        const TOPIC = "test-js-window-actor-diddestroy";
+        Services.obs.addObserver(function obs(subject, topic, data) {
+          ok(data, "didDestroyCallback data should be true.");
+
+          Services.obs.removeObserver(obs, TOPIC);
+          resolve();
+        }, TOPIC);
+      });
+
+      info("Remove frame");
+      content.document.getElementById("frame").remove();
+      await Promise.all([willDestroyPromise, didDestroyPromise]);
+
+      Assert.throws(() => child.getActor("Test"),
+        /InvalidStateError/, "Should throw if frame destroy.");
+    });
+  },
+});
+
+declTest("destroy actor by page navigates", {
+  allFrames: true,
+
+  async test(browser) {
+    info("creating an in-process frame");
+    await ContentTask.spawn(browser, URL, async function(url) {
+      let frame = content.document.createElement("iframe");
+      frame.src = url;
+      content.document.body.appendChild(frame);
+    });
+
+    info("navigating page");
+    await ContentTask.spawn(browser, TEST_URL, async function(url) {
+      let frame = content.document.querySelector("iframe");
+      frame.contentWindow.location = url;
+      let child = frame.contentWindow.window.getWindowGlobalChild();
+      let actorChild = child.getActor("Test");
+      ok(actorChild, "JSWindowActorChild should have value.");
+      await ContentTaskUtils.waitForEvent(frame, "load");
+
+      Assert.throws(() => child.getActor("Test"),
+              /InvalidStateError/, "Should throw if frame destroy.");
+    });
+  },
+});
--- a/toolkit/actors/TestChild.jsm
+++ b/toolkit/actors/TestChild.jsm
@@ -1,14 +1,16 @@
 /* vim: set ts=2 sw=2 sts=2 et tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 "use strict";
 
+const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
+
 var EXPORTED_SYMBOLS = ["TestChild"];
 
 class TestChild extends JSWindowActorChild {
   constructor() {
      super();
   }
 
   receiveMessage(aMessage) {
@@ -36,9 +38,19 @@ class TestChild extends JSWindowActorChi
 
   observe(subject, topic, data) {
     this.lastObserved = {subject, topic, data};
   }
 
   show() {
     return "TestChild";
   }
+
+  willDestroy() {
+    Services.obs.notifyObservers(
+      this, "test-js-window-actor-willdestroy", true);
+  }
+
+  didDestroy() {
+    Services.obs.notifyObservers(
+      this, "test-js-window-actor-diddestroy", true);
+  }
 }