1<!DOCTYPE html> 2<html> 3<head> 4 <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1"> 5<script src="/resources/testharness.js"></script> 6<script src="/resources/testharnessreport.js"></script> 7<script src="/resources/testdriver.js"></script> 8<script src="/resources/testdriver-actions.js"></script> 9<script src="/resources/testdriver-vendor.js"></script> 10<script src="scroll_support.js"></script> 11<style> 12 #targetDiv { 13 width: 200px; 14 height: 200px; 15 overflow: scroll; 16 } 17 18 #innerDiv { 19 width: 400px; 20 height: 400px; 21 } 22</style> 23</head> 24<body style="margin:0" onload=runTest()> 25 <div id="targetDiv"> 26 <div id="innerDiv"> 27 </div> 28 </div> 29</body> 30 31<script> 32var target_div = document.getElementById('targetDiv'); 33 34async function resetTargetScrollState(test) { 35 if (target_div.scrollTop != 0 || target_div.scrollLeft != 0) { 36 target_div.scrollTop = 0; 37 target_div.scrollLeft = 0; 38 return waitForScrollendEvent(test, target_div); 39 } 40} 41 42async function verifyScrollStopped(test) { 43 const unscaled_pause_time_in_ms = 100; 44 const x = target_div.scrollLeft; 45 const y = target_div.scrollTop; 46 return new Promise(resolve => { 47 test.step_timeout(() => { 48 assert_equals(x, target_div.scrollLeft); 49 assert_equals(y, target_div.scrollTop); 50 resolve(); 51 }, unscaled_pause_time_in_ms); 52 }); 53} 54 55async function verifyNoScrollendOnDocument(test) { 56 const callback = 57 test.unreached_func("window got unexpected scrollend event."); 58 window.addEventListener('scrollend', callback); 59} 60 61async function createScrollendPromise(test) { 62 return waitForScrollendEvent(test, target_div).then(evt => { 63 assert_false(evt.cancelable, 'Event is not cancelable'); 64 assert_false(evt.bubbles, 'Event targeting element does not bubble'); 65 }); 66} 67 68function runTest() { 69 promise_test(async (t) => { 70 // Skip the test on a Mac as they do not support touch screens. 71 const isMac = navigator.platform.toUpperCase().indexOf('MAC')>=0; 72 if (isMac) 73 return; 74 75 await resetTargetScrollState(t); 76 await waitForCompositorCommit(); 77 78 const targetScrollendPromise = createScrollendPromise(t); 79 verifyNoScrollendOnDocument(t); 80 81 // Perform a touch drag on target div and wait for target_div to get 82 // a scrollend event. 83 await new test_driver.Actions() 84 .addPointer('TestPointer', 'touch') 85 .pointerMove(0, 0, {origin: target_div}) // 0, 0 is center of element. 86 .pointerDown() 87 .addTick() 88 .pointerMove(0, -40, {origin: target_div}) // Drag up to move down. 89 .addTick() 90 .pause(200) // Prevent inertial scroll. 91 .pointerUp() 92 .send(); 93 94 await targetScrollendPromise; 95 96 assert_true(target_div.scrollTop > 0); 97 await verifyScrollStopped(t); 98 }, 'Tests that the target_div gets scrollend event when touch dragging.'); 99 100 promise_test(async (t) => { 101 // Skip test on platforms that do not have a visible scrollbar (e.g. 102 // overlay scrollbar). 103 const scrollbar_width = target_div.offsetWidth - target_div.clientWidth; 104 if (scrollbar_width == 0) 105 return; 106 107 await resetTargetScrollState(t); 108 await waitForCompositorCommit(); 109 110 const targetScrollendPromise = createScrollendPromise(t); 111 verifyNoScrollendOnDocument(t); 112 113 const bounds = target_div.getBoundingClientRect(); 114 const x = bounds.right - scrollbar_width / 2; 115 const y = bounds.bottom - 20; 116 await new test_driver.Actions() 117 .addPointer('TestPointer', 'mouse') 118 .pointerMove(x, y, {origin: 'viewport'}) 119 .pointerDown() 120 .addTick() 121 .pointerUp() 122 .send(); 123 124 await targetScrollendPromise; 125 assert_true(target_div.scrollTop > 0); 126 await verifyScrollStopped(t); 127 }, 'Tests that the target_div gets scrollend event when clicking ' + 128 'scrollbar.'); 129 130 // Same issue as previous test. 131 promise_test(async (t) => { 132 // Skip test on platforms that do not have a visible scrollbar (e.g. 133 // overlay scrollbar). 134 const scrollbar_width = target_div.offsetWidth - target_div.clientWidth; 135 if (scrollbar_width == 0) 136 return; 137 138 resetTargetScrollState(t); 139 const targetScrollendPromise = createScrollendPromise(t); 140 verifyNoScrollendOnDocument(t); 141 142 const bounds = target_div.getBoundingClientRect(); 143 const x = bounds.right - scrollbar_width / 2; 144 const y = bounds.top + 30; 145 const dy = 30; 146 await new test_driver.Actions() 147 .addPointer('TestPointer', 'mouse') 148 .pointerMove(x, y, { origin: 'viewport' }) 149 .pointerDown() 150 .pointerMove(x, y + dy, { origin: 'viewport' }) 151 .addTick() 152 .pointerUp() 153 .send(); 154 155 await targetScrollendPromise; 156 assert_true(target_div.scrollTop > 0); 157 await verifyScrollStopped(t); 158 }, 'Tests that the target_div gets scrollend event when dragging the ' + 159 'scrollbar thumb.'); 160 161 promise_test(async (t) => { 162 resetTargetScrollState(t); 163 const targetScrollendPromise = createScrollendPromise(t); 164 verifyNoScrollendOnDocument(t); 165 166 const x = 0; 167 const y = 0; 168 const dx = 0; 169 const dy = 40; 170 const duration_ms = 10; 171 await new test_driver.Actions() 172 .scroll(x, y, dx, dy, { origin: target_div }, duration_ms) 173 .send(); 174 175 await targetScrollendPromise; 176 assert_true(target_div.scrollTop > 0); 177 await verifyScrollStopped(t); 178 }, 'Tests that the target_div gets scrollend event when mouse wheel ' + 179 'scrolling.'); 180 181 promise_test(async (t) => { 182 await resetTargetScrollState(t); 183 await waitForCompositorCommit(); 184 185 verifyNoScrollendOnDocument(t); 186 const targetScrollendPromise = createScrollendPromise(t); 187 188 target_div.focus(); 189 window.test_driver.send_keys(target_div, '\ue015'); 190 191 await targetScrollendPromise; 192 assert_true(target_div.scrollTop > 0); 193 await verifyScrollStopped(t); 194 }, 'Tests that the target_div gets scrollend event when sending DOWN key ' + 195 'to the target.'); 196} 197 198</script> 199</html> 200