Bug 1280013 - Add a test. r?botond draft
authorKartikaya Gupta <kgupta@mozilla.com>
Sun, 26 Jun 2016 12:32:42 -0400
changeset 381375 61e97c2632086f2422d3fccb6029dc307879640d
parent 381374 a7322858942b856da6c9c73bdac7a06559f0876a
child 523945 2ed9007af8be39fcf04b42867cbd367b3ad9ac34
push id21457
push userkgupta@mozilla.com
push dateSun, 26 Jun 2016 16:33:09 +0000
reviewersbotond
bugs1280013
milestone50.0a1
Bug 1280013 - Add a test. r?botond MozReview-Commit-ID: IDT4aQt3OqQ
gfx/layers/apz/test/mochitest/apz_test_utils.js
gfx/layers/apz/test/mochitest/helper_bug1280013.html
gfx/layers/apz/test/mochitest/helper_bug982141.html
gfx/layers/apz/test/mochitest/helper_tall.html
gfx/layers/apz/test/mochitest/mochitest.ini
gfx/layers/apz/test/mochitest/test_group_zoom.html
layout/base/nsLayoutUtils.cpp
--- a/gfx/layers/apz/test/mochitest/apz_test_utils.js
+++ b/gfx/layers/apz/test/mochitest/apz_test_utils.js
@@ -11,16 +11,31 @@
 function convertEntries(entries) {
   var result = {};
   for (var i = 0; i < entries.length; ++i) {
     result[entries[i].key] = entries[i].value;
   }
   return result;
 }
 
+function getPropertyAsRect(scrollFrames, scrollId, prop) {
+  SimpleTest.ok(scrollId in scrollFrames,
+                'expected scroll frame data for scroll id ' + scrollId);
+  var scrollFrameData = scrollFrames[scrollId];
+  SimpleTest.ok('displayport' in scrollFrameData,
+                'expected a ' + prop + ' for scroll id ' + scrollId);
+  var value = scrollFrameData[prop];
+  var pieces = value.replace(/[()\s]+/g, '').split(',');
+  SimpleTest.is(pieces.length, 4, "expected string of form (x,y,w,h)");
+  return { x: parseInt(pieces[0]),
+           y: parseInt(pieces[1]),
+           w: parseInt(pieces[2]),
+           h: parseInt(pieces[3]) };
+}
+
 function convertScrollFrameData(scrollFrames) {
   var result = {};
   for (var i = 0; i < scrollFrames.length; ++i) {
     result[scrollFrames[i].scrollId] = convertEntries(scrollFrames[i].entries);
   }
   return result;
 }
 
new file mode 100644
--- /dev/null
+++ b/gfx/layers/apz/test/mochitest/helper_bug1280013.html
@@ -0,0 +1,72 @@
+<!DOCTYPE HTML>
+<html style="overflow:hidden">
+<head>
+  <meta charset="utf-8">
+  <meta name="viewport" content="width=980; initial-scale=1.0">
+  <title>Test for bug 1280013</title>
+  <script type="application/javascript" src="apz_test_native_event_utils.js"></script>
+  <script type="application/javascript" src="apz_test_utils.js"></script>
+  <script type="application/javascript" src="/tests/SimpleTest/paint_listener.js"></script>
+  <script type="application/javascript">
+function* test(testDriver) {
+  SimpleTest.ok(screen.height > 500, "Screen height must be at least 500 pixels for this test to work");
+
+  // This listener will trigger the test to continue once APZ is done with
+  // processing the scroll.
+  SpecialPowers.Services.obs.addObserver(testDriver, "APZ:TransformEnd", false);
+
+  // Scroll down to the iframe. Do it in two drags instead of one in case the
+  // device screen is short
+  yield synthesizeNativeTouchDrag(document.body, 10, 400, 0, -(350 + TOUCH_SLOP));
+  yield synthesizeNativeTouchDrag(document.body, 10, 400, 0, -(350 + TOUCH_SLOP));
+  // Now the top of the visible area should be at y=700 of the top-level page,
+  // so if the screen is >= 500px tall, the entire iframe should be visible, at
+  // least vertically.
+
+  // However, because of the overflow:hidden on the root elements, all this
+  // scrolling is happening in APZ and is not reflected in the main-thread
+  // scroll position (it is stored in the callback transform instead). We check
+  // this by checking the scroll offset.
+  yield flushApzRepaints(testDriver);
+  SimpleTest.is(window.scrollY, 0, "Main-thread scroll position is still at 0");
+
+  // Scroll the iframe by 300px. Note that since the main-thread scroll position
+  // is still 0, the subframe's getBoundingClientRect is going to be off by
+  // 700 pixels, so we compensate for that here.
+  var subframe = document.getElementById('subframe');
+  yield synthesizeNativeTouchDrag(subframe, 10, 200 - 700, 0, -(300 + TOUCH_SLOP));
+
+  // Remove the observer, we don't need it any more.
+  SpecialPowers.Services.obs.removeObserver(testDriver, "APZ:TransformEnd", false);
+
+  // Flush any pending paints
+  yield flushApzRepaints(testDriver);
+
+  // get the displayport for the subframe
+  var utils = SpecialPowers.getDOMWindowUtils(window);
+  var contentPaints = utils.getContentAPZTestData().paints;
+  var lastPaint = convertScrollFrameData(contentPaints[contentPaints.length - 1].scrollFrames);
+  var foundIt = 0;
+  for (var scrollId in lastPaint) {
+    if (('contentDescription' in lastPaint[scrollId]) &&
+        (lastPaint[scrollId]['contentDescription'].includes('tall_html'))) {
+      var dp = getPropertyAsRect(lastPaint, scrollId, 'criticalDisplayport');
+      SimpleTest.ok(dp.y <= 0, 'The critical displayport top should be less than or equal to zero to cover the visible part of the subframe; it is ' + dp.y);
+      SimpleTest.ok(dp.y + dp.h >= subframe.clientHeight, 'The critical displayport bottom should be greater than the clientHeight; it is ' + (dp.y + dp.h));
+      foundIt++;
+    }
+  }
+  SimpleTest.is(foundIt, 1, "Found exactly one critical displayport for the subframe we were interested in.");
+}
+
+waitUntilApzStable()
+.then(runContinuation(test))
+.then(subtestDone);
+
+  </script>
+</head>
+<body style="overflow:hidden">
+  The iframe below is at (0, 800). Scroll it into view, and then scroll the contents. The content should be fully rendered in high-resolution.
+  <iframe id="subframe" style="position:absolute; left: 0px; top: 800px; width: 600px; height: 350px" src="helper_tall.html"></iframe>
+</body>
+</html>
--- a/gfx/layers/apz/test/mochitest/helper_bug982141.html
+++ b/gfx/layers/apz/test/mochitest/helper_bug982141.html
@@ -67,33 +67,24 @@ https://bugzilla.mozilla.org/show_bug.cg
       SimpleTest.is(rcd.children.length, 1, "expected a single child APZC");
       var childScrollId = rcd.children[0].scrollId;
 
       // We should have content-side data for the same paint.
       SimpleTest.ok(lastCompositorPaintSeqNo in contentTestData.paints,
                     "expected a content paint with sequence number" + lastCompositorPaintSeqNo);
       var correspondingContentPaint = contentTestData.paints[lastCompositorPaintSeqNo];
 
-      // This content-side data should have a displayport for our scrollable <div>.
-      SimpleTest.ok(childScrollId in correspondingContentPaint,
-                    "expected scroll frame data for scroll id " + childScrollId);
-      SimpleTest.ok("displayport" in correspondingContentPaint[childScrollId],
-                    "expected a displayport for scroll id " + childScrollId);
-      var childDisplayport = correspondingContentPaint[childScrollId]["displayport"];
-      var dpFields = childDisplayport.replace(/[()\s]+/g, '').split(',');
-      SimpleTest.is(dpFields.length, 4, "expected displayport string of form (x,y,w,h)");
-      var dpWidth = dpFields[2];
-      var dpHeight = dpFields[3];
+      var dp = getPropertyAsRect(correspondingContentPaint, childScrollId, 'displayport');
       var subframe = document.getElementById('subframe');
       // The clientWidth and clientHeight may be less than 50 if there are scrollbars showing.
       // In general they will be (50 - <scrollbarwidth>, 50 - <scrollbarheight>).
       SimpleTest.ok(subframe.clientWidth > 0, "Expected a non-zero clientWidth, got: " + subframe.clientWidth);
       SimpleTest.ok(subframe.clientHeight > 0, "Expected a non-zero clientHeight, got: " + subframe.clientHeight);
-      SimpleTest.ok(dpWidth >= subframe.clientWidth && dpHeight >= subframe.clientHeight,
-                    "expected a displayport at least as large as the scrollable element, got " + childDisplayport);
+      SimpleTest.ok(dp.w >= subframe.clientWidth && dp.h >= subframe.clientHeight,
+                    "expected a displayport at least as large as the scrollable element, got " + JSON.stringify(dp));
 
       window.opener.finishTest();
     }
   </script>
 </head>
 <body style="overflow: hidden;"><!-- This combined with the user-scalable=no ensures the root frame is not scrollable -->
   <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=982141">Mozilla Bug 982141</a>
   <!-- A scrollable subframe, with enough content to make it have a nonzero scroll range -->
new file mode 100644
--- /dev/null
+++ b/gfx/layers/apz/test/mochitest/helper_tall.html
@@ -0,0 +1,504 @@
+<html id="tall_html">
+<body>
+This is a tall page<br/>
+1<br/>
+2<br/>
+3<br/>
+4<br/>
+5<br/>
+6<br/>
+7<br/>
+8<br/>
+9<br/>
+10<br/>
+11<br/>
+12<br/>
+13<br/>
+14<br/>
+15<br/>
+16<br/>
+17<br/>
+18<br/>
+19<br/>
+20<br/>
+21<br/>
+22<br/>
+23<br/>
+24<br/>
+25<br/>
+26<br/>
+27<br/>
+28<br/>
+29<br/>
+30<br/>
+31<br/>
+32<br/>
+33<br/>
+34<br/>
+35<br/>
+36<br/>
+37<br/>
+38<br/>
+39<br/>
+40<br/>
+41<br/>
+42<br/>
+43<br/>
+44<br/>
+45<br/>
+46<br/>
+47<br/>
+48<br/>
+49<br/>
+50<br/>
+51<br/>
+52<br/>
+53<br/>
+54<br/>
+55<br/>
+56<br/>
+57<br/>
+58<br/>
+59<br/>
+60<br/>
+61<br/>
+62<br/>
+63<br/>
+64<br/>
+65<br/>
+66<br/>
+67<br/>
+68<br/>
+69<br/>
+70<br/>
+71<br/>
+72<br/>
+73<br/>
+74<br/>
+75<br/>
+76<br/>
+77<br/>
+78<br/>
+79<br/>
+80<br/>
+81<br/>
+82<br/>
+83<br/>
+84<br/>
+85<br/>
+86<br/>
+87<br/>
+88<br/>
+89<br/>
+90<br/>
+91<br/>
+92<br/>
+93<br/>
+94<br/>
+95<br/>
+96<br/>
+97<br/>
+98<br/>
+99<br/>
+100<br/>
+101<br/>
+102<br/>
+103<br/>
+104<br/>
+105<br/>
+106<br/>
+107<br/>
+108<br/>
+109<br/>
+110<br/>
+111<br/>
+112<br/>
+113<br/>
+114<br/>
+115<br/>
+116<br/>
+117<br/>
+118<br/>
+119<br/>
+120<br/>
+121<br/>
+122<br/>
+123<br/>
+124<br/>
+125<br/>
+126<br/>
+127<br/>
+128<br/>
+129<br/>
+130<br/>
+131<br/>
+132<br/>
+133<br/>
+134<br/>
+135<br/>
+136<br/>
+137<br/>
+138<br/>
+139<br/>
+140<br/>
+141<br/>
+142<br/>
+143<br/>
+144<br/>
+145<br/>
+146<br/>
+147<br/>
+148<br/>
+149<br/>
+150<br/>
+151<br/>
+152<br/>
+153<br/>
+154<br/>
+155<br/>
+156<br/>
+157<br/>
+158<br/>
+159<br/>
+160<br/>
+161<br/>
+162<br/>
+163<br/>
+164<br/>
+165<br/>
+166<br/>
+167<br/>
+168<br/>
+169<br/>
+170<br/>
+171<br/>
+172<br/>
+173<br/>
+174<br/>
+175<br/>
+176<br/>
+177<br/>
+178<br/>
+179<br/>
+180<br/>
+181<br/>
+182<br/>
+183<br/>
+184<br/>
+185<br/>
+186<br/>
+187<br/>
+188<br/>
+189<br/>
+190<br/>
+191<br/>
+192<br/>
+193<br/>
+194<br/>
+195<br/>
+196<br/>
+197<br/>
+198<br/>
+199<br/>
+200<br/>
+201<br/>
+202<br/>
+203<br/>
+204<br/>
+205<br/>
+206<br/>
+207<br/>
+208<br/>
+209<br/>
+210<br/>
+211<br/>
+212<br/>
+213<br/>
+214<br/>
+215<br/>
+216<br/>
+217<br/>
+218<br/>
+219<br/>
+220<br/>
+221<br/>
+222<br/>
+223<br/>
+224<br/>
+225<br/>
+226<br/>
+227<br/>
+228<br/>
+229<br/>
+230<br/>
+231<br/>
+232<br/>
+233<br/>
+234<br/>
+235<br/>
+236<br/>
+237<br/>
+238<br/>
+239<br/>
+240<br/>
+241<br/>
+242<br/>
+243<br/>
+244<br/>
+245<br/>
+246<br/>
+247<br/>
+248<br/>
+249<br/>
+250<br/>
+251<br/>
+252<br/>
+253<br/>
+254<br/>
+255<br/>
+256<br/>
+257<br/>
+258<br/>
+259<br/>
+260<br/>
+261<br/>
+262<br/>
+263<br/>
+264<br/>
+265<br/>
+266<br/>
+267<br/>
+268<br/>
+269<br/>
+270<br/>
+271<br/>
+272<br/>
+273<br/>
+274<br/>
+275<br/>
+276<br/>
+277<br/>
+278<br/>
+279<br/>
+280<br/>
+281<br/>
+282<br/>
+283<br/>
+284<br/>
+285<br/>
+286<br/>
+287<br/>
+288<br/>
+289<br/>
+290<br/>
+291<br/>
+292<br/>
+293<br/>
+294<br/>
+295<br/>
+296<br/>
+297<br/>
+298<br/>
+299<br/>
+300<br/>
+301<br/>
+302<br/>
+303<br/>
+304<br/>
+305<br/>
+306<br/>
+307<br/>
+308<br/>
+309<br/>
+310<br/>
+311<br/>
+312<br/>
+313<br/>
+314<br/>
+315<br/>
+316<br/>
+317<br/>
+318<br/>
+319<br/>
+320<br/>
+321<br/>
+322<br/>
+323<br/>
+324<br/>
+325<br/>
+326<br/>
+327<br/>
+328<br/>
+329<br/>
+330<br/>
+331<br/>
+332<br/>
+333<br/>
+334<br/>
+335<br/>
+336<br/>
+337<br/>
+338<br/>
+339<br/>
+340<br/>
+341<br/>
+342<br/>
+343<br/>
+344<br/>
+345<br/>
+346<br/>
+347<br/>
+348<br/>
+349<br/>
+350<br/>
+351<br/>
+352<br/>
+353<br/>
+354<br/>
+355<br/>
+356<br/>
+357<br/>
+358<br/>
+359<br/>
+360<br/>
+361<br/>
+362<br/>
+363<br/>
+364<br/>
+365<br/>
+366<br/>
+367<br/>
+368<br/>
+369<br/>
+370<br/>
+371<br/>
+372<br/>
+373<br/>
+374<br/>
+375<br/>
+376<br/>
+377<br/>
+378<br/>
+379<br/>
+380<br/>
+381<br/>
+382<br/>
+383<br/>
+384<br/>
+385<br/>
+386<br/>
+387<br/>
+388<br/>
+389<br/>
+390<br/>
+391<br/>
+392<br/>
+393<br/>
+394<br/>
+395<br/>
+396<br/>
+397<br/>
+398<br/>
+399<br/>
+400<br/>
+401<br/>
+402<br/>
+403<br/>
+404<br/>
+405<br/>
+406<br/>
+407<br/>
+408<br/>
+409<br/>
+410<br/>
+411<br/>
+412<br/>
+413<br/>
+414<br/>
+415<br/>
+416<br/>
+417<br/>
+418<br/>
+419<br/>
+420<br/>
+421<br/>
+422<br/>
+423<br/>
+424<br/>
+425<br/>
+426<br/>
+427<br/>
+428<br/>
+429<br/>
+430<br/>
+431<br/>
+432<br/>
+433<br/>
+434<br/>
+435<br/>
+436<br/>
+437<br/>
+438<br/>
+439<br/>
+440<br/>
+441<br/>
+442<br/>
+443<br/>
+444<br/>
+445<br/>
+446<br/>
+447<br/>
+448<br/>
+449<br/>
+450<br/>
+451<br/>
+452<br/>
+453<br/>
+454<br/>
+455<br/>
+456<br/>
+457<br/>
+458<br/>
+459<br/>
+460<br/>
+461<br/>
+462<br/>
+463<br/>
+464<br/>
+465<br/>
+466<br/>
+467<br/>
+468<br/>
+469<br/>
+470<br/>
+471<br/>
+472<br/>
+473<br/>
+474<br/>
+475<br/>
+476<br/>
+477<br/>
+478<br/>
+479<br/>
+480<br/>
+481<br/>
+482<br/>
+483<br/>
+484<br/>
+485<br/>
+486<br/>
+487<br/>
+488<br/>
+489<br/>
+490<br/>
+491<br/>
+492<br/>
+493<br/>
+494<br/>
+495<br/>
+496<br/>
+497<br/>
+498<br/>
+499<br/>
+</body>
+</html>
--- a/gfx/layers/apz/test/mochitest/mochitest.ini
+++ b/gfx/layers/apz/test/mochitest/mochitest.ini
@@ -17,16 +17,18 @@ support-files =
   helper_tap_passive.html
   helper_click.html
   helper_drag_click.html
   helper_bug1271432.html
   helper_touch_action.html
   helper_touch_action_regions.html
   helper_scroll_inactive_perspective.html
   helper_scroll_inactive_zindex.html
+  helper_bug1280013.html
+  helper_tall.html
 tags = apz
 [test_bug982141.html]
 [test_bug1151663.html]
 [test_bug1277814.html]
 skip-if = (os == 'android') || (os == 'b2g') || (buildapp == 'mulet') # wheel events not supported on mobile; see bug 1164274 for mulet
 [test_wheel_scroll.html]
 skip-if = (os == 'android') || (os == 'b2g') || (buildapp == 'mulet') # wheel events not supported on mobile; see bug 1164274 for mulet
 [test_wheel_transactions.html]
@@ -46,8 +48,10 @@ skip-if = (os == 'android') || (os == 'b
 # Windows touch injection doesn't work in automation, but this test can be run locally on a windows touch device.
 # On OS X we don't support touch events at all.
 skip-if = (toolkit == 'windows') || (toolkit == 'cocoa')
 [test_group_wheelevents.html]
 skip-if = (toolkit == 'android') # wheel events not supported on mobile
 [test_group_mouseevents.html]
 [test_touch_listeners_impacting_wheel.html]
 skip-if = (toolkit == 'android') || (toolkit == 'cocoa') # wheel events not supported on mobile, and synthesized wheel smooth-scrolling not supported on OS X
+[test_group_zoom.html]
+skip-if = (toolkit != 'android') # only android supports zoom
new file mode 100644
--- /dev/null
+++ b/gfx/layers/apz/test/mochitest/test_group_zoom.html
@@ -0,0 +1,44 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>Various zoom-related tests that spawn in new windows</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="application/javascript" src="apz_test_utils.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+  <script type="application/javascript">
+
+var prefs = [
+  // We need the APZ paint logging information
+  ["apz.test.logging_enabled", true],
+  // Dropping the touch slop to 0 makes the tests easier to write because
+  // we can just do a one-pixel drag to get over the pan threshold rather
+  // than having to hard-code some larger value.
+  ["apz.touch_start_tolerance", "0.0"],
+  // The subtests in this test do touch-drags to pan the page, but we don't
+  // want those pans to turn into fling animations, so we increase the
+  // fling-stop threshold velocity to absurdly high.
+  ["apz.fling_stopped_threshold", "10000"],
+  // The helper_bug1280013's div gets a displayport on scroll, but if the
+  // test takes too long the displayport can expire before we read the value
+  // out of the test. So we disable displayport expiry for these tests.
+  ["apz.displayport_expiry_ms", 0],
+];
+
+var subtests = [
+  {'file': 'helper_bug1280013.html', 'prefs': prefs},
+];
+
+if (isApzEnabled()) {
+  SimpleTest.waitForExplicitFinish();
+  window.onload = function() {
+    runSubtestsSeriallyInFreshWindows(subtests)
+    .then(SimpleTest.finish);
+  };
+}
+
+  </script>
+</head>
+<body>
+</body>
+</html>
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -8859,16 +8859,18 @@ nsLayoutUtils::ComputeScrollMetadata(nsI
     nsRect dp;
     if (nsLayoutUtils::GetDisplayPort(aContent, &dp)) {
       metrics.SetDisplayPort(CSSRect::FromAppUnits(dp));
       nsLayoutUtils::LogTestDataForPaint(aLayer->Manager(), scrollId, "displayport",
           metrics.GetDisplayPort());
     }
     if (nsLayoutUtils::GetCriticalDisplayPort(aContent, &dp)) {
       metrics.SetCriticalDisplayPort(CSSRect::FromAppUnits(dp));
+      nsLayoutUtils::LogTestDataForPaint(aLayer->Manager(), scrollId,
+          "criticalDisplayport", metrics.GetCriticalDisplayPort());
     }
     DisplayPortMarginsPropertyData* marginsData =
         static_cast<DisplayPortMarginsPropertyData*>(aContent->GetProperty(nsGkAtoms::DisplayPortMargins));
     if (marginsData) {
       metrics.SetDisplayPortMargins(marginsData->mMargins);
     }
   }