chromium/third_party/blink/web_tests/fast/events/touch/gesture/touch-gesture-scroll-page-past-extent.html

<!DOCTYPE html>
<script src="../../../../resources/testharness.js"></script>
<script src="../../../../resources/testharnessreport.js"></script>
<script src="../../../../resources/gesture-util.js"></script>
<style type="text/css">
::-webkit-scrollbar {
  width: 0px;
  height: 0px;
}

#greenbox {
  width: 100px;
  height: 100px;
  background: green;
  padding: 0px;
  margin: 0px;
}

#redbox {
  width: 100px;
  height: 100px;
  background: red;
  padding: 0px;
  margin: 0px;
}

#bluebox {
  width: 100px;
  height: 100px;
  background: blue;
  padding: 0px;
  margin: 0px;
}

#yellowbox {
  width: 100px;
  height: 100px;
  background: yellow;
  padding: 0px;
  margin: 0px;
}

#touchtargetdiv {
  width: 200px;
  height: 200px;
  overflow-y: scroll;
  overflow-x: scroll;
}

td {
  padding: 0px;
}
</style>

<body style="margin:0" onload="buildPage();">
<div id="touchtargetdiv">
  <table border="0" cellspacing="0px" >
    <tr><td><div id="yellowbox"></div></td></tr>
    <tr><td><div id="bluebox"></div></td></tr>
    <tr><td><div id="yellowbox"></div></td></tr>
    <tr><td><div id="bluebox"></div></td></tr>
  </table>
</div>

<table id="table_to_fill" border="0" cellspacing="0px">
  <tr><td><div id="greenbox"></div></td></tr>
  <tr><td><div id="redbox"></div></td></tr>
</table>
</body>

<script type="text/javascript">
var movingDiv = document.getElementById('touchtargetdiv');

// Always construct a page larger than the vertical height of the window.
function buildPage() {
  var table = document.getElementById('table_to_fill');
  var targetHeight = document.body.offsetHeight;
  var cellPairHeight = table.offsetHeight;
  var numberOfReps = targetHeight / cellPairHeight * 2;
  var i;
  for (i = 0; i < numberOfReps; i++) {
    var p = document.createElement('tr');
    p.innerHTML = '<td><div id="greenbox"></div></td>';
    table.appendChild(p);
    var p = document.createElement('tr');
    p.innerHTML = '<td><div id="redbox"></div></td>';
    table.appendChild(p);
  }
}

function firstGestureScroll() {
  var x = 10;
  var y = 72;
  return smoothScroll(110, x, y, GestureSourceType.TOUCH_INPUT, "down",
      SPEED_INSTANT);
}

function secondGestureScroll() {
  var x = 12;
  var y = 40;
  return smoothScroll(360, x, y, GestureSourceType.TOUCH_INPUT, "down",
      SPEED_INSTANT);
}

promise_test (async () => {
  await firstGestureScroll();
  await waitFor(() => {
      return approx_equals(110, movingDiv.scrollTop, 2);
  });
  await secondGestureScroll();
  var expectedScrollTop = movingDiv.scrollHeight - movingDiv.clientHeight;
  await waitFor(() => {
      return approx_equals(expectedScrollTop, movingDiv.scrollTop, 2);
  });
  // Wait for 100 RAFs to make sure the scroll does not propagate to the main
  // frame.
  await conditionHolds(() => {
      return document.scrollingElement.scrollTop == 0;
  });
}, 'This tests that a gesture scroll isn\'t propagated from a div ' + 
   'to the page when the div has no remaining scroll offset.');
</script>