summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/web-animations/interfaces/Animation/finish.html
diff options
context:
space:
mode:
Diffstat (limited to 'testing/web-platform/tests/web-animations/interfaces/Animation/finish.html')
-rw-r--r--testing/web-platform/tests/web-animations/interfaces/Animation/finish.html246
1 files changed, 246 insertions, 0 deletions
diff --git a/testing/web-platform/tests/web-animations/interfaces/Animation/finish.html b/testing/web-platform/tests/web-animations/interfaces/Animation/finish.html
new file mode 100644
index 000000000..9b9c4c710
--- /dev/null
+++ b/testing/web-platform/tests/web-animations/interfaces/Animation/finish.html
@@ -0,0 +1,246 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Animation.finish()</title>
+<link rel="help" href="https://w3c.github.io/web-animations/#dom-animation-finish">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../../testcommon.js"></script>
+<body>
+<div id="log"></div>
+<script>
+'use strict';
+
+var gKeyFrames = { 'marginLeft': ['100px', '200px'] };
+
+test(function(t) {
+ var div = createDiv(t);
+ var animation = div.animate(gKeyFrames, 100 * MS_PER_SEC);
+ animation.playbackRate = 0;
+
+ assert_throws({name: 'InvalidStateError'}, function() {
+ animation.finish();
+ });
+}, 'Test exceptions when finishing non-running animation');
+
+test(function(t) {
+ var div = createDiv(t);
+ var animation = div.animate(gKeyFrames,
+ {duration : 100 * MS_PER_SEC,
+ iterations : Infinity});
+
+ assert_throws({name: 'InvalidStateError'}, function() {
+ animation.finish();
+ });
+}, 'Test exceptions when finishing infinite animation');
+
+test(function(t) {
+ var div = createDiv(t);
+ var animation = div.animate(gKeyFrames, 100 * MS_PER_SEC);
+ animation.finish();
+
+ assert_equals(animation.currentTime, 100 * MS_PER_SEC,
+ 'After finishing, the currentTime should be set to the end ' +
+ 'of the active duration');
+}, 'Test finishing of animation');
+
+test(function(t) {
+ var div = createDiv(t);
+ var animation = div.animate(gKeyFrames, 100 * MS_PER_SEC);
+ // 1s past effect end
+ animation.currentTime =
+ animation.effect.getComputedTiming().endTime + 1 * MS_PER_SEC;
+ animation.finish();
+
+ assert_equals(animation.currentTime, 100 * MS_PER_SEC,
+ 'After finishing, the currentTime should be set back to the ' +
+ 'end of the active duration');
+}, 'Test finishing of animation with a current time past the effect end');
+
+promise_test(function(t) {
+ var div = createDiv(t);
+ var animation = div.animate(gKeyFrames, 100 * MS_PER_SEC);
+ animation.currentTime = 100 * MS_PER_SEC;
+ return animation.finished.then(function() {
+ animation.playbackRate = -1;
+ animation.finish();
+
+ assert_equals(animation.currentTime, 0,
+ 'After finishing a reversed animation the currentTime ' +
+ 'should be set to zero');
+ });
+}, 'Test finishing of reversed animation');
+
+promise_test(function(t) {
+ var div = createDiv(t);
+ var animation = div.animate(gKeyFrames, 100 * MS_PER_SEC);
+ animation.currentTime = 100 * MS_PER_SEC;
+ return animation.finished.then(function() {
+ animation.playbackRate = -1;
+ animation.currentTime = -1000;
+ animation.finish();
+
+ assert_equals(animation.currentTime, 0,
+ 'After finishing a reversed animation the currentTime ' +
+ 'should be set back to zero');
+ });
+}, 'Test finishing of reversed animation with a current time less than zero');
+
+promise_test(function(t) {
+ var div = createDiv(t);
+ var animation = div.animate(gKeyFrames, 100 * MS_PER_SEC);
+ animation.pause();
+ return animation.ready.then(function() {
+ animation.finish();
+
+ assert_equals(animation.playState, 'finished',
+ 'The play state of a paused animation should become ' +
+ '"finished" after finish() is called');
+ assert_times_equal(animation.startTime,
+ animation.timeline.currentTime - 100 * MS_PER_SEC,
+ 'The start time of a paused animation should be set ' +
+ 'after calling finish()');
+ });
+}, 'Test finish() while paused');
+
+test(function(t) {
+ var div = createDiv(t);
+ var animation = div.animate(gKeyFrames, 100 * MS_PER_SEC);
+ animation.pause();
+ // Update playbackRate so we can test that the calculated startTime
+ // respects it
+ animation.playbackRate = 2;
+ // While animation is still pause-pending call finish()
+ animation.finish();
+
+ assert_equals(animation.playState, 'finished',
+ 'The play state of a pause-pending animation should become ' +
+ '"finished" after finish() is called');
+ assert_times_equal(animation.startTime,
+ animation.timeline.currentTime - 100 * MS_PER_SEC / 2,
+ 'The start time of a pause-pending animation should ' +
+ 'be set after calling finish()');
+}, 'Test finish() while pause-pending with positive playbackRate');
+
+test(function(t) {
+ var div = createDiv(t);
+ var animation = div.animate(gKeyFrames, 100 * MS_PER_SEC);
+ animation.pause();
+ animation.playbackRate = -2;
+ animation.finish();
+
+ assert_equals(animation.playState, 'finished',
+ 'The play state of a pause-pending animation should become ' +
+ '"finished" after finish() is called');
+ assert_equals(animation.startTime, animation.timeline.currentTime,
+ 'The start time of a pause-pending animation should be ' +
+ 'set after calling finish()');
+}, 'Test finish() while pause-pending with negative playbackRate');
+
+test(function(t) {
+ var div = createDiv(t);
+ var animation = div.animate(gKeyFrames, 100 * MS_PER_SEC);
+ animation.playbackRate = 0.5;
+ animation.finish();
+
+ assert_equals(animation.playState, 'finished',
+ 'The play state of a play-pending animation should become ' +
+ '"finished" after finish() is called');
+ assert_times_equal(animation.startTime,
+ animation.timeline.currentTime - 100 * MS_PER_SEC / 0.5,
+ 'The start time of a play-pending animation should ' +
+ 'be set after calling finish()');
+}, 'Test finish() while play-pending');
+
+// FIXME: Add a test for when we are play-pending without an active timeline.
+// - In that case even after calling finish() we should still be pending but
+// the current time should be updated
+
+promise_test(function(t) {
+ var div = createDiv(t);
+ var animation = div.animate(gKeyFrames, 100 * MS_PER_SEC);
+ return animation.ready.then(function() {
+ animation.pause();
+ animation.play();
+ // We are now in the unusual situation of being play-pending whilst having
+ // a resolved start time. Check that finish() still triggers a transition
+ // to the finished state immediately.
+ animation.finish();
+
+ assert_equals(animation.playState, 'finished',
+ 'After aborting a pause then calling finish() the play ' +
+ 'state of an animation should become "finished" immediately');
+ });
+}, 'Test finish() during aborted pause');
+
+promise_test(function(t) {
+ var div = createDiv(t);
+ div.style.marginLeft = '10px';
+ var animation = div.animate(gKeyFrames, 100 * MS_PER_SEC);
+ return animation.ready.then(function() {
+ animation.finish();
+ var marginLeft = parseFloat(getComputedStyle(div).marginLeft);
+
+ assert_equals(marginLeft, 10,
+ 'The computed style should be reset when finish() is ' +
+ 'called');
+ });
+}, 'Test resetting of computed style');
+
+promise_test(function(t) {
+ var div = createDiv(t);
+ var animation = div.animate(gKeyFrames, 100 * MS_PER_SEC);
+ var resolvedFinished = false;
+ animation.finished.then(function() {
+ resolvedFinished = true;
+ });
+
+ return animation.ready.then(function() {
+ animation.finish();
+ }).then(function() {
+ assert_true(resolvedFinished,
+ 'Animation.finished should be resolved soon after ' +
+ 'Animation.finish()');
+ });
+}, 'Test finish() resolves finished promise synchronously');
+
+promise_test(function(t) {
+ var effect = new KeyframeEffectReadOnly(null, gKeyFrames, 100 * MS_PER_SEC);
+ var animation = new Animation(effect, document.timeline);
+ var resolvedFinished = false;
+ animation.finished.then(function() {
+ resolvedFinished = true;
+ });
+
+ return animation.ready.then(function() {
+ animation.finish();
+ }).then(function() {
+ assert_true(resolvedFinished,
+ 'Animation.finished should be resolved soon after ' +
+ 'Animation.finish()');
+ });
+}, 'Test finish() resolves finished promise synchronously with an animation ' +
+ 'without a target');
+
+promise_test(function(t) {
+ var effect = new KeyframeEffectReadOnly(null, gKeyFrames, 100 * MS_PER_SEC);
+ var animation = new Animation(effect, document.timeline);
+ animation.play();
+
+ var resolvedFinished = false;
+ animation.finished.then(function() {
+ resolvedFinished = true;
+ });
+
+ return animation.ready.then(function() {
+ animation.currentTime = animation.effect.getComputedTiming().endTime - 1;
+ return waitForAnimationFrames(2);
+ }).then(function() {
+ assert_true(resolvedFinished,
+ 'Animation.finished should be resolved soon after ' +
+ 'Animation finishes normally');
+ });
+}, 'Test normally finished animation resolves finished promise synchronously ' +
+ 'with an animation without a target');
+
+</script>
+</body>