Bug 861689 - Unable to restore focus, expect failures and timeouts after certain tests in the b2g mochitest run. r=jmaher
☠☠ backed out by ca037d3e866f ☠ ☠
authorMartijn Wargers <mwargers@mozilla.com>
Mon, 29 Apr 2013 23:14:32 +0200
changeset 141279 f4da799815dabe5d1e0e739cf7347dd51d85b68d
parent 141278 101bd6c508b98d7078ed958bbfc04c33becf5ce8
child 141280 75db6ad43aa1e7d952479f469d3975b33150fafb
push id2579
push userakeybl@mozilla.com
push dateMon, 24 Jun 2013 18:52:47 +0000
treeherdermozilla-beta@b69b7de8a05a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjmaher
bugs861689
milestone23.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 861689 - Unable to restore focus, expect failures and timeouts after certain tests in the b2g mochitest run. r=jmaher
content/html/content/test/forms/test_input_typing_sanitization.html
testing/mochitest/runtestsb2g.py
testing/mochitest/tests/SimpleTest/ChromePowers.js
testing/mochitest/tests/SimpleTest/TestRunner.js
testing/specialpowers/components/SpecialPowersObserver.js
testing/specialpowers/content/specialpowersAPI.js
--- a/content/html/content/test/forms/test_input_typing_sanitization.html
+++ b/content/html/content/test/forms/test_input_typing_sanitization.html
@@ -89,17 +89,17 @@ function checkValueSubmittedIsInvalid()
     submitMethod = sendKeyEventToSubmitForm;
     submitFrame.onload = checkValueSubmittedIsValid;
     testData = gValidData;
   }
   testSubmissions();
 }
 
 function testSubmissions() {
-  SpecialPowers.focus(input);
+  input.focus();
   sendString(testData[valueIndex]);
   submitMethod();
 }
 
 var valueIndex = 0;
 var submitMethod = submitForm;
 
 SimpleTest.waitForExplicitFinish();
@@ -181,25 +181,25 @@ function runTest()
     }
 
     input.type = test.type;
     gValidData = test.validData;
     gInvalidData = test.invalidData;
 
     for (data of gValidData) {
       input.value = "";
-      SpecialPowers.focus(input);
+      input.focus();
       sendString(data);
       input.blur();
       is(input.value, data, "valid user input should not be sanitized");
     }
 
     for (data of gInvalidData) {
       input.value = "";
-      SpecialPowers.focus(input);
+      input.focus();
       sendString(data);
       input.blur();
       is(input.value, "", "invalid user input should be sanitized");
     }
 
     input.value = '';
 
     testData = gValidData;
--- a/testing/mochitest/runtestsb2g.py
+++ b/testing/mochitest/runtestsb2g.py
@@ -55,21 +55,21 @@ class B2GMochitest(Mochitest):
             OOP_script = """
 let specialpowers = {};
 let loader = Cc["@mozilla.org/moz/jssubscript-loader;1"].getService(Ci.mozIJSSubScriptLoader);
 loader.loadSubScript("chrome://specialpowers/content/SpecialPowersObserver.js", specialpowers);
 let specialPowersObserver = new specialpowers.SpecialPowersObserver();
 specialPowersObserver.init();
 
 let mm = container.QueryInterface(Ci.nsIFrameLoaderOwner).frameLoader.messageManager;
-container.focus();
 mm.addMessageListener("SPPrefService", specialPowersObserver);
 mm.addMessageListener("SPProcessCrashService", specialPowersObserver);
 mm.addMessageListener("SPPingService", specialPowersObserver);
 mm.addMessageListener("SpecialPowers.Quit", specialPowersObserver);
+mm.addMessageListener("SpecialPowers.Focus", specialPowersObserver);
 mm.addMessageListener("SPPermissionManager", specialPowersObserver);
 
 mm.loadFrameScript(CHILD_LOGGER_SCRIPT, true);
 mm.loadFrameScript(CHILD_SCRIPT_API, true);
 mm.loadFrameScript(CHILD_SCRIPT, true);
 specialPowersObserver._isFrameScriptLoaded = true;
 """
         else:
--- a/testing/mochitest/tests/SimpleTest/ChromePowers.js
+++ b/testing/mochitest/tests/SimpleTest/ChromePowers.js
@@ -67,16 +67,23 @@ ChromePowers.prototype._receiveMessage =
 
 ChromePowers.prototype.quit = function() {
   // We come in here as SpecialPowers.quit, but SpecialPowers is really ChromePowers.
   // For some reason this.<func> resolves to TestRunner, so using SpecialPowers
   // allows us to use the ChromePowers object which we defined below.
   SpecialPowers._sendSyncMessage("SpecialPowers.Quit", {});
 };
 
+ChromePowers.prototype.focus = function(aWindow) {
+  // We come in here as SpecialPowers.focus, but SpecialPowers is really ChromePowers.
+  // For some reason this.<func> resolves to TestRunner, so using SpecialPowers
+  // allows us to use the ChromePowers object which we defined below.
+  aWindow.focus();
+};
+
 ChromePowers.prototype.executeAfterFlushingMessageQueue = function(aCallback) {
   aCallback();
 };
 
 // Expose everything but internal APIs (starting with underscores) to
 // web content.  We cannot use Object.keys to view SpecialPowers.prototype since
 // we are using the functions from SpecialPowersAPI.prototype
 ChromePowers.prototype.__exposedProps__ = {};
--- a/testing/mochitest/tests/SimpleTest/TestRunner.js
+++ b/testing/mochitest/tests/SimpleTest/TestRunner.js
@@ -232,24 +232,24 @@ TestRunner._makeIframe = function (url, 
     var iframe = $('testframe');
     if (url != "about:blank" &&
         (("hasFocus" in document && !document.hasFocus()) ||
          ("activeElement" in document && document.activeElement != iframe))) {
         // typically calling ourselves from setTimeout is sufficient
         // but we'll try focus() just in case that's needed
 
         contentAsyncEvent("Focus");
-        window.focus();
+        SpecialPowers.focus(window);
         iframe.focus();
         if (retry < 3) {
             window.setTimeout('TestRunner._makeIframe("'+url+'", '+(retry+1)+')', 1000);
             return;
         }
 
-        TestRunner.log("Error: Unable to restore focus, expect failures and timeouts.");
+        TestRunner.error("Error: Unable to restore focus, expect failures and timeouts.");
     }
     window.scrollTo(0, $('indicator').offsetTop);
     iframe.src = url;
     iframe.name = url;
     iframe.width = "500";
     return iframe;
 };
 
@@ -277,18 +277,16 @@ TestRunner.runTests = function (/*url...
     TestRunner.log("SimpleTest START");
     TestRunner.originalTestURL = $("current-test").innerHTML;
 
     SpecialPowers.registerProcessCrashObservers();
 
     TestRunner._urls = flattenArguments(arguments);
     $('testframe').src="";
     TestRunner._checkForHangs();
-    window.focus();
-    $('testframe').focus();
     TestRunner.runNextTest();
 };
 
 /**
  * Used for running a set of tests in a loop for debugging purposes
  * Takes an array of URLs
 **/
 TestRunner.resetTests = function(listURLs) {
@@ -296,18 +294,16 @@ TestRunner.resetTests = function(listURL
   // Reset our "Current-test" line - functionality depends on it
   $("current-test").innerHTML = TestRunner.originalTestURL;
   if (TestRunner.logEnabled)
     TestRunner.log("SimpleTest START Loop " + TestRunner._currentLoop);
 
   TestRunner._urls = listURLs;
   $('testframe').src="";
   TestRunner._checkForHangs();
-  window.focus();
-  $('testframe').focus();
   TestRunner.runNextTest();
 }
 
 /*
  * Used to run a single test in a loop and update the UI with the results
  */
 TestRunner.loopTest = function(testPath) {
   //must set the following line so that TestHarness.updateUI finds the right div to update
--- a/testing/specialpowers/components/SpecialPowersObserver.js
+++ b/testing/specialpowers/components/SpecialPowersObserver.js
@@ -51,16 +51,17 @@ SpecialPowersObserver.prototype = new Sp
 
       case "chrome-document-global-created":
         if (!this._isFrameScriptLoaded) {
           // Register for any messages our API needs us to handle
           this._messageManager.addMessageListener("SPPrefService", this);
           this._messageManager.addMessageListener("SPProcessCrashService", this);
           this._messageManager.addMessageListener("SPPingService", this);
           this._messageManager.addMessageListener("SpecialPowers.Quit", this);
+          this._messageManager.addMessageListener("SpecialPowers.Focus", this);
           this._messageManager.addMessageListener("SPPermissionManager", this);
           this._messageManager.addMessageListener("SPWebAppService", this);
 
           this._messageManager.loadFrameScript(CHILD_LOGGER_SCRIPT, true);
           this._messageManager.loadFrameScript(CHILD_SCRIPT_API, true);
           this._messageManager.loadFrameScript(CHILD_SCRIPT, true);
           this._isFrameScriptLoaded = true;
         }
@@ -139,14 +140,17 @@ SpecialPowersObserver.prototype = new Sp
                   .messageManager
                   .sendAsyncMessage("SPPingService", { op: "pong" });
         }
         break;
       case "SpecialPowers.Quit":
         let appStartup = Cc["@mozilla.org/toolkit/app-startup;1"].getService(Ci.nsIAppStartup);
         appStartup.quit(Ci.nsIAppStartup.eForceQuit);
         break;
+      case "SpecialPowers.Focus":
+        aMessage.target.focus();
+        break;
       default:
         return this._receiveMessage(aMessage);
     }
   };
 
 this.NSGetFactory = XPCOMUtils.generateNSGetFactory([SpecialPowersObserver]);
--- a/testing/specialpowers/content/specialpowersAPI.js
+++ b/testing/specialpowers/content/specialpowersAPI.js
@@ -1251,18 +1251,19 @@ SpecialPowersAPI.prototype = {
   activeWindow: function() {
     return this.focusManager.activeWindow;
   },
 
   focusedWindow: function() {
     return this.focusManager.focusedWindow;
   },
 
-  focus: function(window) {
-    window.focus();
+  focus: function(aWindow) {
+    sendAsyncMessage("SpecialPowers.Focus", {});
+    aWindow.focus();
   },
 
   getClipboardData: function(flavor) {
     if (this._cb == null)
       this._cb = Components.classes["@mozilla.org/widget/clipboard;1"].
                             getService(Components.interfaces.nsIClipboard);
 
     var xferable = Components.classes["@mozilla.org/widget/transferable;1"].