Files
sousa-gecko/testing/web-platform/tests/scroll-animations/scroll-timelines/setting-current-time.html
T
Rune Lillesveen 93405ba0c3 Bug 1990305 [wpt PR 55017] - Make scroll-timelines/setting-* tests pass for run-snapshot-post-layout, a=testonly
Automatic update from web-platform-tests
Make scroll-timelines/setting-* tests pass for run-snapshot-post-layout

Preparing for proposed change:

https://github.com/whatwg/html/pull/11613

Bug: 384523570

Change-Id: Ic4ba0c31dcf0a1783dd2710462a5061ff8586c52
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6976604
Commit-Queue: Rune Lillesveen <futhark@chromium.org>
Reviewed-by: Kevin Ellis <kevers@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1519481}

--

wpt-commits: 538a74ceed6fb26498dccfb6a3ec3aa8baec363a
wpt-pr: 55017
2025-09-26 12:08:44 +00:00

287 lines
10 KiB
HTML

<!DOCTYPE html>
<meta charset=utf-8>
<title>Setting the current time of an animation</title>
<link rel="help" href="https://drafts.csswg.org/web-animations-1/#setting-the-current-time-of-an-animation">
<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: 200px;
width: 100px;
will-change: transform;
}
.contents {
height: 1000px;
width: 100%;
}
</style>
<body>
<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;
scroller.scrollTop = 0.25 * maxScroll;
// Wait for new animation frame which allows the timeline to compute new
// current time.
await waitForNextFrame();
animation.play();
await animation.ready;
assert_throws_js(TypeError, () => {
animation.currentTime = null;
});
}, 'Setting animation current time to null throws TypeError.');
promise_test(async t => {
const animation = createScrollLinkedAnimation(t);
assert_throws_js(TypeError, () => {
animation.currentTime = CSSNumericValue.parse("300");
});
assert_throws_js(TypeError, () => {
animation.currentTime = CSSNumericValue.parse("300ms");
});
assert_throws_js(TypeError, () => {
animation.currentTime = CSSNumericValue.parse("0.3s");
});
}, 'Setting the current time to an absolute time value throws exception');
promise_test(async t => {
const animation = createScrollLinkedAnimation(t);
const scroller = animation.timeline.source;
const maxScroll = scroller.scrollHeight - scroller.clientHeight;
scroller.scrollTop = 0.25 * maxScroll;
// Wait for new animation frame which allows the timeline to compute new
// current time.
await waitForNextFrame();
animation.currentTime = CSSNumericValue.parse("33.3%");
assert_percents_equal(animation.currentTime, 33.3,
"Animation current time should be equal to the set value."
);
}, 'Set animation current time to a valid value without playing.');
promise_test(async t => {
const animation = createScrollLinkedAnimation(t);
const scroller = animation.timeline.source;
const maxScroll = scroller.scrollHeight - scroller.clientHeight;
scroller.scrollTop = 0.25 * maxScroll;
// Wait for new animation frame which allows the timeline to compute new
// current time.
await waitForNextFrame();
animation.play();
await animation.ready;
animation.currentTime = CSSNumericValue.parse("33.3%");
assert_percents_equal(animation.currentTime, 33.3,
"Animation current time should be equal to the set value."
);
}, 'Set animation current time to a valid value while playing.');
promise_test(async t => {
const animation = createScrollLinkedAnimation(t);
const scroller = animation.timeline.source;
const maxScroll = scroller.scrollHeight - scroller.clientHeight;
scroller.scrollTop = 0.25 * maxScroll;
// Wait for new animation frame which allows the timeline to compute new
// current time.
await waitForNextFrame();
animation.play();
await animation.ready;
animation.currentTime = CSSNumericValue.parse("200%");
assert_equals(animation.playState, "finished");
assert_percents_equal(animation.currentTime, 200,
"Animation current time should be equal to the set value."
);
}, 'Set animation current time to a value beyond effect end.');
promise_test(async t => {
const animation = createScrollLinkedAnimation(t);
const scroller = animation.timeline.source;
const maxScroll = scroller.scrollHeight - scroller.clientHeight;
scroller.scrollTop = 0.25 * maxScroll;
// Wait for new animation frame which allows the timeline to compute new
// current time.
await waitForNextFrame();
animation.play();
await animation.ready;
animation.currentTime = CSSNumericValue.parse("-10%");
assert_equals(animation.playState, "running");
assert_percents_equal(animation.currentTime, -10,
"Animation current time should be equal to the set value."
);
}, 'Set animation current time to a negative value.');
promise_test(async t => {
const animation = createScrollLinkedAnimation(t);
const scroller = animation.timeline.source;
const maxScroll = scroller.scrollHeight - scroller.clientHeight;
scroller.scrollTop = 0.25 * maxScroll;
// Wait for new animation frame which allows the timeline to compute new
// current time.
await waitForNextFrame();
animation.play();
animation.currentTime = CSSNumericValue.parse("30%");
assert_equals(animation.playState, "running");
assert_true(animation.pending);
assert_percents_equal(animation.currentTime, 30);
}, "Setting current time while play pending overrides the current time");
promise_test(async t => {
const animation = createScrollLinkedAnimation(t);
const scroller = animation.timeline.source;
const maxScroll = scroller.scrollHeight - scroller.clientHeight;
scroller.scrollTop = 0.25 * maxScroll;
// Wait for new animation frame which allows the timeline to compute new
// current time.
await waitForNextFrame();
animation.play();
await animation.ready;
animation.currentTime = CSSNumericValue.parse("33.3%");
assert_percents_equal(animation.currentTime, 33.3,
"Animation current time should be equal to the set value."
);
// Cancel the animation and play it again, check that current time has reset
// to scroll offset based current time.
animation.cancel();
animation.play();
await animation.ready;
assert_percents_equal(animation.currentTime, animation.timeline.currentTime,
"Animation current time should return to a value matching its" +
" timeline current time after animation is cancelled and played again."
);
}, 'Setting animation.currentTime then restarting the animation should' +
' reset the current time.');
promise_test(async t => {
const animation = createScrollLinkedAnimation(t);
const scroller = animation.timeline.source;
const maxScroll = scroller.scrollHeight - scroller.clientHeight;
scroller.scrollTop = 0.25 * maxScroll;
// Wait for new animation frame which allows the timeline to compute new
// current time.
await waitForNextFrame();
animation.play();
await animation.ready;
const originalCurrentTime = animation.currentTime.value;
// Set the current time to something other than where the scroll offset.
animation.currentTime = CSSNumericValue.parse("50%");
// Setting current time is internally setting the start time to
// scrollTimeline.currentTime - newAnimationCurrentTime.
// Which results in current time of (timeline.currentTime - start_time).
// This behavior puts the animation in a strange "out of sync" state between
// the scroller and the animation effect, this is currently expected
// behavior.
const expectedStartTime = originalCurrentTime - animation.currentTime.value;
assert_percents_equal(animation.startTime, expectedStartTime,
"Animation current time should be updated when setting the current time" +
" to a time within the range of the animation.");
scroller.scrollTop = 0.7 * maxScroll;
// Wait for new animation frame which allows the timeline to compute new
// current time.
await waitForNextFrame();
assert_percents_equal(animation.startTime, expectedStartTime,
"Animation start time should remain unchanged when the scroller changes" +
" position."
);
assert_percents_equal(animation.currentTime,
animation.timeline.currentTime.value - animation.startTime.value,
"Animation current time should return to a value equal to" +
" (timeline.currentTime - animation.startTime) after timeline scroll" +
" source has been scrolled."
);
}, 'Set Animation current time then scroll.');
promise_test(async t => {
const animation = createScrollLinkedAnimation(t);
const scroller = animation.timeline.source;
// Wait for new animation frame which allows the timeline to compute new
// current time.
await waitForNextFrame();
animation.play();
await animation.ready;
// Make the timeline inactive.
await runAndWaitForFrameUpdate(() => {
scroller.style.overflow = 'visible';
});
assert_equals(animation.currentTime, null,
'Current time is unresolved when the timeline is inactive.');
animation.currentTime = CSSNumericValue.parse("30%");
assert_percents_equal(animation.currentTime, 30,
'Animation current time should be equal to the set value.');
assert_equals(animation.playState, 'paused',
'Animation play state is \'paused\' when current time is set and ' +
'timeline is inactive.');
}, 'Animation current time and play state are correct when current time is ' +
'set while the timeline is inactive.');
promise_test(async t => {
const animation = createScrollLinkedAnimation(t);
const scroller = animation.timeline.source;
// Wait for new animation frame which allows the timeline to compute new
// current time.
await waitForNextFrame();
animation.play();
await animation.ready;
// Make the timeline inactive.
await runAndWaitForFrameUpdate(() => {
scroller.style.overflow = 'visible';
});
assert_equals(animation.timeline.currentTime, null,
'Current time is unresolved when the timeline is inactive.');
animation.currentTime = CSSNumericValue.parse("30%");
assert_percents_equal(animation.currentTime, 30,
'Animation current time should be equal to the set value.');
assert_equals(animation.playState, 'paused',
'Animation play state is \'paused\' when current time is set and ' +
'timeline is inactive.');
// Make the timeline active.
await runAndWaitForFrameUpdate(() => {
scroller.style.overflow = 'auto';
});
assert_percents_equal(animation.timeline.currentTime, 0,
'Current time is resolved when the timeline is active.');
assert_percents_equal(animation.currentTime, 30,
'Animation current time holds the set value.');
assert_equals(animation.playState, 'paused',
'Animation holds \'paused\' state.');
}, 'Animation current time set while the timeline is inactive holds when the ' +
'timeline becomes active again.');
</script>
</body>