1<!DOCTYPE html>
2<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1">
3<script src="/resources/testharness.js"></script>
4<script src="/resources/testharnessreport.js"></script>
5<script src="/resources/testdriver.js"></script>
6<script src="/resources/testdriver-actions.js"></script>
7<script src="/resources/testdriver-vendor.js"></script>
8<script src="scroll_support.js"></script>
9<style>
10div {
11  position: absolute;
12}
13#scroller {
14  width: 500px;
15  height: 500px;
16  overflow: scroll;
17  scroll-snap-type: both mandatory;
18  border: solid black 5px;
19}
20#space {
21  width: 2000px;
22  height: 2000px;
23}
24.target {
25  width: 200px;
26  height: 200px;
27  scroll-snap-align: start;
28  background-color: blue;
29}
30</style>
31
32<body style="margin:0" onload=runTests()>
33  <div id="scroller">
34    <div id="space"></div>
35    <div class="target" style="left: 0px; top: 0px;"></div>
36    <div class="target" style="left: 80px; top: 80px;"></div>
37    <div class="target" style="left: 200px; top: 200px;"></div>
38  </div>
39</body>
40
41<script>
42var scroller = document.getElementById("scroller");
43var space = document.getElementById("space");
44const MAX_FRAME_COUNT = 700;
45const MAX_UNCHANGED_FRAME = 20;
46
47function scrollTop() {
48  return scroller.scrollTop;
49}
50
51var scroll_arrived_after_scroll_end = false;
52var scroll_end_arrived = false;
53scroller.addEventListener("scroll", () => {
54  if (scroll_end_arrived)
55    scroll_arrived_after_scroll_end = true;
56});
57scroller.addEventListener("scrollend", () => {
58  scroll_end_arrived = true;
59});
60
61function runTests() {
62  promise_test (async () => {
63    await waitForCompositorCommit();
64    await touchScrollInTarget(100, scroller, 'down');
65    // Wait for the scroll snap animation to finish.
66    await waitForAnimationEnd(scrollTop);
67    await waitFor(() => { return scroll_end_arrived; });
68    // Verify that scroll snap animation has finished before firing scrollend event.
69    assert_false(scroll_arrived_after_scroll_end);
70  }, "Tests that scrollend is fired after scroll snap animation completion.");
71
72  promise_test (async () => {
73    // Reset scroll state.
74    scroller.scrollTo(0, 0);
75    await waitForCompositorCommit();
76    scroll_end_arrived = false;
77    scroll_arrived_after_scroll_end = false;
78
79    await touchFlingInTarget(50, scroller, 'down');
80    // Wait for the scroll snap animation to finish.
81    await waitForAnimationEnd(scrollTop);
82    await waitFor(() => { return scroll_end_arrived; });
83    // Verify that scroll snap animation has finished before firing scrollend event.
84    assert_false(scroll_arrived_after_scroll_end);
85  }, "Tests that scrollend is fired after fling snap animation completion.");
86}
87</script>
88