Bug 1592776 - Make test_notification_tag work with Fission. r=dom-workers-and-storage-reviewers,asuth
☠☠ backed out by 7206207af8c4 ☠ ☠
authorSimon Giesecke <sgiesecke@mozilla.com>
Wed, 27 May 2020 07:34:54 +0000
changeset 532323 edaf8a5f8d5364db88956636a24f6623b05b5f0d
parent 532322 aa836c2449d5b3a8342a836fba49231aedeac1e9
child 532324 7ea25549ca316cd087b31668d1958f5640b5e6aa
push id37454
push userccoroiu@mozilla.com
push dateWed, 27 May 2020 16:14:31 +0000
treeherdermozilla-central@a1dd9afbfdf5 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdom-workers-and-storage-reviewers, asuth
bugs1592776
milestone78.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 1592776 - Make test_notification_tag work with Fission. r=dom-workers-and-storage-reviewers,asuth Differential Revision: https://phabricator.services.mozilla.com/D76824
dom/notification/test/mochitest/mochitest.ini
dom/notification/test/mochitest/test_notification_tag.html
--- a/dom/notification/test/mochitest/mochitest.ini
+++ b/dom/notification/test/mochitest/mochitest.ini
@@ -11,9 +11,8 @@ skip-if = toolkit == 'android' && !is_fe
 [test_notification_crossorigin_iframe.html]
 # This test needs to be run on HTTP (not HTTPS).
 [test_notification_insecure_context.html]
 [test_notification_permissions.html]
 scheme = https
 [test_notification_storage.html]
 [test_bug931307.html]
 [test_notification_tag.html]
-fail-if = fission
--- a/dom/notification/test/mochitest/test_notification_tag.html
+++ b/dom/notification/test/mochitest/test_notification_tag.html
@@ -15,126 +15,151 @@ https://bugzilla.mozilla.org/show_bug.cg
 <iframe name="anotherSameDomain"></iframe>
 <iframe name="crossDomain"></iframe>
 <div id="content" style="display: none">
 </div>
 <pre id="test">
 </pre>
 <script type="text/javascript">
   /* eslint-disable mozilla/use-chromeutils-generateqi */
-  const MOCK_CID = SpecialPowers.wrap(SpecialPowers.Components).ID(
-    "{dbe37e64-d9a3-402c-8d8a-0826c619f7ad}"
-  );
-  const ALERTS_SERVICE_CONTRACT_ID = "@mozilla.org/alerts-service;1";
+
+  // The mock is not a general purpose mock, but is specific for this test.
+  // It is always registered in the parent process using LoadChromeScript by
+  // the MockAlertsService below, to allow this to work regardless of whether
+  // the frames from different origins live in the same process or in different
+  // processes (with Fission), since the default content-process alerts service
+  // relays messages to the parent process.
+  function mockServicesChromeScript() {
+    const MOCK_CID = Components.ID("{dbe37e64-d9a3-402c-8d8a-0826c619f7ad}");
+    const ALERTS_SERVICE_CONTRACT_ID = "@mozilla.org/alerts-service;1";
+
+    var notificationsCreated = [];
 
-  var mockAlertsService = {
-    showAlert(alert, alertListener) {
-      notificationsCreated.push(alert.name);
-      if (notificationsCreated.length == 3) {
-        checkNotifications();
-      }
-    },
+    const mockAlertsService = {
+      showAlert(alert, alertListener) {
+        notificationsCreated.push(alert.name);
+        if (notificationsCreated.length == 3) {
+          // notifications created by the test1 origin
+          var test1notifications = [];
+          // notifications created by the test2 origin
+          var test2notifications = [];
+          for (var i = 0; i < notificationsCreated.length; i++) {
+            var notificationName = notificationsCreated[i];
+            if (notificationName.includes("test1")) {
+              test1notifications.push(notificationsCreated[i]);
+            } else if (notificationName.includes("test2")) {
+              test2notifications.push(notificationsCreated[i]);
+            }
+          }
+
+          is(
+            test1notifications.length,
+            2,
+            "2 notifications should be created by test1.example.org:80 origin."
+          );
+          is(
+            test1notifications[0],
+            test1notifications[1],
+            "notification names should be identical."
+          );
+          is(
+            test2notifications.length,
+            1,
+            "1 notification should be created by test2.example.org:80 origin."
+          );
+
+          // Register original alerts service.
+          registrar.unregisterFactory(MOCK_CID, this);
+
+          sendAsyncMessage("mock-alert-service:unregistered");
+        }
+      },
 
-    showAlertNotification(
-      imageUrl,
-      title,
-      text,
-      textClickable,
-      cookie,
-      alertListener,
-      name,
-      dir,
-      lang,
-      data
-    ) {
-      this.showAlert({ name });
-    },
+      showAlertNotification(
+        imageUrl,
+        title,
+        text,
+        textClickable,
+        cookie,
+        alertListener,
+        name,
+        dir,
+        lang,
+        data
+      ) {
+        this.showAlert({ name });
+      },
+
+      QueryInterface(aIID) {
+        if (aIID.equals(Ci.nsISupports) || aIID.equals(Ci.nsIAlertsService)) {
+          return this;
+        }
+        throw Components.Exception("", Cr.NS_ERROR_NO_INTERFACE);
+      },
 
-    QueryInterface(aIID) {
-      if (
-        SpecialPowers.wrap(aIID).equals(SpecialPowers.Ci.nsISupports) ||
-        SpecialPowers.wrap(aIID).equals(SpecialPowers.Ci.nsIAlertsService)
-      ) {
-        return this;
+      createInstance(aOuter, aIID) {
+        if (aOuter != null) {
+          throw Components.Exception("", Cr.NS_ERROR_NO_AGGREGATION);
+        }
+        return this.QueryInterface(aIID);
+      },
+    };
+
+    const registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
+
+    registrar.registerFactory(
+      MOCK_CID,
+      "alerts service",
+      ALERTS_SERVICE_CONTRACT_ID,
+      mockAlertsService
+    );
+
+    const { sendAsyncMessage } = this;
+
+    sendAsyncMessage("mock-alert-service:registered");
+  }
+
+  const MockAlertsService = {
+    async register() {
+      if (this._chromeScript) {
+        throw new Error("MockAlertsService already registered");
       }
-      throw SpecialPowers.Components.results.NS_ERROR_NO_INTERFACE;
+      this._chromeScript = SpecialPowers.loadChromeScript(
+        mockServicesChromeScript
+      );
+      await this._chromeScript.promiseOneMessage("mock-alert-service:registered");
     },
-
-    createInstance(aOuter, aIID) {
-      if (aOuter != null) {
-        throw SpecialPowers.Components.results.NS_ERROR_NO_AGGREGATION;
-      }
-      return this.QueryInterface(aIID);
+    async unregistered() {
+      await this._chromeScript.promiseOneMessage(
+        "mock-alert-service:unregistered"
+      );
     },
   };
-  mockAlertsService = SpecialPowers.wrapCallbackObject(mockAlertsService);
-
-  var notificationsCreated = [];
-  function checkNotifications() {
-    // notifications created by the test1 origin
-    var test1notifications = [];
-    // notifications created by the test2 origin
-    var test2notifications = [];
-    for (var i = 0; i < notificationsCreated.length; i++) {
-      var notificationName = notificationsCreated[i];
-      if (notificationName.includes("test1")) {
-        test1notifications.push(notificationsCreated[i]);
-      } else if (notificationName.includes("test2")) {
-        test2notifications.push(notificationsCreated[i]);
-      }
-    }
-
-    is(
-      test1notifications.length,
-      2,
-      "2 notifications should be created by test1.example.org:80 origin."
-    );
-    is(
-      test1notifications[0],
-      test1notifications[1],
-      "notification names should be identical."
-    );
-    is(
-      test2notifications.length,
-      1,
-      "1 notification should be created by test2.example.org:80 origin."
-    );
-
-    // Register original alerts service.
-    SpecialPowers.wrap(SpecialPowers.Components)
-      .manager.QueryInterface(SpecialPowers.Ci.nsIComponentRegistrar)
-      .unregisterFactory(MOCK_CID, mockAlertsService);
-
-    SimpleTest.finish();
-  }
 
   if (window.Notification) {
     SimpleTest.waitForExplicitFinish();
 
-    function showNotifications() {
-      SpecialPowers.wrap(SpecialPowers.Components)
-        .manager.QueryInterface(SpecialPowers.Ci.nsIComponentRegistrar)
-        .registerFactory(
-          MOCK_CID,
-          "alerts service",
-          ALERTS_SERVICE_CONTRACT_ID,
-          mockAlertsService
-        );
+    async function showNotifications() {
+      await MockAlertsService.register();
 
       // Load two frames with the same origin that create notification with the same tag.
       // Both pages should generate notifications with the same name, and thus the second
       // notification should replace the first.
       frames.sameDomain.location.href =
         "http://test1.example.org:80/tests/dom/notification/test/mochitest/create_notification.html";
       frames.anotherSameDomain.location.href =
         "http://test1.example.org:80/tests/dom/notification/test/mochitest/create_notification.html";
       // Load a frame with a different origin that creates a notification with the same tag.
       // The notification name should be different and thus no notifications should be replaced.
       frames.crossDomain.location.href =
         "http://test2.example.org:80/tests/dom/notification/test/mochitest/create_notification.html";
+
+      await MockAlertsService.unregistered();
+
+      SimpleTest.finish();
     }
 
     SpecialPowers.pushPrefEnv(
       {
         set: [
           ["notification.prompt.testing", true],
           ["notification.prompt.testing.allow", true],
         ],