Bug 1264842 - Make the XUL alerts tests work in e10s. r=jaws draft
authorKit Cambridge <kcambridge@mozilla.com>
Wed, 27 Apr 2016 11:58:23 -0700
changeset 362854 4c84123ec9db03e0266aeca5c50845ddac28fb7f
parent 358327 77cead2cd20300623eea2416bc9bce4d5021df09
child 519892 a36f46b6ee91d8d17c827e2eb46e44404d68e34c
push id17050
push userkcambridge@mozilla.com
push dateTue, 03 May 2016 11:36:07 +0000
reviewersjaws
bugs1264842
milestone49.0a1
Bug 1264842 - Make the XUL alerts tests work in e10s. r=jaws MozReview-Commit-ID: 7ctqlv1bWyq
toolkit/components/alerts/test/mochitest.ini
toolkit/components/alerts/test/test_alerts_noobserve.html
toolkit/components/alerts/test/test_multiple_alerts.html
toolkit/components/alerts/test/test_principal.html
--- a/toolkit/components/alerts/test/mochitest.ini
+++ b/toolkit/components/alerts/test/mochitest.ini
@@ -3,9 +3,9 @@ skip-if = buildapp == 'b2g' || buildapp 
 
 # Synchronous tests like test_alerts.html must come before
 # asynchronous tests like test_alerts_noobserve.html!
 [test_alerts.html]
 skip-if = toolkit == 'android'
 [test_alerts_noobserve.html]
 [test_multiple_alerts.html]
 [test_principal.html]
-skip-if = toolkit == 'android' || (e10s && os == 'win') # Win: Bug 1264842
+skip-if = toolkit == 'android'
--- a/toolkit/components/alerts/test/test_alerts_noobserve.html
+++ b/toolkit/components/alerts/test/test_alerts_noobserve.html
@@ -17,31 +17,45 @@
 <br>If there has been no crash when the notification (later) disappears, assume all is good.
 
 <pre id="test">
 <script class="testbody" type="text/javascript">
 
 const Cc = SpecialPowers.Cc;
 const Ci = SpecialPowers.Ci;
 
-const wm = Cc["@mozilla.org/appshell/window-mediator;1"]
-             .getService(Ci.nsIWindowMediator);
+const chromeScript = SpecialPowers.loadChromeScript(_ => {
+  const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
+
+  Cu.import("resource://gre/modules/Services.jsm");
+  Cu.import("resource://gre/modules/Timer.jsm");
+
+  function anyXULAlertsVisible() {
+    var windows = Services.wm.getEnumerator("alert:alert");
+    return windows.hasMoreElements();
+  }
 
-function anyXULAlertsVisible() {
-  var windows = wm.getEnumerator('alert:alert');
-  return windows.hasMoreElements();
-}
+  addMessageListener("anyXULAlertsVisible", anyXULAlertsVisible);
+
+  addMessageListener("waitForAlerts", function waitForAlerts() {
+    if (anyXULAlertsVisible()) {
+      setTimeout(waitForAlerts, 1000);
+    } else {
+      sendAsyncMessage("waitedForAlerts");
+    }
+  });
+});
 
 function waitForAlertsThenFinish() {
-  if (anyXULAlertsVisible()) {
-    setTimeout(waitForAlertsThenFinish, 1000);
-  } else {
+  chromeScript.addMessageListener("waitedForAlerts", function waitedForAlerts() {
+    chromeScript.removeMessageListener("waitedForAlerts", waitedForAlerts);
     ok(true, "Alert disappeared.");
     SimpleTest.finish();
-  }
+  });
+  chromeScript.sendAsyncMessage("waitForAlerts");
 }
 
 function runTest() {
   if (!("@mozilla.org/alerts-service;1" in Cc)) {
     todo(false, "Alerts service does not exist in this application");
   } else {
     ok(true, "Alerts service exists in this application");
 
@@ -63,15 +77,20 @@ function runTest() {
         todo(false, "showAlertNotification() failed.", ex);
       }
     }
   }
 }
 
 SimpleTest.waitForExplicitFinish();
 SimpleTest.requestFlakyTimeout("untriaged");
-ok(!anyXULAlertsVisible(), "Alerts should not be present at the start of the test.");
+
+// sendSyncMessage returns an array of arrays: the outer array is from the
+// message manager, and the inner array is from the chrome script's listeners.
+// See the comment in test_SpecialPowersLoadChromeScript.html.
+var [[alertsVisible]] = chromeScript.sendSyncMessage("anyXULAlertsVisible");
+ok(!alertsVisible, "Alerts should not be present at the start of the test.");
 runTest();
 setTimeout(waitForAlertsThenFinish, 1000);
 </script>
 </pre>
 </body>
 </html>
--- a/toolkit/components/alerts/test/test_multiple_alerts.html
+++ b/toolkit/components/alerts/test/test_multiple_alerts.html
@@ -1,129 +1,105 @@
 <!DOCTYPE HTML>
 <html>
 <head>
   <title>Test for multiple alerts</title>
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> 
+  <script type="text/javascript" src="/tests/SimpleTest/SpawnTask.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
 </head>
 <body>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 
 const Cc = SpecialPowers.Cc;
 const Ci = SpecialPowers.Ci;
 
-const ww = Cc["@mozilla.org/embedcomp/window-watcher;1"]
-             .getService(Ci.nsIWindowWatcher);
+const chromeScript = SpecialPowers.loadChromeScript(_ => {
+  const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
+
+  Cu.import("resource://gre/modules/Services.jsm");
+  Cu.import("resource://gre/modules/Timer.jsm");
+
+  const alertService = Cc["@mozilla.org/alerts-service;1"]
+                         .getService(Ci.nsIAlertsService);
+
+  addMessageListener("waitForPosition", function() {
+    var timer = setTimeout(function() {
+      Services.ww.unregisterNotification(windowObserver);
+      sendAsyncMessage("waitedForPosition", null);
+    }, 2000);
+
+    var windowObserver = function(aSubject, aTopic, aData) {
+      if (aTopic != "domwindowopened") {
+        return;
+      }
+
+      // Alerts are implemented using XUL.
+      clearTimeout(timer);
+
+      Services.ww.unregisterNotification(windowObserver);
 
-function showSimpleAlert(alertService) {
-  try {
+      var win = aSubject.QueryInterface(Ci.nsIDOMWindow);
+      win.addEventListener("pageshow", function onPageShow() {
+        win.removeEventListener("pageshow", onPageShow, false);
+
+        var x = win.screenX;
+        var y = win.screenY;
+
+        win.addEventListener("pagehide", function onPageHide() {
+          win.removeEventListener("pagehide", onPageHide, false);
+          sendAsyncMessage("waitedForPosition", { x, y });
+        }, false);
+
+        alertService.closeAlert();
+      }, false);
+    };
+
+    Services.ww.registerNotification(windowObserver);
+  });
+});
+
+function promiseAlertPosition(alertService) {
+  return new Promise(resolve => {
+    chromeScript.addMessageListener("waitedForPosition", function waitedForPosition(result) {
+      chromeScript.removeMessageListener("waitedForPosition", waitedForPosition);
+      resolve(result);
+    });
+    chromeScript.sendAsyncMessage("waitForPosition");
+
     alertService.showAlertNotification(null, "title", "body");
     ok(true, "Alert shown.");
-  } catch (ex) {
-    ok(false, "Failed to show alert.", ex);
-    SimpleTest.finish();
-  }
+  });
 }
 
-var firstAlertXPosition = 0;
-var firstAlertYPosition = 0;
-
-function showFirstAlert(alertService) {
-  // Set a timeout to finish the test in case we are on a platform
-  // that doesn't use XUL alert windows. This timeout is cleared
-  // when a XUL alert window does get created.
-  var timer = setTimeout(function() {
-    ok(true, "Platform does not use XUL alerts.");
-    ww.unregisterNotification(windowObserver);
-    SimpleTest.finish();
-  }, 2000);
-
-  var windowObserver = function(aSubject, aTopic, aData) {
-    if (aTopic != "domwindowopened") {
-      return;
-    }
-
-    // Alerts are implemented using XUL, clear the timeout
-    // that finishes the test.
-    clearTimeout(timer);
-
-    ww.unregisterNotification(windowObserver);
-
-    var win = SpecialPowers.wrap(aSubject);
-    win.addEventListener("pageshow", function() {
-      win.removeEventListener("pageshow", arguments.callee, false);
-      firstAlertXPosition = win.screenX;
-      firstAlertYPosition = win.screenY;
-
-      // Wait for alert window to close then open a second alert.
-      win.addEventListener("pagehide", function() {
-        win.removeEventListener("pagehide", arguments.callee, false);
-        // Wait for alert to close before creating a new one.
-        showSecondAlert(alertService);
-      }, false);
-
-      alertService.closeAlert();
-    }, false);
-  };
-
-  ww.registerNotification(windowObserver);
-  showSimpleAlert(alertService);
-}
-
-function showSecondAlert(alertService) {
-  var windowObserver = function(aSubject, aTopic, aData) {
-    if (aTopic != "domwindowopened") {
-      return;
-    }
-
-    ww.unregisterNotification(windowObserver);
-
-    var win = SpecialPowers.wrap(aSubject);
-    win.addEventListener("pageshow", function() {
-      win.removeEventListener("pageshow", arguments.callee, false);
-      is(win.screenX, firstAlertXPosition, "Second alert should be opened in the same position.");
-      is(win.screenY, firstAlertYPosition, "Second alert should be opened in the same position.");
-
-      // Wait for alert window to close then finish the test.
-      win.addEventListener("pagehide", function() {
-        win.removeEventListener("pagehide", arguments.callee, false);
-        // Wait for alert to close before finishing the test.
-        SimpleTest.finish();
-      }, false);
-
-      alertService.closeAlert();
-    }, false);
-  };
-
-  ww.registerNotification(windowObserver);
-  showSimpleAlert(alertService);
-}
-
-function runTest() {
+add_task(function* test_multiple_alerts() {
   if (!("@mozilla.org/alerts-service;1" in Cc)) {
     todo(false, "Alerts service does not exist in this application.");
     return;
   }
 
   ok(true, "Alerts service exists in this application.");
 
   var alertService;
   try {
     alertService = Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService);
     ok(true, "Alerts service is available.");
   } catch (ex) {
     todo(false, "Alerts service is not available.");
     return;
   }
 
-  SimpleTest.waitForExplicitFinish();
-  SimpleTest.requestFlakyTimeout("untriaged");
-  showFirstAlert(alertService);
-}
+  var firstAlertPosition = yield promiseAlertPosition(alertService);
+  if (!firstAlertPosition) {
+    ok(true, "Platform does not use XUL alerts.");
+    return;
+  }
 
-runTest();
+  var secondAlertPosition = yield promiseAlertPosition(alertService);
+  is(secondAlertPosition.x, firstAlertPosition.x, "Second alert should be opened in the same position.");
+  is(secondAlertPosition.y, firstAlertPosition.y, "Second alert should be opened in the same position.");
+});
 
 </script>
 </pre>
 </body>
 </html>
--- a/toolkit/components/alerts/test/test_principal.html
+++ b/toolkit/components/alerts/test/test_principal.html
@@ -15,27 +15,45 @@
 
 const Cc = SpecialPowers.Cc;
 const Ci = SpecialPowers.Ci;
 const Services = SpecialPowers.Services;
 
 const notifier = Cc["@mozilla.org/alerts-service;1"]
                    .getService(Ci.nsIAlertsService);
 
+const chromeScript = SpecialPowers.loadChromeScript(_ => {
+  const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
+
+  Cu.import("resource://gre/modules/Services.jsm");
+
+  addMessageListener("anyXULAlertsVisible", function() {
+    var windows = Services.wm.getEnumerator("alert:alert");
+    return windows.hasMoreElements();
+  });
+
+  addMessageListener("getAlertSource", function() {
+    var alertWindows = Services.wm.getEnumerator("alert:alert");
+    if (!alertWindows) {
+      return null;
+    }
+    var alertWindow = alertWindows.getNext();
+    return alertWindow.document.getElementById("alertSourceLabel").getAttribute("value");
+  });
+});
+
 function notify(alertName, principal) {
   return new Promise((resolve, reject) => {
     var source;
     function observe(subject, topic, data) {
       if (topic == "alertclickcallback") {
         reject(new Error("Alerts should not be clicked during test"));
       } else if (topic == "alertshow") {
-        var alertWindows = Services.wm.getEnumerator("alert:alert");
-        ok(alertWindows.hasMoreElements(), "Should show alert");
-        var alertWindow = alertWindows.getNext();
-        source = alertWindow.document.getElementById("alertSourceLabel").getAttribute("value");
+        source = chromeScript.sendSyncMessage("getAlertSource")[0][0];
+        notifier.closeAlert(alertName);
       } else {
         is(topic, "alertfinished", "Should hide alert");
         resolve(source);
       }
     }
     notifier.showAlertNotification(null, "Notification test",
                                    "Surprise! I'm here to test notifications!",
                                    false, alertName, observe, alertName,
@@ -52,22 +70,16 @@ function* testNoPrincipal() {
 }
 
 function* testSystemPrincipal() {
   var principal = Services.scriptSecurityManager.getSystemPrincipal();
   var source = yield notify("systemPrincipal", principal);
   ok(!source, "Should omit source for system principal");
 }
 
-function* testExpandedPrincipal() {
-  var principal = Services.scriptSecurityManager.createExpandedPrincipal([], 0);
-  var source = yield notify("expandedPrincipal", principal);
-  ok(!source, "Should omit source for expanded principal");
-}
-
 function* testNullPrincipal() {
   var principal = Services.scriptSecurityManager.createNullPrincipal({});
   var source = yield notify("nullPrincipal", principal);
   ok(!source, "Should omit source for null principal");
 }
 
 function* testNodePrincipal() {
   var principal = SpecialPowers.wrap(document).nodePrincipal;
@@ -89,22 +101,23 @@ function runTest() {
 
   if ("@mozilla.org/system-alerts-service;1" in Cc) {
     todo(false, "Native alerts service exists in this application");
     return;
   }
 
   ok(true, "Alerts service exists in this application");
 
-  ok(!Services.wm.getEnumerator("alert:alert").hasMoreElements(),
-     "Alerts should not be present at the start of the test.");
+  // sendSyncMessage returns an array of arrays. See the comments in
+  // test_alerts_noobserve.html and test_SpecialPowersLoadChromeScript.html.
+  var [[alertsVisible]] = chromeScript.sendSyncMessage("anyXULAlertsVisible");
+  ok(!alertsVisible, "Alerts should not be present at the start of the test.");
 
   add_task(testNoPrincipal);
   add_task(testSystemPrincipal);
-  add_task(testExpandedPrincipal);
   add_task(testNullPrincipal);
   add_task(testNodePrincipal);
 }
 
 runTest();
 </script>
 </pre>
 </body>