Bug 1138079 - Fix focus issue that sometimes affects browser-chrome test runs. r=enndeakin, a=test-only
authorGavin Sharp <gavin@gavinsharp.com>
Thu, 30 Apr 2015 12:50:30 -0700
changeset 260423 96da8302e8a2
parent 260422 53b766c68811
child 260424 121ed6b9b6dd
push id777
push userryanvm@gmail.com
push date2015-05-07 18:04 +0000
treeherdermozilla-release@121ed6b9b6dd [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersenndeakin, test-only
bugs1138079
milestone38.0
Bug 1138079 - Fix focus issue that sometimes affects browser-chrome test runs. r=enndeakin, a=test-only
testing/mochitest/browser-harness.xul
--- a/testing/mochitest/browser-harness.xul
+++ b/testing/mochitest/browser-harness.xul
@@ -249,19 +249,50 @@
                     gConfig.testRoot == "webapprtChrome" ? "webapprt:webapp" :
                     null;
       if (!winType) {
         throw new Error("Unrecognized gConfig.testRoot: " + gConfig.testRoot);
       }
       var testWin = windowMediator.getMostRecentWindow(winType);
 
       setStatus("Running...");
-      testWin.focus();
-      var Tester = new testWin.Tester(links, gDumper, testsFinished);
-      Tester.start();
+
+      // It's possible that the test harness window is not yet focused when this
+      // function runs (in which case testWin is already focused, and focusing it
+      // will be a no-op, and then the test harness window will steal focus later,
+      // which will mess up tests). So wait for the test harness window to be
+      // focused before trying to focus testWin.
+      waitForFocus(() => {
+        // Focus the test window and start tests.
+        waitForFocus(() => {
+          var Tester = new testWin.Tester(links, gDumper, testsFinished);
+          Tester.start();
+        }, testWin);
+      }, window);
+    }
+
+    function executeSoon(callback) {
+      let tm = Cc["@mozilla.org/thread-manager;1"].getService(Ci.nsIThreadManager);
+      tm.mainThread.dispatch(callback, Ci.nsIThread.DISPATCH_NORMAL);
+    }
+
+    function waitForFocus(callback, win) {
+      // If "win" is already focused, just call the callback.
+      let fm = Cc["@mozilla.org/focus-manager;1"].getService(Ci.nsIFocusManager);
+      if (fm.focusedWindow == win) {
+        executeSoon(callback);
+        return;
+      }
+
+      // Otherwise focus it, and wait for the focus event.
+      win.addEventListener("focus", function listener() {
+        win.removeEventListener("focus", listener, true);
+        executeSoon(callback);
+      }, true);
+      win.focus();
     }
 
     function sum(a, b) {
       return a + b;
     }
 
     function getHTMLLogFromTests(aTests) {
       if (!aTests.length)