Bug 1302879 - Intermittent browser_device_change.js | Test timed out. r=jryans, a=test-only
authorMatteo Ferretti <mferretti@mozilla.com>
Thu, 29 Sep 2016 14:07:24 +0200
changeset 355871 18533e740b1428f1462cd4f4817be3f597986c48
parent 355870 c45559c115da22f70d58cec454b7b508af4f03de
child 355872 9942a916850c2035379c28f13018573421fc1573
push id6570
push userraliiev@mozilla.com
push dateMon, 14 Nov 2016 12:26:13 +0000
treeherdermozilla-beta@f455459b2ae5 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjryans, test-only
bugs1302879
milestone51.0a2
Bug 1302879 - Intermittent browser_device_change.js | Test timed out. r=jryans, a=test-only - 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);