Bug 1400226 - Wait for visibilitychange event on window minimize/restore. r=whimboo
authorAndreas Tolfsen <ato@sny.no>
Wed, 20 Sep 2017 14:42:13 +0100
changeset 435529 6470a12114de3e4f0a333f89b0dcf570a101f392
parent 435528 69c2f0ea56ddc0114cdc4035d7d16dea9ab3d729
child 435530 e907fa0c6d37aa3153a41027b13140821d60b052
push id1618
push userCallek@gmail.com
push dateThu, 11 Jan 2018 17:45:48 +0000
treeherdermozilla-release@882ca853e05a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerswhimboo
bugs1400226, 1397007
milestone57.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 1400226 - Wait for visibilitychange event on window minimize/restore. r=whimboo The sizemodechange event is not strongly connected to the visibilitychange event that the WPT minimize_window.py test is now using to ascertain whether the window has been successfully iconified. Because Marionette uses the sizemodechange event it is causing intermittents such as https://bugzil.la/1397007. You can also read a lengthy summary I did on the problem in https://bugzil.la/1397007#c11. The fix for the problem is to wait for the visibilitychange DOM event content. MozReview-Commit-ID: B6i33Ee5iMC
testing/marionette/driver.js
--- a/testing/marionette/driver.js
+++ b/testing/marionette/driver.js
@@ -1516,17 +1516,17 @@ GeckoDriver.prototype.setWindowRect = as
   }
 
   switch (WindowState.from(win.windowState)) {
     case WindowState.Fullscreen:
       await exitFullscreen(win);
       break;
 
     case WindowState.Minimized:
-      await restoreWindow(win);
+      await restoreWindow(win, this.curBrowser.eventObserver);
       break;
   }
 
   if (height != null && width != null) {
     assert.positiveInteger(height);
     assert.positiveInteger(width);
 
     if (win.outerWidth != width || win.outerHeight != height) {
@@ -3000,17 +3000,17 @@ GeckoDriver.prototype.minimizeWindow = a
   assert.noUserPrompt(this.dialog);
 
   if (WindowState.from(win.windowState) == WindowState.Fullscreen) {
     await exitFullscreen(win);
   }
 
   if (WindowState.from(win.windowState) != WindowState.Minimized) {
     await new Promise(resolve => {
-      win.addEventListener("sizemodechange", whenIdle(win, resolve), {once: true});
+      this.curBrowser.eventObserver.addEventListener("visibilitychange", resolve, {once: true});
       win.minimize();
     });
   }
 
   return this.curBrowser.rect;
 };
 
 /**
@@ -3037,17 +3037,17 @@ GeckoDriver.prototype.maximizeWindow = a
   assert.noUserPrompt(this.dialog);
 
   switch (WindowState.from(win.windowState)) {
     case WindowState.Fullscreen:
       await exitFullscreen(win);
       break;
 
     case WindowState.Minimized:
-      await restoreWindow(win);
+      await restoreWindow(win, this.curBrowser.eventObserver);
       break;
   }
 
   const origSize = {
     outerWidth: win.outerWidth,
     outerHeight: win.outerHeight,
   };
 
@@ -3118,17 +3118,17 @@ GeckoDriver.prototype.maximizeWindow = a
  *     A modal dialog is open, blocking this operation.
  */
 GeckoDriver.prototype.fullscreenWindow = async function(cmd, resp) {
   assert.firefox();
   const win = assert.window(this.getCurrentWindow());
   assert.noUserPrompt(this.dialog);
 
   if (WindowState.from(win.windowState) == WindowState.Minimized) {
-    await restoreWindow(win);
+    await restoreWindow(win, this.curBrowser.eventObserver);
   }
 
   if (WindowState.from(win.windowState) != WindowState.Fullscreen) {
     await new Promise(resolve => {
       win.addEventListener("sizemodechange", resolve, {once: true});
       win.fullScreen = true;
     });
   }
@@ -3708,23 +3708,25 @@ async function exitFullscreen(window) {
     window.addEventListener("sizemodechange", whenIdle(window, resolve), {once: true});
     window.fullScreen = false;
   });
 }
 
 /**
  * Restore window and wait for the window state to change.
  *
- * @param {ChromeWindow} window
+ * @param {ChromeWindow} chromWindow
  *     Window to restore.
+ * @param {WebElementEventTarget} contentWindow
+ *     Content window to listen for events in.
  */
-async function restoreWindow(window) {
+async function restoreWindow(chromeWindow, contentWindow) {
   return new Promise(resolve => {
-    window.addEventListener("sizemodechange", whenIdle(window, resolve), {once: true});
-    window.restore();
+    contentWindow.addEventListener("visibilitychange", resolve, {once: true});
+    chromeWindow.restore();
   });
 }
 
 /**
  * Throttle <var>callback</var> until the main thread is idle and
  * <var>window</var> has performed an animation frame.
  *
  * @param {ChromeWindow} window