blob: 9a9ed331629a67be2875ff897b3ee6947c9a9500 [file] [log] [blame]
<!DOCTYPE html>
<meta charset=utf-8>
<title>Test play state changes for animations with a negative playback rate</title>
<link rel="help" href="https://drafts.csswg.org/web-animations/#play-state">
<script src="../../external/wpt/web-animations/testcommon.js"></script>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<script>
var duration = 100000;
function assert_unresolved(value) {
assert_equals(value, null);
}
function idleAnimation() {
var animation = document.documentElement.animate([], duration);
animation.reverse();
animation.cancel();
return animation;
}
function runningAnimation() {
var animation = idleAnimation();
animation.play();
animation.startTime = document.timeline.currentTime + duration / 2;
return animation;
}
function pendingAnimation() {
var animation = idleAnimation();
animation.play();
return animation;
}
function pausedAnimation() {
var animation = idleAnimation();
animation.pause();
animation.currentTime = duration;
return animation;
}
function finishedAnimation() {
var animation = idleAnimation();
animation.play();
animation.finish();
return animation;
}
test(function() {
var animation = idleAnimation();
assert_unresolved(animation.startTime);
assert_unresolved(animation.currentTime);
assert_false(animation.pending);
assert_equals(animation.playState, 'idle');
}, "Play state is idle after cancelling a reversed animation");
test(function() {
var animation = pendingAnimation();
assert_unresolved(animation.startTime);
assert_equals(animation.currentTime, duration);
assert_true(animation.pending);
assert_equals(animation.playState, 'running');
}, "Play state is running after playing a canceled reversed animation");
test(function() {
var animation = runningAnimation();
assert_times_equal(animation.startTime, document.timeline.currentTime - (animation.playbackRate * animation.currentTime));
assert_times_equal(animation.currentTime, duration / 2);
assert_false(animation.pending);
assert_equals(animation.playState, 'running');
}, "Play state is running after playing and setting start time of a canceled reversed animation");
test(function() {
var animation = pausedAnimation();
assert_unresolved(animation.startTime);
assert_equals(animation.currentTime, duration);
// Setting the current time of a pause-pending animation applies a synchronous update.
assert_false(animation.pending);
assert_equals(animation.playState, 'paused');
}, "Play state is paused after pausing and setting current time of a canceled reversed animation");
test(function() {
var animation = finishedAnimation();
assert_times_equal(
animation.startTime,
document.timeline.currentTime - (animation.playbackRate * animation.currentTime));
assert_equals(animation.currentTime, 0);
assert_false(animation.pending);
assert_equals(animation.playState, 'finished');
}, "Play state is finished after playing and finishing a cancelled reversed animation");
test(function() {
var animation = idleAnimation();
animation.play();
assert_unresolved(animation.startTime);
assert_equals(animation.currentTime, duration);
assert_true(animation.pending);
assert_equals(animation.playState, 'running');
}, "Calling play() on an idle animation");
test(function() {
var animation = idleAnimation();
animation.pause();
assert_unresolved(animation.startTime);
assert_equals(animation.currentTime, duration);
assert_true(animation.pending);
assert_equals(animation.playState, 'paused');
}, "Calling pause() on an idle animation");
test(function() {
var animation = idleAnimation();
animation.cancel();
assert_unresolved(animation.startTime);
assert_unresolved(animation.currentTime);
assert_false(animation.pending);
assert_equals(animation.playState, 'idle');
}, "Calling cancel() on an idle animation");
test(function() {
var animation = idleAnimation();
animation.finish();
assert_times_equal(
animation.startTime,
document.timeline.currentTime - (animation.playbackRate * animation.currentTime));
assert_equals(animation.currentTime, 0);
assert_false(animation.pending);
assert_equals(animation.playState, 'finished');
}, "Calling finish() on an idle animation");
test(function() {
var animation = idleAnimation();
animation.reverse();
assert_unresolved(animation.startTime);
assert_equals(animation.currentTime, 0);
assert_true(animation.pending);
assert_equals(animation.playState, 'running');
}, "Calling reverse() on an idle animation");
test(function() {
var animation = idleAnimation();
animation.currentTime = 1000;
assert_unresolved(animation.startTime);
assert_equals(animation.currentTime, 1000);
assert_false(animation.pending);
assert_equals(animation.playState, 'paused');
}, "Setting currentTime on an idle animation");
test(function() {
var animation = idleAnimation();
animation.startTime = document.timeline.currentTime + 1000;
assert_times_equal(animation.startTime, document.timeline.currentTime + 1000);
assert_times_equal(animation.currentTime, 1000);
assert_false(animation.pending);
assert_equals(animation.playState, 'running');
}, "Setting startTime on an idle animation");
test(function() {
var animation = pendingAnimation();
animation.play();
assert_unresolved(animation.startTime);
assert_equals(animation.currentTime, duration);
assert_true(animation.pending);
assert_equals(animation.playState, 'running');
}, "Calling play() on a pending animation");
test(function() {
var animation = pendingAnimation();
animation.pause();
assert_unresolved(animation.startTime);
assert_equals(animation.currentTime, duration);
assert_true(animation.pending);
assert_equals(animation.playState, 'paused');
}, "Calling pause() on a pending animation");
test(function() {
var animation = pendingAnimation();
animation.cancel();
assert_unresolved(animation.startTime);
assert_unresolved(animation.currentTime);
assert_false(animation.pending);
assert_equals(animation.playState, 'idle');
}, "Calling cancel() on a pending animation");
test(function() {
var animation = pendingAnimation();
animation.finish();
assert_times_equal(animation.startTime, document.timeline.currentTime - (animation.playbackRate * animation.currentTime));
assert_equals(animation.currentTime, 0);
assert_false(animation.pending);
assert_equals(animation.playState, 'finished');
}, "Calling finish() on a pending animation");
test(function() {
var animation = pendingAnimation();
animation.reverse();
assert_unresolved(animation.startTime);
assert_equals(animation.currentTime, 0);
assert_true(animation.pending);
assert_equals(animation.playState, 'running');
}, "Calling reverse() on a pending animation");
test(function() {
var animation = pendingAnimation();
animation.currentTime = 1000;
assert_unresolved(animation.startTime);
assert_equals(animation.currentTime, 1000);
assert_true(animation.pending);
assert_equals(animation.playState, 'running');
}, "Setting currentTime on a pending animation");
test(function() {
var animation = pendingAnimation();
animation.startTime = document.timeline.currentTime + 1000;
assert_times_equal(animation.startTime, document.timeline.currentTime + 1000);
assert_times_equal(animation.currentTime, 1000);
assert_false(animation.pending);
assert_equals(animation.playState, 'running');
}, "Setting startTime on a pending animation");
test(function() {
var animation = runningAnimation();
var startTime = animation.startTime;
var currentTime = animation.currentTime;
animation.play();
assert_equals(animation.startTime, startTime);
assert_equals(animation.currentTime, currentTime);
assert_false(animation.pending);
assert_equals(animation.playState, 'running');
}, "Calling play() on a running animation");
async_test(function(t) {
var animation = runningAnimation();
animation.pause();
assert_true(animation.pending);
assert_times_equal(animation.currentTime, duration / 2);
assert_equals(animation.playState, 'paused');
animation.ready.then(t.step_func_done(() => {
assert_equals(animation.startTime, null);
assert_false(animation.pending);
assert_equals(animation.playState, 'paused');
}));
}, "Calling pause() on a running animation");
test(function() {
var animation = runningAnimation();
animation.cancel();
assert_unresolved(animation.startTime);
assert_unresolved(animation.currentTime);
assert_false(animation.pending);
assert_equals(animation.playState, 'idle');
}, "Calling cancel() on a running animation");
test(function() {
var animation = runningAnimation();
animation.finish();
assert_times_equal(animation.startTime, document.timeline.currentTime - (animation.playbackRate * animation.currentTime));
assert_equals(animation.currentTime, 0);
assert_false(animation.pending);
assert_equals(animation.playState, 'finished');
}, "Calling finish() on a running animation");
async_test(function(t) {
var animation = runningAnimation();
assert_equals(animation.playbackRate, -1);
animation.reverse();
assert_true(animation.pending);
assert_times_equal(animation.currentTime, duration / 2);
assert_equals(animation.playbackRate, -1);
assert_equals(animation.playState, 'running');
animation.ready.then(t.step_func_done(() => {
assert_false(animation.pending);
// TODO(crbug.com/960944): Add check to ensure that current time remains
// unchanged once remaining timing glitches are resolved.
assert_not_equals(animation.startTime, null);
assert_equals(animation.playbackRate, 1);
assert_equals(animation.playState, 'running');
}));
}, "Calling reverse() on a running animation");
test(function() {
var animation = runningAnimation();
animation.currentTime = 1000;
assert_times_equal(animation.startTime, document.timeline.currentTime - (animation.playbackRate * animation.currentTime));
assert_times_equal(animation.currentTime, 1000);
assert_false(animation.pending);
assert_equals(animation.playState, 'running');
}, "Setting currentTime on a running animation");
test(function() {
var animation = runningAnimation();
animation.startTime = document.timeline.currentTime + 1000;
assert_times_equal(animation.startTime, document.timeline.currentTime + 1000);
assert_times_equal(animation.currentTime, 1000);
assert_false(animation.pending);
assert_equals(animation.playState, 'running');
}, "Setting startTime on a running animation");
test(function() {
var animation = pausedAnimation();
animation.play();
assert_unresolved(animation.startTime);
assert_equals(animation.currentTime, duration);
assert_true(animation.pending);
assert_equals(animation.playState, 'running');
}, "Calling play() on a paused animation");
test(function() {
var animation = pausedAnimation();
// Calling pause on an animation that is already paused or pause-pending is
// a no-op.
animation.pause();
assert_unresolved(animation.startTime);
assert_equals(animation.currentTime, duration);
assert_false(animation.pending);
assert_equals(animation.playState, 'paused');
}, "Calling pause() on a paused animation");
test(function() {
var animation = pausedAnimation();
animation.cancel();
assert_unresolved(animation.startTime);
assert_unresolved(animation.currentTime);
assert_false(animation.pending);
assert_equals(animation.playState, 'idle');
}, "Calling cancel() on a paused animation");
test(function() {
var animation = pausedAnimation();
animation.finish();
assert_times_equal(animation.startTime, document.timeline.currentTime - (animation.playbackRate * animation.currentTime));
assert_equals(animation.currentTime, 0);
assert_false(animation.pending);
assert_equals(animation.playState, 'finished');
}, "Calling finish() on a paused animation");
test(function() {
var animation = pausedAnimation();
animation.reverse();
assert_unresolved(animation.startTime);
assert_equals(animation.currentTime, 0);
assert_true(animation.pending);
assert_equals(animation.playState, 'running');
}, "Calling reverse() on a paused animation");
test(function() {
var animation = pausedAnimation();
// Setting the current time on a paused or pause-pending animation gets
// resolved synchronously.
animation.currentTime = 1000;
assert_unresolved(animation.startTime);
assert_times_equal(animation.currentTime, 1000);
assert_false(animation.pending);
assert_equals(animation.playState, 'paused');
}, "Setting currentTime on a paused animation");
test(function() {
var animation = pausedAnimation();
animation.startTime = document.timeline.currentTime + 1000;
assert_times_equal(animation.startTime, document.timeline.currentTime + 1000);
assert_times_equal(animation.currentTime, 1000);
assert_false(animation.pending);
assert_equals(animation.playState, 'running');
}, "Setting startTime on a paused animation");
test(function() {
var animation = finishedAnimation();
animation.play();
assert_unresolved(animation.startTime);
assert_equals(animation.currentTime, duration);
assert_true(animation.pending);
assert_equals(animation.playState, 'running');
}, "Calling play() on a finished animation");
async_test(function(t) {
var animation = finishedAnimation();
animation.pause();
assert_equals(animation.currentTime, 0);
assert_true(animation.pending);
assert_equals(animation.playState, 'paused');
animation.ready.then(t.step_func_done(() => {
assert_equals(animation.startTime, null);
assert_equals(animation.currentTime, 0);
assert_false(animation.pending);
assert_equals(animation.playState, 'paused');
}));
}, "Calling pause() on a finished animation");
test(function() {
var animation = finishedAnimation();
animation.cancel();
assert_unresolved(animation.startTime);
assert_unresolved(animation.currentTime);
assert_false(animation.pending);
assert_equals(animation.playState, 'idle');
}, "Calling cancel() on a finished animation");
test(function() {
var animation = finishedAnimation();
animation.finish();
assert_times_equal(animation.startTime, document.timeline.currentTime - (animation.playbackRate * animation.currentTime));
assert_equals(animation.currentTime, 0);
assert_false(animation.pending);
assert_equals(animation.playState, 'finished');
}, "Calling finish() on a finished animation");
async_test(function(t) {
var animation = finishedAnimation();
animation.reverse();
assert_equals(animation.startTime, null);
assert_equals(animation.currentTime, 0);
assert_equals(animation.playbackRate, -1);
assert_true(animation.pending);
assert_equals(animation.playState, 'running');
animation.ready.then(t.step_func_done(() => {
assert_false(animation.pending);
assert_not_equals(animation.startTime, null);
assert_greater_than_equal(animation.currentTime, 0);
assert_equals(animation.playbackRate, 1);
assert_equals(animation.playState, 'running');
}));
}, "Calling reverse() on a finished animation");
test(function() {
var animation = finishedAnimation();
animation.currentTime = 1000;
assert_times_equal(animation.startTime, document.timeline.currentTime - (animation.playbackRate * animation.currentTime));
assert_times_equal(animation.currentTime, 1000);
assert_false(animation.pending);
assert_equals(animation.playState, 'running');
}, "Setting currentTime on a finished animation");
</script>