зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1635643 [wpt PR 23411] - Enabled finish() API for scroll animations, a=testonly
Automatic update from web-platform-tests Enabled finish() API for scroll animations Enabled finish() API and added tests. Bug: 916117 Change-Id: I0eb61645b8ba886c85da8a57c033225d6746c805 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2181574 Reviewed-by: Majid Valipour <majidvp@chromium.org> Reviewed-by: Yi Gu <yigu@chromium.org> Commit-Queue: Olga Gerchikov <gerchiko@microsoft.com> Cr-Commit-Position: refs/heads/master@{#767371} -- wpt-commits: 9457be11692da290af6e51eeedc4b0abc4dafb3c wpt-pr: 23411
This commit is contained in:
Родитель
3fcabca3a7
Коммит
7a33361b57
|
@ -0,0 +1,342 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset=utf-8>
|
||||
<title>Finishing an animation</title>
|
||||
<link rel="help"
|
||||
href="https://drafts.csswg.org/web-animations/#finishing-an-animation-section">
|
||||
<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;
|
||||
}
|
||||
|
||||
.contents {
|
||||
height: 1000px;
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
<body>
|
||||
<div id="log"></div>
|
||||
<script>
|
||||
'use strict';
|
||||
promise_test(async t => {
|
||||
const animation = createScrollLinkedAnimation(t);
|
||||
// Wait for new animation frame which allows the timeline to compute new
|
||||
// current time.
|
||||
await waitForNextFrame();
|
||||
animation.play();
|
||||
animation.playbackRate = 0;
|
||||
|
||||
assert_throws_dom('InvalidStateError', () => {
|
||||
animation.finish();
|
||||
});
|
||||
}, 'Finishing an animation with a zero playback rate throws');
|
||||
|
||||
promise_test(async t => {
|
||||
const animation = createScrollLinkedAnimation(t);
|
||||
animation.effect.updateTiming({ iterations : Infinity });
|
||||
animation.play();
|
||||
// Wait for new animation frame which allows the timeline to compute new
|
||||
// current time.
|
||||
await waitForNextFrame();
|
||||
|
||||
assert_throws_dom('InvalidStateError', () => {
|
||||
animation.finish();
|
||||
});
|
||||
}, 'Finishing an infinite animation throws');
|
||||
|
||||
promise_test(async t => {
|
||||
const animation = createScrollLinkedAnimation(t);
|
||||
// Wait for new animation frame which allows the timeline to compute new
|
||||
// current time.
|
||||
await waitForNextFrame();
|
||||
animation.play();
|
||||
animation.finish();
|
||||
|
||||
assert_times_equal(animation.currentTime, 1000,
|
||||
'After finishing, the currentTime should be set to the end of the'
|
||||
+ ' active duration');
|
||||
}, 'Finishing an animation seeks to the end time');
|
||||
|
||||
promise_test(async t => {
|
||||
const animation = createScrollLinkedAnimation(t);
|
||||
// Wait for new animation frame which allows the timeline to compute new
|
||||
// current time.
|
||||
await waitForNextFrame();
|
||||
animation.play();
|
||||
// 1s past effect end
|
||||
animation.currentTime =
|
||||
animation.effect.getComputedTiming().endTime + 1;
|
||||
animation.finish();
|
||||
|
||||
assert_time_equals_literal(animation.currentTime, 1000,
|
||||
'After finishing, the currentTime should be set back to the end of the'
|
||||
+ ' active duration');
|
||||
}, 'Finishing an animation with a current time past the effect end jumps'
|
||||
+ ' back to the end');
|
||||
|
||||
promise_test(async t => {
|
||||
const animation = createScrollLinkedAnimation(t);
|
||||
// Wait for new animation frame which allows the timeline to compute new
|
||||
// current time.
|
||||
await waitForNextFrame();
|
||||
animation.play();
|
||||
animation.currentTime = 1000;
|
||||
await animation.finished;
|
||||
|
||||
animation.playbackRate = -1;
|
||||
animation.finish();
|
||||
|
||||
assert_equals(animation.currentTime, 0,
|
||||
'After finishing a reversed animation the currentTime ' +
|
||||
'should be set to zero');
|
||||
}, 'Finishing a reversed animation jumps to zero time');
|
||||
|
||||
promise_test(async t => {
|
||||
const animation = createScrollLinkedAnimation(t);
|
||||
// Wait for new animation frame which allows the timeline to compute new
|
||||
// current time.
|
||||
await waitForNextFrame();
|
||||
animation.play();
|
||||
animation.currentTime = 1000;
|
||||
await animation.finished;
|
||||
|
||||
animation.playbackRate = -1;
|
||||
animation.currentTime = -10000;
|
||||
animation.finish();
|
||||
|
||||
assert_equals(animation.currentTime, 0,
|
||||
'After finishing a reversed animation the currentTime ' +
|
||||
'should be set back to zero');
|
||||
}, 'Finishing a reversed animation with a current time less than zero'
|
||||
+ ' makes it jump back to zero');
|
||||
|
||||
promise_test(async t => {
|
||||
const animation = createScrollLinkedAnimation(t);
|
||||
// Wait for new animation frame which allows the timeline to compute new
|
||||
// current time.
|
||||
await waitForNextFrame();
|
||||
animation.play();
|
||||
animation.playbackRate = 0.5;
|
||||
animation.finish();
|
||||
|
||||
assert_false(animation.pending);
|
||||
assert_equals(animation.playState, 'finished',
|
||||
'The play state of a play-pending animation should become ' +
|
||||
'"finished"');
|
||||
assert_times_equal(animation.startTime,
|
||||
animation.timeline.currentTime - 1000 / 0.5,
|
||||
'The start time of a play-pending animation should ' +
|
||||
'be set');
|
||||
}, 'Finishing an animation while play-pending resolves the pending'
|
||||
+ ' task immediately');
|
||||
|
||||
promise_test(async t => {
|
||||
const animation = createScrollLinkedAnimation(t);
|
||||
const scroller = animation.timeline.scrollSource;
|
||||
// Make the scroll timeline inactive.
|
||||
scroller.style.overflow = 'visible';
|
||||
scroller.scrollTop;
|
||||
// Wait for new animation frame which allows the timeline to compute new
|
||||
// current time.
|
||||
await waitForNextFrame();
|
||||
animation.play();
|
||||
animation.finish();
|
||||
|
||||
await animation.finished;
|
||||
|
||||
assert_true(animation.pending);
|
||||
assert_equals(animation.playState, 'finished',
|
||||
'The play state of a play-pending animation should become ' +
|
||||
'"finished"');
|
||||
assert_times_equal(animation.currentTime, 1000,
|
||||
'The current time of a play-pending animation should ' +
|
||||
'be set to the end of the active duration');
|
||||
assert_equals(animation.startTime, null,
|
||||
'The start time of a finished play-pending animation' +
|
||||
' should be be unresolved');
|
||||
}, 'Finishing an animation attached to inactive timeline while play-pending '
|
||||
+ 'doesn\'t resolves the pending task');
|
||||
|
||||
promise_test(async t => {
|
||||
const animation = createScrollLinkedAnimation(t);
|
||||
// Wait for new animation frame which allows the timeline to compute new
|
||||
// current time.
|
||||
await waitForNextFrame();
|
||||
animation.play();
|
||||
let resolvedFinished = false;
|
||||
animation.finished.then(() => {
|
||||
resolvedFinished = true;
|
||||
});
|
||||
|
||||
await animation.ready;
|
||||
|
||||
animation.finish();
|
||||
await Promise.resolve();
|
||||
|
||||
assert_true(resolvedFinished, 'finished promise should be resolved');
|
||||
}, 'Finishing an animation resolves the finished promise synchronously');
|
||||
|
||||
promise_test(async t => {
|
||||
const animation = createScrollLinkedAnimation(t);
|
||||
// Wait for new animation frame which allows the timeline to compute new
|
||||
// current time.
|
||||
await waitForNextFrame();
|
||||
animation.play();
|
||||
const promise = animation.ready;
|
||||
let readyResolved = false;
|
||||
|
||||
animation.finish();
|
||||
animation.ready.then(() => { readyResolved = true; });
|
||||
|
||||
const promiseResult = await animation.finished;
|
||||
await animation.ready;
|
||||
|
||||
assert_equals(promiseResult, animation);
|
||||
assert_equals(animation.ready, promise);
|
||||
assert_true(readyResolved);
|
||||
}, 'A pending ready promise is resolved and not replaced when the animation'
|
||||
+ ' is finished');
|
||||
|
||||
promise_test(async t => {
|
||||
const animation = createScrollLinkedAnimation(t);
|
||||
// Wait for new animation frame which allows the timeline to compute new
|
||||
// current time.
|
||||
await waitForNextFrame();
|
||||
animation.play();
|
||||
animation.effect.target.remove();
|
||||
|
||||
const eventWatcher = new EventWatcher(t, animation, 'finish');
|
||||
|
||||
await animation.ready;
|
||||
animation.finish();
|
||||
|
||||
await eventWatcher.wait_for('finish');
|
||||
assert_equals(animation.effect.target.parentNode, null,
|
||||
'finish event should be fired for the animation on an orphaned element');
|
||||
}, 'Finishing an animation fires finish event on orphaned element');
|
||||
|
||||
promise_test(async t => {
|
||||
const animation = createScrollLinkedAnimation(t);
|
||||
// Wait for new animation frame which allows the timeline to compute new
|
||||
// current time.
|
||||
await waitForNextFrame();
|
||||
animation.play();
|
||||
await animation.ready;
|
||||
|
||||
const originalFinishPromise = animation.finished;
|
||||
|
||||
animation.cancel();
|
||||
assert_equals(animation.startTime, null);
|
||||
assert_equals(animation.currentTime, null);
|
||||
|
||||
const resolvedFinishPromise = animation.finished;
|
||||
assert_true(originalFinishPromise != resolvedFinishPromise,
|
||||
'Canceling an animation should create a new finished promise');
|
||||
|
||||
animation.finish();
|
||||
assert_equals(animation.playState, 'finished',
|
||||
'The play state of a canceled animation should become ' +
|
||||
'"finished"');
|
||||
assert_times_equal(animation.startTime,
|
||||
animation.timeline.currentTime - 1000,
|
||||
'The start time of a finished animation should be set');
|
||||
assert_times_equal(animation.currentTime, 1000,
|
||||
'Hold time should be set to end boundary of the animation');
|
||||
|
||||
}, 'Finishing a canceled animation sets the current and start times');
|
||||
|
||||
promise_test(async t => {
|
||||
const animation = createScrollLinkedAnimation(t);
|
||||
const scroller = animation.timeline.scrollSource;
|
||||
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();
|
||||
|
||||
const eventWatcher = new EventWatcher(t, animation, 'finish');
|
||||
animation.finish();
|
||||
await animation.finished;
|
||||
const finishEvent = await eventWatcher.wait_for('finish');
|
||||
assert_equals(animation.playState, 'finished',
|
||||
'Animation is finished.');
|
||||
assert_equals(animation.currentTime, 1000,
|
||||
'The current time is the end of the active duration in finished state.');
|
||||
assert_equals(animation.startTime, -750,
|
||||
'The start time is calculated to match the current time.');
|
||||
assert_equals(finishEvent.currentTime, 1000,
|
||||
'event.currentTime is the animation current time.');
|
||||
assert_equals(finishEvent.timelineTime, 250,
|
||||
'event.timelineTime is timeline.currentTime');
|
||||
}, 'Finishing idle animation produces correct state and fires finish event.');
|
||||
|
||||
promise_test(async t => {
|
||||
const animation = createScrollLinkedAnimation(t);
|
||||
const scroller = animation.timeline.scrollSource;
|
||||
// Make the scroll timeline inactive.
|
||||
scroller.style.overflow = 'visible';
|
||||
await waitForNextFrame();
|
||||
assert_equals(animation.timeline.currentTime, null,
|
||||
'Sanity check the timeline is inactive.');
|
||||
animation.finish();
|
||||
assert_equals(animation.playState, 'paused', 'Animation is paused.');
|
||||
}, 'Finishing idle animation attached to inactive timeline pauses the ' +
|
||||
'animation.');
|
||||
|
||||
promise_test(async t => {
|
||||
const animation = createScrollLinkedAnimation(t);
|
||||
const scroller = animation.timeline.scrollSource;
|
||||
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 eventWatcher = new EventWatcher(t, animation, 'finish');
|
||||
animation.finish();
|
||||
await animation.finished;
|
||||
const finishEvent = await eventWatcher.wait_for('finish');
|
||||
assert_equals(animation.playState, 'finished',
|
||||
'Animation is finished.');
|
||||
assert_equals(animation.currentTime, 1000,
|
||||
'The current time is the end of active duration in finished state.');
|
||||
assert_equals(animation.startTime, -750,
|
||||
'The start time is calculated to match animation current time.');
|
||||
assert_equals(finishEvent.currentTime, 1000,
|
||||
'event.currentTime is the animation current time.');
|
||||
assert_equals(finishEvent.timelineTime, 250,
|
||||
'event.timelineTime is timeline.currentTime');
|
||||
}, 'Finishing running animation produces correct state and fires finish event.');
|
||||
|
||||
promise_test(async t => {
|
||||
const animation = createScrollLinkedAnimation(t);
|
||||
const scroller = animation.timeline.scrollSource;
|
||||
// Wait for new animation frame which allows the timeline to compute new
|
||||
// current time.
|
||||
await waitForNextFrame();
|
||||
animation.play();
|
||||
await animation.ready;
|
||||
|
||||
// Make the scroll timeline inactive.
|
||||
scroller.style.overflow = 'visible';
|
||||
scroller.scrollTop;
|
||||
await waitForNextFrame();
|
||||
assert_equals(animation.timeline.currentTime, null,
|
||||
'Sanity check the timeline is inactive.');
|
||||
assert_equals(animation.playState, 'running',
|
||||
'Sanity check the animation is running.');
|
||||
|
||||
animation.finish();
|
||||
assert_equals(animation.playState, 'paused', 'Animation is paused.');
|
||||
}, 'Finishing running animation attached to inactive timeline pauses the ' +
|
||||
'animation.');
|
||||
|
||||
</script>
|
||||
</body>
|
Загрузка…
Ссылка в новой задаче