diff options
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.html | 246 |
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> |