Bug 1592776 - Make test_notification_tag work with Fission. r=dom-workers-and-storage-reviewers,asuth
☠☠ backed out by 4f7f6d6bc618 ☠ ☠
authorSimon Giesecke <sgiesecke@mozilla.com>
Fri, 29 May 2020 09:02:01 +0000
changeset 597598 052839fb9b56060e603e4fada1c8f7e56df4ae0f
parent 597597 e0a47494eaeafc78099c58c94cdc01546c9f47a5
child 597599 e650aaef268c09419ada9611bec4b985f5b21841
push id13310
push userffxbld-merge
push dateMon, 29 Jun 2020 14:50:06 +0000
treeherdermozilla-beta@15a59a0afa5c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdom-workers-and-storage-reviewers, asuth
bugs1592776
milestone79.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],
         ],