Bug 1538979 - Part 3: Add testcase to test JSWindowActor's lifecycle; r=nika
☠☠ backed out by 012ce6437a4c ☠ ☠
authorJohn Dai <jdai@mozilla.com>
Fri, 10 May 2019 09:19:37 +0000
changeset 532183 a098226e42117f59f17112ed7be9e39710e18681
parent 532182 8e065761738c199fc06388dcfc22df7e92827152
child 532184 daa2837789242ad8e01798e97fc986509a2e680e
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);
+  }
 }