Bug 1319237 - Make GeckoDriver#setWindowSize synchronous. r=automatedtester, r=maja_zf, a=test-only
authorAndreas Tolfsen <ato@mozilla.com>
Mon, 21 Nov 2016 23:44:22 +0100
changeset 378505 9040530f721acf09e402a3f4d7533310a4428b5e
parent 378504 50aa351e8ffd0d70639e3da3d04eb5c64feedf41
child 378506 fc404ef132629e39963e7cf0dd2049fb7e4b4b5d
push id1419
push userjlund@mozilla.com
push dateMon, 10 Apr 2017 20:44:07 +0000
treeherdermozilla-release@5e6801b73ef6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersautomatedtester, maja_zf, test-only
bugs1319237
milestone53.0a2
Bug 1319237 - Make GeckoDriver#setWindowSize synchronous. r=automatedtester, r=maja_zf, a=test-only Return from the Set Window Size command only after the window resize DOM event has occurred. MozReview-Commit-ID: 7ygZuNJZzq2
testing/marionette/driver.js
--- a/testing/marionette/driver.js
+++ b/testing/marionette/driver.js
@@ -2414,27 +2414,54 @@ GeckoDriver.prototype.getWindowSize = fu
     width: win.outerWidth,
     height: win.outerHeight,
   };
 };
 
 /**
  * Set the size of the browser window currently in focus.
  *
- * Not supported on B2G. The supplied width and height values refer to
- * the window outerWidth and outerHeight values, which include scroll
- * bars, title bars, etc.
+ * The supplied width and height values refer to the window outerWidth
+ * and outerHeight values, which include browser chrome and OS-level
+ * window borders.
+ *
+ * @param {number} width
+ *     Requested window outer width.
+ * @param {number} height
+ *     Requested window outer height.
+ *
+ * @return {Map.<string, number>}
+ *     New outerWidth/outerHeight dimensions.
  */
-GeckoDriver.prototype.setWindowSize = function (cmd, resp) {
+GeckoDriver.prototype.setWindowSize = function* (cmd, resp) {
   assert.firefox()
 
-  let {width, height} = cmd.parameters;
-  let win = this.getCurrentWindow();
-  win.resizeTo(width, height);
-  this.getWindowSize(cmd, resp);
+  const {width, height} = cmd.parameters;
+  const win = this.getCurrentWindow();
+
+  yield new Promise(resolve => {
+    // When the DOM resize event claims that it fires _after_ the document
+    // view has been resized, it is lying.
+    //
+    // Because resize events fire at a high rate, DOM modifications
+    // such as updates to outerWidth/outerHeight are not guaranteed to
+    // have processed.  To overcome this... abomination... of the web
+    // platform, we throttle the event using setTimeout.  If everything
+    // was well in this world we would use requestAnimationFrame, but
+    // it does not seem to like our particular flavour of XUL.
+    const fps15 = 66;
+    const synchronousResize = () => win.setTimeout(resolve, fps15);
+    win.addEventListener("resize", synchronousResize, {once: true});
+    win.resizeTo(width, height);
+  });
+
+  return {
+    width: win.outerWidth,
+    height: win.outerHeight,
+  };
 };
 
 /**
  * Maximizes the user agent window as if the user pressed the maximise
  * button.
  *
  * Not Supported on B2G or Fennec.
  */