Bug 870205 - Fix intermittent browser_bug295977_autoscroll_overflow.js. r=neil
authorDrew Willcoxon <adw@mozilla.com>
Thu, 05 Jun 2014 10:50:33 -0700
changeset 207265 24f124582f70a64103835464160441bc0a449c69
parent 207264 275b8b4d30ec268c77a0dbe35710673fb34a53ee
child 207266 31db3f3b1107fb0549b26ffb94ddaa17f55fa365
push id494
push userraliiev@mozilla.com
push dateMon, 25 Aug 2014 18:42:16 +0000
treeherdermozilla-release@a3cc3e46b571 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersneil
bugs870205
milestone32.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 870205 - Fix intermittent browser_bug295977_autoscroll_overflow.js. r=neil
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
@@ -4,44 +4,44 @@ function test()
   Services.prefs.setBoolPref(kPrefName_AutoScroll, true);
 
   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;
 
@@ -53,24 +53,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),
@@ -78,30 +99,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) {