Source code
Revision control
Copy as Markdown
Other Tools
Test Info: Warnings
- This test has a WPT meta file that expects 4 subtest issues.
- This WPT test may be referenced by the following Test IDs:
- /scroll-animations/scroll-timelines/scroll-animation.html - WPT Dashboard Interop Dashboard
<!DOCTYPE html>
<meta charset=utf-8>
<title>Test basic functionality of scroll linked animation.</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/web-animations/testcommon.js"></script>
<script src="testcommon.js"></script>
<style>
.scroller {
overflow: auto;
height: 100px;
width: 100px;
will-change: transform;
}
.contents {
height: 1000px;
width: 100%;
}
</style>
<div id="log"></div>
<script>
'use strict';
promise_test(async t => {
const animation = createScrollLinkedAnimation(t);
const scroller = animation.timeline.source;
const maxScroll = scroller.scrollHeight - scroller.clientHeight;
// Verify initial start and current times in Idle state.
assert_equals(animation.currentTime, null,
"The current time is null in Idle state.");
assert_equals(animation.startTime, null,
"The start time is null in Idle state.");
animation.play();
assert_true(animation.pending, "Animation is in the pending state.");
// Verify initial start and current times in the pending state.
assert_equals(animation.currentTime, null,
"The current time remains null while in the pending state.");
assert_equals(animation.startTime, null,
"The start time remains null while in the pending state.");
await animation.ready;
// Verify initial start and current times once ready.
assert_percents_equal(animation.currentTime, 0,
"The current time is resolved when ready.");
assert_percents_equal(animation.startTime, 0,
"The start time is resolved when ready.");
// Now do some scrolling and make sure that the Animation current time is
// correct.
scroller.scrollTop = 0.4 * maxScroll;
// Wait for new animation frame which allows the timeline to compute new
// current time.
await waitForNextFrame();
assert_percents_equal(animation.currentTime, animation.timeline.currentTime,
"The current time corresponds to the scroll position of the scroller.");
assert_times_equal(
animation.effect.getComputedTiming().progress,
animation.timeline.currentTime.value / 100,
'Effect progress corresponds to the scroll position of the scroller.');
}, 'Animation start and current times are correct for each animation state.');
promise_test(async t => {
const animation = createScrollLinkedAnimation(t);
const scroller = animation.timeline.source;
const maxScroll = scroller.scrollHeight - scroller.clientHeight;
// Advance the scroller.
scroller.scrollTop = 0.2 * maxScroll;
// Wait for new animation frame which allows the timeline to compute new
// current time.
await waitForNextFrame();
// Verify initial start and current times in Idle state.
assert_equals(animation.currentTime, null,
"The current time is null in Idle state.");
assert_equals(animation.startTime, null,
"The start time is null in Idle state.");
animation.play();
// Verify initial start and current times in Pending state.
assert_equals(animation.currentTime, null,
"The current time remains unresolved while play-pending.");
assert_equals(animation.startTime, null,
"The start time remains unresolved while play-pending.");
await animation.ready;
// Verify initial start and current times in Playing state.
assert_percents_equal(animation.currentTime, animation.timeline.currentTime,
"The current corresponds to the scroll position of the scroller.");
assert_percents_equal(animation.startTime, 0,
"The start time is zero in Playing state.");
}, 'Animation start and current times are correct for each animation state' +
' when the animation starts playing with advanced scroller.');
promise_test(async t => {
const animation = createScrollLinkedAnimation(t);
const scroller = animation.timeline.source;
const maxScroll = scroller.scrollHeight - scroller.clientHeight;
animation.play();
await animation.ready;
// Advance the scroller to max position.
scroller.scrollTop = maxScroll;
await animation.finished;
assert_equals(animation.playState, 'finished',
'Animation state is in finished state.');
assert_percents_equal(animation.currentTime, 100,
'Animation current time is at 100% on reverse scrolling.');
// Scroll back.
scroller.scrollTop = 0.2 * maxScroll;
// Wait for new animation frame which allows the timeline to compute new
// current time.
await waitForNextFrame();
// Verify animation state and current time on reverse scrolling.
assert_equals(animation.playState, 'running',
'Animation state is playing on reverse scrolling.');
assert_percents_equal(animation.currentTime, 20,
'Animation current time is updated on reverse scrolling.');
}, 'Finished animation plays on reverse scrolling.');
promise_test(async t => {
const animation = createScrollLinkedAnimation(t);
const scroller = animation.timeline.source;
const maxScroll = scroller.scrollHeight - scroller.clientHeight;
animation.play();
await animation.ready;
// Advance the scroller to max position.
scroller.scrollTop = maxScroll;
await animation.finished;
var sent_finish_event = false;
animation.onfinish = function() {
sent_finish_event = true;
};
// Scroll back.
scroller.scrollTop = 0.2 * maxScroll;
// Wait for new animation frame which allows the timeline to compute new
// current time.
await waitForNextFrame();
assert_false(sent_finish_event,
"No animation finished event is sent on reverse scroll.");
scroller.scrollTop = maxScroll;
await animation.finished;
// Wait for next frame to allow the animation to send finish events. The
// finished promise fires before events are sent.
await waitForNextFrame();
assert_true(sent_finish_event,
"Animation finished event is sent on reaching max scroll.");
}, 'Sending animation finished events by finished animation on reverse ' +
'scrolling.');
</script>