chromium/third_party/blink/web_tests/external/wpt/dom/events/scrolling/scrollend-event-fired-for-programmatic-scroll.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="/common/subset-tests-by-key.js"></script>
<meta name="variant" content="?include=subframe-scrollTo-auto"/>
<meta name="variant" content="?include=subframe-scrollTo-smooth"/>
<meta name="variant" content="?include=subframe-scrollBy-auto"/>
<meta name="variant" content="?include=subframe-scrollBy-smooth"/>
<meta name="variant" content="?include=root-scrollTo-auto"/>
<meta name="variant" content="?include=root-scrollTo-smooth"/>
<meta name="variant" content="?include=root-scrollBy-auto"/>
<meta name="variant" content="?include=root-scrollBy-smooth"/>
<script src="scroll_support.js"></script>
<style>
html {
  height: 3000px;
  width: 3000px;
}
#targetDiv {
  width: 200px;
  height: 200px;
  overflow: scroll;
}

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

<body style="margin:0" onload=runTest()>
<div id="targetDiv">
  <div id="innerDiv">
  </div>
</div>
</body>
<script>
let element_scrollend_arrived = false;
let document_scrollend_arrived = false;

function onElementScrollEnd(event) {
  assert_false(event.cancelable);
  assert_false(event.bubbles);
  element_scrollend_arrived = true;
}

function onDocumentScrollEnd(event) {
  assert_false(event.cancelable);
  // scrollend events are bubbled when the target node is document.
  assert_true(event.bubbles);
  document_scrollend_arrived = true;
}

let scroll_fn_variants = [
  {
    key: "subframe-scrollTo-auto",
    target: targetDiv,
    fn: "scrollTo",
    behavior: "auto",
    title: "Tests scrollend event for calling scrollTo with behavior 'auto' on subframe."
  },
  {
    key: "subframe-scrollTo-smooth",
    target: targetDiv,
    fn: "scrollTo",
    behavior: "smooth",
    title: "Tests scrollend event for calling scrollTo with behavior 'smooth' on subframe."
  },
  {
    key: "subframe-scrollBy-auto",
    target: targetDiv,
    fn: "scrollBy",
    behavior: "auto",
    title: "Tests scrollend event for calling scrollBy with behavior 'auto' on subframe."
  },
  {
    key: "subframe-scrollBy-smooth",
    target: targetDiv,
    fn: "scrollBy",
    behavior: "smooth",
    title: "Tests scrollend event for calling scrollBy with behavior 'smooth' on subframe."
  },
  {
    key: "root-scrollTo-auto",
    target: document.scrollingElement,
    fn: "scrollTo",
    behavior: "auto",
    title: "Tests scrollend event for calling scrollTo with behavior 'auto' on root."
  },
  {
    key: "root-scrollTo-smooth",
    target: document.scrollingElement,
    fn: "scrollTo",
    behavior: "smooth",
    title: "Tests scrollend event for calling scrollTo with behavior 'smooth' on root."
  },
  {
    key: "root-scrollBy-auto",
    target: document.scrollingElement,
    fn: "scrollBy",
    behavior: "auto",
    title: "Tests scrollend event for calling scrollBy with behavior 'auto' on root."
  },
  {
    key: "root-scrollBy-smooth",
    target: document.scrollingElement,
    fn: "scrollBy",
    behavior: "smooth",
    title: "Tests scrollend event for calling scrollBy with behavior 'smooth' on root."
  },
];

function runTest() {

  async function testScrollFn(testInfo, t) {
    await waitForCompositorCommit();

    targetDiv.addEventListener("scrollend", onElementScrollEnd);
    document.addEventListener("scrollend", onDocumentScrollEnd);

    testInfo.target[testInfo.fn]({ top: 200, left: 200,
                                   behavior: testInfo.behavior });

    await waitFor(() => {
      return element_scrollend_arrived || document_scrollend_arrived;
    }, testInfo.target.tagName + "." + testInfo.fn + " did not receive scrollend event.");
    if (testInfo.target == document.scrollingElement) {
      assert_false(element_scrollend_arrived);
    } else {
      assert_false(document_scrollend_arrived);
    }

    assert_equals(testInfo.target.scrollLeft, 200,
                  testInfo.target.tagName + "." + testInfo.fn + " scrollLeft");
    assert_equals(testInfo.target.scrollTop, 200,
                  testInfo.target.tagName + "." + testInfo.fn + " scrollTop");
  }

  scroll_fn_variants.forEach((testInfo) => {
    subsetTestByKey(testInfo.key, promise_test,
                    async (t) => testScrollFn(testInfo, t), testInfo.title);
  });

}
</script>