Bug 1053413 part 0 - Fix of some fullscreen tests. r=smaug
authorXidorn Quan <quanxunzhen@gmail.com>
Thu, 21 May 2015 09:52:26 +1200
changeset 244793 8f57a2e8384b29139e14685e9329f69edf1c6e91
parent 244792 ce80e70b04e253c58c03fc3304c8ec7dd141a52d
child 244794 4a335d85b27b75196b5f0a785073f69c4086bae0
push id60038
push userxquan@mozilla.com
push dateWed, 20 May 2015 21:53:15 +0000
treeherdermozilla-inbound@49ffe4e6b4d2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1053413
milestone41.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 1053413 part 0 - Fix of some fullscreen tests. r=smaug
dom/html/test/file_fullscreen-api-keys.html
dom/html/test/file_fullscreen-utils.js
dom/html/test/test_fullscreen-api.html
--- a/dom/html/test/file_fullscreen-api-keys.html
+++ b/dom/html/test/file_fullscreen-api-keys.html
@@ -87,18 +87,22 @@ function testScriptInitiatedKeyEvents() 
   
   ok(gKeyReceived, "dispatchEvent should dispatch events synchronously");
   ok(document.mozFullScreen,
      "Should remain in full-screen mode for script initiated key events for " + gKeyName);
 }
 
 function testNextKey() {
   if (!document.mozFullScreen) {
-    addFullscreenChangeContinuation("enter", reallyTestNextKey);
-    document.body.mozRequestFullScreen();
+    // Async request fullscreen to avoid the request be accidentally
+    // cancelled due to unfinished clean-up of exiting fullscreen.
+    setTimeout(() => {
+      addFullscreenChangeContinuation("enter", reallyTestNextKey);
+      document.body.mozRequestFullScreen();
+    }, 0);
   }
   else {
     reallyTestNextKey();
   }
 }
 
 function reallyTestNextKey() {
   ok(document.mozFullScreen, "Must be in full-screen mode");
--- a/dom/html/test/file_fullscreen-utils.js
+++ b/dom/html/test/file_fullscreen-utils.js
@@ -15,91 +15,60 @@ function inFullscreenMode() {
 // Returns true if the window is in normal mode, i.e. non fullscreen mode.
 // Note this only returns true once the transition from fullscreen back to
 // normal mode is complete.
 function inNormalMode() {
   return window.outerWidth == normalSize.w &&
          window.outerHeight == normalSize.h;
 }
 
-function ok(condition, msg) {
-  opener.ok(condition, "[rollback] " + msg);
-  if (!condition) {
-    opener.finish();
-  }
-}
-
-// On Linux we sometimes receive fullscreenchange events before the window
-// has finished transitioning to fullscreen. This can cause problems and
-// test failures, so work around it on Linux until we can get a proper fix.
-const workAroundFullscreenTransition = navigator.userAgent.indexOf("Linux") != -1;
-
-if (workAroundFullscreenTransition) {
-  SimpleTest.requestFlakyTimeout("We need to wait an arbitrary and non-zero " +
-    "amount of time in case of the Linux specific workaround to avoid busy-waiting.");
-}
-
 // Adds a listener that will be called once a fullscreen transition
 // is complete. When type==='enter', callback is called when we've
 // received a fullscreenchange event, and the fullscreen transition is
 // complete. When type==='exit', callback is called when we've
 // received a fullscreenchange event and the window dimensions match
 // the window dimensions when the window opened (so don't resize the
 // window while running your test!). inDoc is the document which
 // the listeners are added on, if absent, the listeners are added to
 // the current document.
 function addFullscreenChangeContinuation(type, callback, inDoc) {
   var doc = inDoc || document;
-  var listener = null;
-  if (type === "enter") {
-    // when entering fullscreen, ensure we don't call 'callback' until the
-    // enter transition is complete.
-    listener = function(event) {
-      doc.removeEventListener("mozfullscreenchange", listener, false);
-      if (!workAroundFullscreenTransition) {
-        callback(event);
-        return;
-      }
-      if (!inFullscreenMode()) {
-        opener.todo(false, "fullscreenchange before entering fullscreen complete! " +
-                    " window.fullScreen=" + window.fullScreen +
-                    " normal=(" + normalSize.w + "," + normalSize.h + ")" +
-                    " outerWidth=" + window.outerWidth + " width=" + window.screen.width +
-                    " outerHeight=" + window.outerHeight + " height=" + window.screen.height);
-        setTimeout(function(){listener(event);}, 100);
-        return;
+  function checkCondition() {
+    if (type == "enter") {
+      return inFullscreenMode();
+    } else if (type == "exit") {
+      // If we just revert the state to a previous fullscreen state,
+      // the window won't back to the normal mode. Hence we check
+      // mozFullScreenElement first here.
+      return doc.mozFullScreenElement || inNormalMode();
+    } else {
+      throw "'type' must be either 'enter', or 'exit'.";
+    }
+  }
+  function invokeCallback(event) {
+    // Use async call after a paint to workaround unfinished fullscreen
+    // change even when the window size has changed on Linux.
+    requestAnimationFrame(() => setTimeout(() => callback(event), 0), 0);
+  }
+  function onFullscreenChange(event) {
+    doc.removeEventListener("mozfullscreenchange", onFullscreenChange, false);
+    if (checkCondition()) {
+      invokeCallback(event);
+      return;
+    }
+    var win = doc.defaultView;
+    function onResize() {
+      if (checkCondition()) {
+        win.removeEventListener("resize", onResize, false);
+        invokeCallback(event);
       }
-      setTimeout(function(){callback(event)}, 0);
-    };
-  } else if (type === "exit") {
-    listener = function(event) {
-      doc.removeEventListener("mozfullscreenchange", listener, false);
-      if (!workAroundFullscreenTransition) {
-        callback(event);
-        return;
-      }
-      if (!document.mozFullScreenElement && !inNormalMode()) {
-        opener.todo(false, "fullscreenchange before exiting fullscreen complete! " +
-                    " window.fullScreen=" + window.fullScreen +
-                    " normal=(" + normalSize.w + "," + normalSize.h + ")" +
-                    " outerWidth=" + window.outerWidth + " width=" + window.screen.width +
-                    " outerHeight=" + window.outerHeight + " height=" + window.screen.height);
-        // 'document' (*not* 'doc') has no fullscreen element, so we're trying
-        // to completely exit fullscreen mode. Wait until the transition
-        // to normal mode is complete before calling callback.
-        setTimeout(function(){listener(event);}, 100);
-        return;
-      }
-      opener.info("[rollback] Exited fullscreen");
-      setTimeout(function(){callback(event);}, 0);
-    };
-  } else {
-    throw "'type' must be either 'enter', or 'exit'.";
+    }
+    win.addEventListener("resize", onResize, false);
   }
-  doc.addEventListener("mozfullscreenchange", listener, false);
+  doc.addEventListener("mozfullscreenchange", onFullscreenChange, false);
 }
 
 // Calls |callback| when the next fullscreenerror is dispatched to inDoc||document.
 function addFullscreenErrorContinuation(callback, inDoc) {
   var doc = inDoc || document;
   var listener = function(event) {
     doc.removeEventListener("mozfullscreenerror", listener, false);
     setTimeout(function(){callback(event);}, 0);
--- a/dom/html/test/test_fullscreen-api.html
+++ b/dom/html/test/test_fullscreen-api.html
@@ -47,16 +47,20 @@ var gTestIndex = 0;
 
 // TODO: if ever we remove these checks for XP and Lion, we should do the same
 // in dom/tests/mochitest/pointerlock/test_pointerlock-api.html, which uses the same pattern.
 const isWinXP = navigator.userAgent.indexOf("Windows NT 5.1") != -1;
 const isOSXLion = navigator.userAgent.indexOf("Mac OS X 10.7") != -1;
 const isOSXMtnLion = navigator.userAgent.indexOf("Mac OS X 10.8") != -1;
 const isOSXYosemite = navigator.userAgent.indexOf("Mac OS X 10.10") != -1;
 
+function finish() {
+  SimpleTest.finish();
+}
+
 function nextTest() {
   if (isWinXP) {
     todo(false, "Can't reliably run full-screen tests on Windows XP due to bug 704010");
     SimpleTest.finish();
     return;
   }
   if (testWindow) {
     testWindow.close();
@@ -68,16 +72,17 @@ function nextTest() {
       return;
     }
   }
   runNextTest();
 }
 
 function runNextTest() {
   if (gTestIndex < gTestWindows.length) {
+    info("Run test " + gTestWindows[gTestIndex]);
     testWindow = window.open(gTestWindows[gTestIndex], "", "width=500,height=500");
     // We'll wait for the window to load, then make sure our window is refocused
     // before starting the test, which will get kicked off on "focus".
     // This ensures that we're essentially back on the primary "desktop" on
     // OS X Lion before we run the test.
     testWindow.addEventListener("load", function onload() {
       testWindow.removeEventListener("load", onload, false);
       SimpleTest.waitForFocus(function() {