Bug 870205 - Fix intermittent browser_bug295977_autoscroll_overflow.js. r=neil, a=test-only
authorDrew Willcoxon <adw@mozilla.com>
Thu, 05 Jun 2014 10:50:33 -0700
changeset 200482 e92fd2c60d1d9d26b42991893e119db9ffdc604a
parent 200481 082d356f509ce70dfcdc7f1cd3d2d85fec4002df
child 200483 9a6276cde9bbe9804152e92727d8e147f4ba7427
push id486
push userasasaki@mozilla.com
push dateMon, 14 Jul 2014 18:39:42 +0000
treeherdermozilla-release@d33428174ff1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersneil, test-only
bugs870205
milestone31.0a2
Bug 870205 - Fix intermittent browser_bug295977_autoscroll_overflow.js. r=neil, a=test-only
toolkit/content/tests/browser/browser_bug295977_autoscroll_overflow.js
--- a/toolkit/content/tests/browser/browser_bug295977_autoscroll_overflow.js
+++ b/toolkit/content/tests/browser/browser_bug295977_autoscroll_overflow.js
@@ -6,44 +6,44 @@ function test()
   gBrowser.selectedTab = gBrowser.addTab();
 
   const expectScrollNone = 0;
   const expectScrollVert = 1;
   const expectScrollHori = 2;
   const expectScrollBoth = 3;
 
   var allTests = [
-    {dataUri: 'data:text/html,<body><style type="text/css">div { display: inline-block; }</style>\
+    {dataUri: 'data:text/html,<html><head><meta charset="utf-8"></head><body><style type="text/css">div { display: inline-block; }</style>\
       <div id="a" style="width: 100px; height: 100px; overflow: hidden;"><div style="width: 200px; height: 200px;"></div></div>\
       <div id="b" style="width: 100px; height: 100px; overflow: auto;"><div style="width: 200px; height: 200px;"></div></div>\
       <div id="c" style="width: 100px; height: 100px; overflow-x: auto; overflow-y: hidden;"><div style="width: 200px; height: 200px;"></div></div>\
       <div id="d" style="width: 100px; height: 100px; overflow-y: auto; overflow-x: hidden;"><div style="width: 200px; height: 200px;"></div></div>\
       <select id="e" style="width: 100px; height: 100px;" multiple="multiple"><option>aaaaaaaaaaaaaaaaaaaaaaaa</option><option>a</option><option>a</option>\
       <option>a</option><option>a</option><option>a</option><option>a</option><option>a</option><option>a</option><option>a</option>\
       <option>a</option><option>a</option><option>a</option><option>a</option><option>a</option><option>a</option><option>a</option></select>\
       <select id="f" style="width: 100px; height: 100px;"><option>a</option><option>aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa</option><option>a</option>\
       <option>a</option><option>a</option><option>a</option><option>a</option><option>a</option><option>a</option><option>a</option>\
       <option>a</option><option>a</option><option>a</option><option>a</option><option>a</option><option>a</option><option>a</option></select>\
       <div id="g" style="width: 99px; height: 99px; border: 10px solid black; margin: 10px; overflow: auto;"><div style="width: 100px; height: 100px;"></div></div>\
       <div id="h" style="width: 100px; height: 100px; overflow: -moz-hidden-unscrollable;"><div style="width: 200px; height: 200px;"></div></div>\
       <iframe id="iframe" style="display: none;"></iframe>\
-      </body>'},
+      </body></html>'},
     {elem: 'a', expected: expectScrollNone},
     {elem: 'b', expected: expectScrollBoth},
     {elem: 'c', expected: expectScrollHori},
     {elem: 'd', expected: expectScrollVert},
     {elem: 'e', expected: expectScrollVert},
     {elem: 'f', expected: expectScrollNone},
     {elem: 'g', expected: expectScrollBoth},
     {elem: 'h', expected: expectScrollNone},
-    {dataUri: 'data:text/html,<html><body id="i" style="overflow-y: scroll"><div style="height: 2000px"></div>\
+    {dataUri: 'data:text/html,<html><head><meta charset="utf-8"></head><body id="i" style="overflow-y: scroll"><div style="height: 2000px"></div>\
       <iframe id="iframe" style="display: none;"></iframe>\
       </body></html>'},
     {elem: 'i', expected: expectScrollVert}, // bug 695121
-    {dataUri: 'data:text/html,<html><style>html, body { width: 100%; height: 100%; overflow-x: hidden; overflow-y: scroll; }</style>\
+    {dataUri: 'data:text/html,<html><head><meta charset="utf-8"></head><style>html, body { width: 100%; height: 100%; overflow-x: hidden; overflow-y: scroll; }</style>\
       <body id="j"><div style="height: 2000px"></div>\
       <iframe id="iframe" style="display: none;"></iframe>\
       </body></html>'},
     {elem: 'j', expected: expectScrollVert}  // bug 914251
   ];
 
   var doc;
 
@@ -55,24 +55,45 @@ function test()
     }
 
     if (test.dataUri) {
       startLoad(test.dataUri);
       return;
     }
 
     var elem = doc.getElementById(test.elem);
-    // Skip the first callback as it's the same callback that the browser
-    // uses to kick off the scrolling.
-    var skipFrames = 1;
-    var checkScroll = function () {
-      if (skipFrames--) {
+
+    let firstTimestamp = undefined;
+    function checkScroll(timestamp) {
+      if (firstTimestamp === undefined) {
+        firstTimestamp = timestamp;
+      }
+
+      // This value is calculated similarly to the value of the same name in
+      // ClickEventHandler.autoscrollLoop, except here it's cumulative across
+      // all frames after the first one instead of being based only on the
+      // current frame.
+      let timeCompensation = (timestamp - firstTimestamp) / 20;
+      info("timestamp=" + timestamp + " firstTimestamp=" + firstTimestamp +
+           " timeCompensation=" + timeCompensation);
+
+      // Try to wait until enough time has passed to allow the scroll to happen.
+      // autoscrollLoop incrementally scrolls during each animation frame, but
+      // due to how its calculations work, when a frame is very close to the
+      // previous frame, no scrolling may actually occur during that frame.
+      // After 20ms's worth of frames, timeCompensation will be 1, making it
+      // more likely that the accumulated scroll in autoscrollLoop will be >= 1,
+      // although it also depends on acceleration, which here in this test
+      // should be > 1 due to how it synthesizes mouse events below.
+      if (timeCompensation < 1) {
         window.mozRequestAnimationFrame(checkScroll);
         return;
       }
+
+      // Close the autoscroll popup by synthesizing Esc.
       EventUtils.synthesizeKey("VK_ESCAPE", {}, gBrowser.contentWindow);
       var scrollVert = test.expected & expectScrollVert;
       ok((scrollVert && elem.scrollTop > 0) ||
          (!scrollVert && elem.scrollTop == 0),
          test.elem+' should'+(scrollVert ? '' : ' not')+' have scrolled vertically');
       var scrollHori = test.expected & expectScrollHori;
       ok((scrollHori && elem.scrollLeft > 0) ||
          (!scrollHori && elem.scrollLeft == 0),
@@ -80,30 +101,29 @@ function test()
 
       // Before continuing the test, we need to ensure that the IPC
       // message that stops autoscrolling has had time to arrive.
       executeSoon(nextTest);
     };
     EventUtils.synthesizeMouse(elem, 50, 50, { button: 1 },
                                gBrowser.contentWindow);
 
+    // This ensures bug 605127 is fixed: pagehide in an unrelated document
+    // should not cancel the autoscroll.
     var iframe = gBrowser.contentDocument.getElementById("iframe");
     var e = iframe.contentDocument.createEvent("pagetransition");
     e.initPageTransitionEvent("pagehide", true, true, false);
     iframe.contentDocument.dispatchEvent(e);
     iframe.contentDocument.documentElement.dispatchEvent(e);
 
     EventUtils.synthesizeMouse(elem, 100, 100,
                                { type: "mousemove", clickCount: "0" },
                                gBrowser.contentWindow);
-    /*
-     * if scrolling didn’t work, we wouldn’t do any redraws and thus time out.
-     * so request and force redraws to get the chance to check for scrolling at
-     * all.
-     */
+
+    // Start checking for the scroll.
     window.mozRequestAnimationFrame(checkScroll);
   }
 
   waitForExplicitFinish();
 
   nextTest();
 
   function startLoad(dataUri) {