Bug 1302879 - Intermittent browser_device_change.js | Test timed out; r=jryans
authorMatteo Ferretti <mferretti@mozilla.com>
Thu, 29 Sep 2016 14:07:24 +0200
changeset 316114 af6e01b8574b2a844e86a4ed983b98c18305525f
parent 316113 55741185923649a1628de065bb1ec04dc37ccbd5
child 316115 5bf0ee1a10f44ef12f13bfe03f58726feffa59a1
push id30760
push userphilringnalda@gmail.com
push dateSat, 01 Oct 2016 06:25:51 +0000
treeherdermozilla-central@87cd291d2db6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjryans
bugs1302879
milestone52.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 1302879 - Intermittent browser_device_change.js | Test timed out; r=jryans - Handled racing condition from document's reload in `waitForViewportResizeTo` MozReview-Commit-ID: 6WR6ETcQsB8
devtools/client/responsive.html/test/browser/head.js
--- a/devtools/client/responsive.html/test/browser/head.js
+++ b/devtools/client/responsive.html/test/browser/head.js
@@ -117,28 +117,52 @@ function waitForFrameLoad(ui, targetURL)
         content.location.href == args.targetURL) {
       return;
     }
     yield ContentTaskUtils.waitForEvent(this, "DOMContentLoaded");
   });
 }
 
 function waitForViewportResizeTo(ui, width, height) {
-  return new Promise(resolve => {
+  return new Promise(Task.async(function* (resolve) {
+    let isSizeMatching = (data) => data.width == width && data.height == height;
+
+    // If the viewport has already the expected size, we resolve the promise immediately.
+    let size = yield getContentSize(ui);
+    if (isSizeMatching(size)) {
+      resolve();
+      return;
+    }
+
+    // Otherwise, we'll listen to both content's resize event and browser's load end;
+    // since a racing condition can happen, where the content's listener is added after
+    // the resize, because the content's document was reloaded; therefore the test would
+    // hang forever. See bug 1302879.
+    let browser = ui.getViewportBrowser();
+
     let onResize = (_, data) => {
-      if (data.width != width || data.height != height) {
+      if (!isSizeMatching(data)) {
         return;
       }
       ui.off("content-resize", onResize);
+      browser.removeEventListener("mozbrowserloadend", onBrowserLoadEnd);
       info(`Got content-resize to ${width} x ${height}`);
       resolve();
     };
+
+    let onBrowserLoadEnd = Task.async(function* () {
+      let data = yield getContentSize(ui);
+      onResize(undefined, data);
+    });
+
     info(`Waiting for content-resize to ${width} x ${height}`);
     ui.on("content-resize", onResize);
-  });
+    browser.addEventListener("mozbrowserloadend",
+      onBrowserLoadEnd, { once: true });
+  }));
 }
 
 var setViewportSize = Task.async(function* (ui, manager, width, height) {
   let size = ui.getViewportSize();
   info(`Current size: ${size.width} x ${size.height}, ` +
        `set to: ${width} x ${height}`);
   if (size.width != width || size.height != height) {
     let resized = waitForViewportResizeTo(ui, width, height);
@@ -245,16 +269,23 @@ function getSessionHistory(browser) {
       });
     }
 
     return result;
     /* eslint-enable no-undef */
   });
 }
 
+function getContentSize(ui) {
+  return spawnViewportTask(ui, {}, () => ({
+    width: content.screen.width,
+    height: content.screen.height
+  }));
+}
+
 function waitForPageShow(browser) {
   let mm = browser.messageManager;
   return new Promise(resolve => {
     let onShow = message => {
       if (message.target != browser) {
         return;
       }
       mm.removeMessageListener("PageVisibility:Show", onShow);