Bug 1729735 [wpt PR 30400] - Update scroll-animation tests to be independent of scrol...
[gecko.git] / testing / web-platform / tests / scroll-animations / current-time.html
blobed3ed49eef78247c23885dddfed43901e3aa959b
1 <!DOCTYPE html>
2 <meta charset="utf-8">
3 <title>ScrollTimeline current time algorithm</title>
4 <link rel="help" href="https://wicg.github.io/scroll-animations/#current-time-algorithm">
5 <script src="/resources/testharness.js"></script>
6 <script src="/resources/testharnessreport.js"></script>
7 <script src="/web-animations/testcommon.js"></script>
8 <script src="./testcommon.js"></script>
10 <body></body>
12 <script>
13 'use strict';
15 promise_test(async t => {
16 const scroller = setupScrollTimelineTest();
17 const scrollTimeline = new ScrollTimeline({ scrollSource: scroller });
19 assert_equals(scrollTimeline.duration.unit, "percent",
20 "duration returns as a percent for scroll timelines");
21 assert_equals(scrollTimeline.duration.value, 100, "duration is 100%");
22 }, "Scroll timeline correctly returns duration as 100%");
24 promise_test(async t => {
25 const scroller = setupScrollTimelineTest();
26 const scrollerSize = scroller.scrollHeight - scroller.clientHeight;
28 const blockScrollTimeline = new ScrollTimeline({
29 scrollSource: scroller,
30 orientation: 'block'
31 });
32 const inlineScrollTimeline = new ScrollTimeline({
33 scrollSource: scroller,
34 orientation: 'inline'
35 });
36 const horizontalScrollTimeline = new ScrollTimeline({
37 scrollSource: scroller,
38 orientation: 'horizontal'
39 });
40 const verticalScrollTimeline = new ScrollTimeline({
41 scrollSource: scroller,
42 orientation: 'vertical'
43 });
45 // Unscrolled, all timelines should read a currentTime of 0.
46 assert_percents_equal(blockScrollTimeline.currentTime, 0,
47 'Unscrolled block timeline');
48 assert_percents_equal(inlineScrollTimeline.currentTime, 0,
49 'Unscrolled inline timeline');
50 assert_percents_equal(horizontalScrollTimeline.currentTime, 0,
51 'Unscrolled horizontal timeline');
52 assert_percents_equal(verticalScrollTimeline.currentTime, 0,
53 'Unscrolled vertical timeline');
55 // Do some scrolling and make sure that the ScrollTimelines update.
56 scroller.scrollTop = 50;
57 scroller.scrollLeft = 75;
58 // Wait for new animation frame which allows the timeline to compute new
59 // current time.
60 await waitForNextFrame();
62 const inlineScrollRange = scroller.scrollWidth - scroller.clientWidth;
63 const expectedInlineCurrentTime =
64 100 * scroller.scrollLeft / inlineScrollRange;
66 const blockScrollRange = scroller.scrollHeight - scroller.clientHeight;
67 const expectedBlockCurrentTime =
68 100 * scroller.scrollTop / blockScrollRange;
70 assert_percents_approx_equal(blockScrollTimeline.currentTime,
71 expectedBlockCurrentTime,
72 blockScrollRange,
73 'Scrolled block timeline');
74 assert_percents_approx_equal(inlineScrollTimeline.currentTime,
75 expectedInlineCurrentTime,
76 inlineScrollRange,
77 'Scrolled inline timeline');
78 assert_percents_approx_equal(horizontalScrollTimeline.currentTime,
79 expectedInlineCurrentTime,
80 inlineScrollRange,
81 'Scrolled horizontal timeline');
82 assert_percents_approx_equal(verticalScrollTimeline.currentTime,
83 expectedBlockCurrentTime,
84 blockScrollRange,
85 'Scrolled vertical timeline');
86 }, 'currentTime calculates the correct time based on scroll progress');
89 promise_test(async t => {
90 const scroller = setupScrollTimelineTest();
91 const scrollerSize = scroller.scrollHeight - scroller.clientHeight;
93 const lengthScrollTimeline = new ScrollTimeline({
94 scrollSource: scroller,
95 orientation: 'block',
96 scrollOffsets: [CSS.px(20), 'auto']
97 });
98 const percentageScrollTimeline = new ScrollTimeline({
99 scrollSource: scroller,
100 orientation: 'block',
101 scrollOffsets: [CSS.percent(20), 'auto']
103 const calcScrollTimeline = new ScrollTimeline({
104 scrollSource: scroller,
105 orientation: 'block',
106 scrollOffsets: [CSS.percent(20).sub(CSS.px(5)), 'auto']
109 // Unscrolled all timelines should read a current time of 0, as the
110 // current offset (0) will be less than the startScrollOffset.
111 assert_percents_equal(lengthScrollTimeline.currentTime, 0,
112 'Unscrolled length-based timeline current time');
113 assert_equals(lengthScrollTimeline.phase, "before",
114 'Unscrolled length-based timeline phase');
115 assert_percents_equal(percentageScrollTimeline.currentTime, 0,
116 'Unscrolled percentage-based timeline current time');
117 assert_equals(percentageScrollTimeline.phase, "before",
118 'Unscrolled percentage-based timeline phase');
119 assert_percents_equal(calcScrollTimeline.currentTime, 0,
120 'Unscrolled calc-based timeline current time');
121 assert_equals(calcScrollTimeline.phase, "before",
122 'Unscrolled calc-based timeline phase');
124 // Check the length-based ScrollTimeline.
125 scroller.scrollTop = 19;
126 // Wait for new animation frame which allows the timeline to compute new
127 // current time.
128 await waitForNextFrame();
129 assert_percents_equal(lengthScrollTimeline.currentTime, 0,
130 'Length-based timeline current time before the startScrollOffset point');
131 assert_equals(lengthScrollTimeline.phase, "before",
132 'Length-based timeline phase before the startScrollOffset point');
133 scroller.scrollTop = 20;
134 await waitForNextFrame();
135 assert_percents_equal(lengthScrollTimeline.currentTime, 0,
136 'Length-based timeline current time at the startScrollOffset point');
137 assert_equals(lengthScrollTimeline.phase, "active",
138 'Length-based timeline phase at the startScrollOffset point');
139 scroller.scrollTop = 50;
140 await waitForNextFrame();
141 assert_percents_equal(
142 lengthScrollTimeline.currentTime,
143 calculateCurrentTime(50, 20, scrollerSize),
144 'Length-based timeline current time after the startScrollOffset point');
145 assert_equals(lengthScrollTimeline.phase, "active",
146 'Length-based timeline phase after the startScrollOffset point');
148 // Check the percentage-based ScrollTimeline.
149 scroller.scrollTop = 0.19 * scrollerSize;
150 await waitForNextFrame();
151 assert_percents_equal(percentageScrollTimeline.currentTime, 0,
152 'Percentage-based timeline current time before the startScrollOffset ' +
153 'point');
154 assert_equals(percentageScrollTimeline.phase, "before",
155 'Percentage-based timeline phase before the startScrollOffset point');
156 scroller.scrollTop = 0.20 * scrollerSize;
157 await waitForNextFrame();
158 assert_percents_equal(percentageScrollTimeline.currentTime, 0,
159 'Percentage-based timeline current time at the startScrollOffset point');
160 assert_equals(percentageScrollTimeline.phase, "active",
161 'Percentage-based timeline phase at the startScrollOffset point');
162 scroller.scrollTop = 0.50 * scrollerSize;
163 await waitForNextFrame();
164 assert_percents_equal(
165 percentageScrollTimeline.currentTime,
166 calculateCurrentTime(
167 scroller.scrollTop, 0.2 * scrollerSize, scrollerSize),
168 'Percentage-based timeline current time after the startScrollOffset ' +
169 'point');
170 assert_equals(percentageScrollTimeline.phase, "active",
171 'Percentage-based timeline phase after the startScrollOffset point');
173 // Check the calc-based ScrollTimeline.
174 scroller.scrollTop = 0.2 * scrollerSize - 10;
175 await waitForNextFrame();
176 assert_percents_equal(calcScrollTimeline.currentTime, 0,
177 'Calc-based timeline current time before the startScrollOffset point');
178 assert_equals(calcScrollTimeline.phase, "before",
179 'Calc-based timeline phase at the startScrollOffset point');
180 scroller.scrollTop = 0.2 * scrollerSize - 5;
181 await waitForNextFrame();
182 assert_percents_equal(calcScrollTimeline.currentTime, 0,
183 'Calc-based timeline current time at the startScrollOffset point');
184 assert_equals(calcScrollTimeline.phase, "active",
185 'Calc-based timeline phase at the startScrollOffset point');
186 scroller.scrollTop = 0.2 * scrollerSize;
187 await waitForNextFrame();
188 assert_percents_equal(
189 calcScrollTimeline.currentTime,
190 calculateCurrentTime(
191 scroller.scrollTop, 0.2 * scrollerSize - 5, scrollerSize),
192 'Calc-based timeline current time after the startScrollOffset point');
193 assert_equals(calcScrollTimeline.phase, "active",
194 'Calc-based timeline phase at the startScrollOffset point');
195 }, 'currentTime handles startScrollOffset correctly');
197 promise_test(async t => {
198 const scroller = setupScrollTimelineTest();
199 const scrollerSize = scroller.scrollHeight - scroller.clientHeight;
201 // When the endScrollOffset is equal to the maximum scroll offset (and there
202 // are no fill modes), the endScrollOffset is treated as inclusive.
203 const inclusiveAutoScrollTimeline = new ScrollTimeline({
204 scrollSource: scroller,
205 orientation: 'block',
207 const inclusiveLengthScrollTimeline = new ScrollTimeline({
208 scrollSource: scroller,
209 orientation: 'block',
210 scrollOffsets: [CSS.px(scrollerSize)]
212 const inclusivePercentageScrollTimeline = new ScrollTimeline({
213 scrollSource: scroller,
214 orientation: 'block',
215 scrollOffsets: [CSS.percent(100)]
217 const inclusiveCalcScrollTimeline = new ScrollTimeline({
218 scrollSource: scroller,
219 orientation: 'block',
220 scrollOffsets: [CSS.percent(80).add(CSS.px(0.2 * scrollerSize))]
223 scroller.scrollTop = scrollerSize;
224 let expectedCurrentTime = calculateCurrentTime(
225 scroller.scrollTop, 0, scrollerSize);
227 // Wait for new animation frame which allows the timeline to compute new
228 // current time.
229 await waitForNextFrame();
231 assert_percents_equal(
232 inclusiveAutoScrollTimeline.currentTime, expectedCurrentTime,
233 'Inclusive auto timeline at the endScrollOffset point');
234 assert_percents_equal(
235 inclusiveLengthScrollTimeline.currentTime, expectedCurrentTime,
236 'Inclusive length-based timeline at the endScrollOffset point');
237 assert_percents_equal(
238 inclusivePercentageScrollTimeline.currentTime, expectedCurrentTime,
239 'Inclusive percentage-based timeline at the endScrollOffset point');
240 assert_percents_equal(
241 inclusiveCalcScrollTimeline.currentTime, expectedCurrentTime,
242 'Inclusive calc-based timeline at the endScrollOffset point');
243 }, 'currentTime handles endScrollOffset correctly (inclusive cases)');
245 promise_test(async t => {
246 const scroller = setupScrollTimelineTest();
247 const scrollerSize = scroller.scrollHeight - scroller.clientHeight;
249 const lengthScrollTimeline = new ScrollTimeline({
250 scrollSource: scroller,
251 orientation: 'block',
252 scrollOffsets: [CSS.px(scrollerSize - 20)]
254 const percentageScrollTimeline = new ScrollTimeline({
255 scrollSource: scroller,
256 orientation: 'block',
257 scrollOffsets: [CSS.percent(80)]
259 const calcScrollTimeline = new ScrollTimeline({
260 scrollSource: scroller,
261 orientation: 'block',
262 scrollOffsets: [CSS.percent(80).add(CSS.px(5))]
265 // Check the length-based ScrollTimeline.
266 scroller.scrollTop = scrollerSize;
267 // Wait for new animation frame which allows the timeline to compute new
268 // current time.
269 await waitForNextFrame();
270 assert_percents_equal(lengthScrollTimeline.currentTime, 100,
271 'Length-based timeline current time after the endScrollOffset point');
272 assert_equals(lengthScrollTimeline.phase, "after",
273 'Length-based timeline phase after the endScrollOffset point');
274 scroller.scrollTop = scrollerSize - 20;
275 await waitForNextFrame();
276 assert_percents_equal(lengthScrollTimeline.currentTime, 100,
277 'Length-based timeline current time at the endScrollOffset point');
278 assert_equals(lengthScrollTimeline.phase, "after",
279 'Length-based timeline phase at the endScrollOffset point');
280 scroller.scrollTop = scrollerSize - 50;
281 await waitForNextFrame();
282 assert_percents_equal(
283 lengthScrollTimeline.currentTime,
284 calculateCurrentTime(scrollerSize - 50, 0, scrollerSize - 20),
285 'Length-based timeline current time before the endScrollOffset point');
286 assert_equals(lengthScrollTimeline.phase, "active",
287 'Length-based timeline phase before the endScrollOffset point');
289 // Check the percentage-based ScrollTimeline.
290 scroller.scrollTop = 0.81 * scrollerSize;
291 await waitForNextFrame();
292 assert_percents_equal(percentageScrollTimeline.currentTime, 100,
293 'Percentage-based timeline current time after the endScrollOffset point');
294 assert_equals(percentageScrollTimeline.phase, "after",
295 'Percentage-based timeline phase after the endScrollOffset point');
296 scroller.scrollTop = 0.80 * scrollerSize;
297 await waitForNextFrame();
298 assert_percents_equal(percentageScrollTimeline.currentTime, 100,
299 'Percentage-based timeline current time at the endScrollOffset point');
300 assert_equals(percentageScrollTimeline.phase, "after",
301 'Percentage-based timeline phase at the endScrollOffset point');
302 scroller.scrollTop = 0.50 * scrollerSize;
303 await waitForNextFrame();
304 assert_percents_equal(
305 percentageScrollTimeline.currentTime,
306 calculateCurrentTime(scroller.scrollTop, 0, 0.8 * scrollerSize),
307 'Percentage-based timeline current time before the endScrollOffset ' +
308 'point');
309 assert_equals(percentageScrollTimeline.phase, "active",
310 'Percentage-based timeline phase before the endScrollOffset point');
312 // Check the calc-based ScrollTimeline.
313 scroller.scrollTop = 0.8 * scrollerSize + 6;
314 await waitForNextFrame();
315 assert_percents_equal(calcScrollTimeline.currentTime, 100,
316 'Calc-based timeline current time after the endScrollOffset point');
317 assert_equals(calcScrollTimeline.phase, "after",
318 'Calc-based timeline phase after the endScrollOffset point');
319 scroller.scrollTop = 0.8 * scrollerSize + 5;
320 await waitForNextFrame();
321 assert_percents_equal(calcScrollTimeline.currentTime, 100,
322 'Calc-based timeline current time at the endScrollOffset point');
323 assert_equals(calcScrollTimeline.phase, "after",
324 'Calc-based timeline phase at the endScrollOffset point');
325 scroller.scrollTop = 0.5 * scrollerSize;
326 await waitForNextFrame();
327 assert_percents_equal(
328 calcScrollTimeline.currentTime,
329 calculateCurrentTime(scroller.scrollTop, 0, 0.8 * scrollerSize + 5),
330 'Calc-based timeline current time before the endScrollOffset point');
331 assert_equals(calcScrollTimeline.phase, "active",
332 'Calc-based timeline phase before the endScrollOffset point');
333 }, 'currentTime handles endScrollOffset correctly');
335 promise_test(async t => {
336 const scroller = setupScrollTimelineTest();
337 const scrollerSize = scroller.scrollHeight - scroller.clientHeight;
339 const scrollTimeline = new ScrollTimeline({
340 scrollSource: scroller,
341 orientation: 'block',
342 scrollOffsets: [CSS.px(20), CSS.px(scrollerSize - 50)]
345 scroller.scrollTop = 150;
346 // Wait for new animation frame which allows the timeline to compute new
347 // current time.
348 await waitForNextFrame();
349 assert_percents_equal(
350 scrollTimeline.currentTime,
351 calculateCurrentTime(150, 20, scrollerSize - 50));
352 }, 'currentTime handles startScrollOffset and endScrollOffset together' +
353 ' correctly');
355 promise_test(async t => {
356 const scroller = setupScrollTimelineTest();
357 const scrollTimeline = new ScrollTimeline({
358 scrollSource: scroller,
359 orientation: 'block',
360 scrollOffsets: [CSS.px(20), CSS.px(20)]
363 scroller.scrollTop = 150;
364 // Wait for new animation frame which allows the timeline to compute new
365 // current time.
366 await waitForNextFrame();
367 assert_percents_equal(scrollTimeline.currentTime, 100);
368 }, 'currentTime handles startScrollOffset == endScrollOffset correctly');
370 promise_test(async t => {
371 const scroller = setupScrollTimelineTest();
372 const scrollTimeline = new ScrollTimeline({
373 scrollSource: scroller,
374 orientation: 'block',
375 scrollOffsets: [CSS.px(50), CSS.px(10)]
378 scroller.scrollTop = 40;
379 // Wait for new animation frame which allows the timeline to compute new
380 // current time.
381 await waitForNextFrame();
382 assert_percents_equal(scrollTimeline.currentTime, 0);
383 scroller.scrollTop = 60;
384 await waitForNextFrame();
385 assert_percents_equal(scrollTimeline.currentTime, 100);
386 }, 'currentTime handles startScrollOffset > endScrollOffset correctly');
388 promise_test(async t => {
389 const scroller = setupScrollTimelineTest();
390 const scrollTimeline = new ScrollTimeline({
391 scrollSource: scroller,
392 orientation: 'block',
393 scrollOffsets: [CSS.px(10), CSS.px(20), CSS.px(40), CSS.px(70), CSS.px(90)],
396 var offset = 0;
397 var w = 1 / 4; // offset weight
398 var p = 0; // progress within the offset
400 scroller.scrollTop = 10;
401 // Wait for new animation frame which allows the timeline to compute new
402 // current time.
403 await waitForNextFrame();
405 assert_percents_equal(scrollTimeline.currentTime, (offset + p) * w * 100,
406 "current time calculation when scroll = " + scroller.scrollTop);
408 p = (12 - 10) / (20 - 10);
409 scroller.scrollTop = 12;
410 await waitForNextFrame();
411 assert_percents_equal(scrollTimeline.currentTime, (offset + p) * w * 100,
412 "current time calculation when scroll = " + scroller.scrollTop);
414 offset = 1;
415 p = 0;
416 scroller.scrollTop = 20;
417 await waitForNextFrame();
418 assert_percents_equal(scrollTimeline.currentTime, (offset + p) * w * 100,
419 "current time calculation when scroll = " + scroller.scrollTop);
421 p = (35 - 20) / (40 - 20);
422 scroller.scrollTop = 35;
423 await waitForNextFrame();
424 assert_percents_equal(scrollTimeline.currentTime, (offset + p) * w * 100,
425 "current time calculation when scroll = " + scroller.scrollTop);
427 offset = 2;
428 p = 0;
429 scroller.scrollTop = 40;
430 await waitForNextFrame();
431 assert_percents_equal(scrollTimeline.currentTime, (offset + p) * w * 100,
432 "current time calculation when scroll = " + scroller.scrollTop);
434 p = (60 - 40) / (70 - 40);
435 scroller.scrollTop = 60;
436 await waitForNextFrame();
437 assert_percents_equal(scrollTimeline.currentTime, (offset + p) * w * 100,
438 "current time calculation when scroll = " + scroller.scrollTop);
440 offset = 3;
441 p = 0;
442 scroller.scrollTop = 70;
443 await waitForNextFrame();
444 assert_percents_equal(scrollTimeline.currentTime, (offset + p) * w * 100,
445 "current time calculation when scroll = " + scroller.scrollTop);
447 p = (80 - 70) / (90 - 70);
448 scroller.scrollTop = 80;
449 await waitForNextFrame();
450 assert_percents_equal(scrollTimeline.currentTime, (offset + p) * w * 100,
451 "current time calculation when scroll = " + scroller.scrollTop);
453 scroller.scrollTop = 90;
454 await waitForNextFrame();
455 assert_percents_equal(scrollTimeline.currentTime, 100,
456 "current time calculation when scroll = " + scroller.scrollTop);
457 }, 'currentTime calculations when multiple scroll offsets are specified');
459 </script>