chromium/third_party/blink/web_tests/external/wpt/dom/events/scrolling/scrollend-event-fired-after-sequence-of-scrolls.tentative.html

<!DOCTYPE HTML>
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-actions.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script src="scroll_support.js"></script>
<style>
#targetDiv {
  width: 200px;
  height: 200px;
  overflow: scroll;
}

#innerDiv {
  width: 4000px;
  height: 4000px;
}
</style>

<body style="margin:0" onload=runTest()>
<div id="targetDiv">
  <div id="innerDiv">
  </div>
</div>
</body>

<script>
const target_div = document.getElementById('targetDiv');

async function testWithMovePath(t, move_path) {
  // Skip the test on a Mac as they do not support touch screens.
  const isMac = navigator.platform.toUpperCase().indexOf('MAC')>=0;
  if (isMac)
    return;

  await resetTargetScrollState(t, target_div);
  await waitForCompositorReady();

  verifyNoScrollendOnDocument(t);

  let scrollend_count = 0;
  const scrollend_listener = () => { scrollend_count += 1; };
  target_div.addEventListener("scrollend", scrollend_listener);
  t.add_cleanup(() => { target_div.removeEventListener('scrollend', scrollend_listener); });

  const pointercancel_listener = () => {
    assert_equals(scrollend_count, 0, 'scrollend should happen after pointercancel.');
  };
  target_div.addEventListener("pointercancel", pointercancel_listener);
  t.add_cleanup(() => { target_div.removeEventListener('pointercancel', pointercancel_listener); });

  // Because we have several pointer moves, we choose bigger timeout.
  const timeoutMs = 3000;
  const targetPointercancelPromise = waitForPointercancelEvent(t, target_div, timeoutMs);
  const targetScrollendPromise = createScrollendPromiseForTarget(t, target_div, timeoutMs);

  await touchScrollInTargetSequentiallyWithPause(target_div, move_path);

  // Because we start scrolling after pointerdown, there is no pointerup, instead the target
  // will receive a pointercancel, so we wait for pointercancel, and then continue.
  await targetPointercancelPromise;
  await targetScrollendPromise;
  await verifyScrollStopped(t, target_div);
  assert_equals(scrollend_count, 1, 'Only one scrollend event should be fired');
}

function runTest() {
  promise_test (async (t) => {
    // Scroll down & up & down on target div and wait for the target_div to get scrollend event.
    const move_path = [
      { x: 0, y: -80 }, // Scroll down
      { x: 0, y: -40 }, // Scroll up
      { x: 0, y: -80 }, // Scroll down
    ];
    await testWithMovePath(t, move_path);
  }, "Move down, up and down again, receive scrollend event only once");

  promise_test (async (t) => {
    // Scroll right & left & right on target div and wait for the target_div to get scrollend event.
    const move_path = [
      { x: -80, y: 0 }, // Scroll right
      { x: -40, y: 0 }, // Scroll left
      { x: -80, y: 0 }, // Scroll right
    ];
    await testWithMovePath(t, move_path);
  }, "Move right, left and right again, receive scrollend event only once");

}
</script>