| Index: third_party/WebKit/LayoutTests/imported/web-platform-tests/web-animations/animation/finished.html
|
| diff --git a/third_party/WebKit/LayoutTests/imported/web-platform-tests/web-animations/animation/finished.html b/third_party/WebKit/LayoutTests/imported/web-platform-tests/web-animations/animation/finished.html
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..dfd6581604e8ce54513df0594241ac761ed032bb
|
| --- /dev/null
|
| +++ b/third_party/WebKit/LayoutTests/imported/web-platform-tests/web-animations/animation/finished.html
|
| @@ -0,0 +1,371 @@
|
| +<!DOCTYPE html>
|
| +<meta charset=utf-8>
|
| +<title>Animation.finished</title>
|
| +<link rel="help" href="https://w3c.github.io/web-animations/#dom-animation-finished">
|
| +<script src="../../../../resources/testharness.js"></script>
|
| +<script src="../../../../resources/testharnessreport.js"></script>
|
| +<script src="../testcommon.js"></script>
|
| +<link rel="stylesheet" href="../../../../resources/testharness.css">
|
| +<body>
|
| +<div id="log"></div>
|
| +<script>
|
| +"use strict";
|
| +
|
| +promise_test(function(t) {
|
| + var div = createDiv(t);
|
| + var animation = div.animate({}, 100 * MS_PER_SEC);
|
| + var previousFinishedPromise = animation.finished;
|
| + return animation.ready.then(function() {
|
| + assert_equals(animation.finished, previousFinishedPromise,
|
| + 'Finished promise is the same object when playing starts');
|
| + animation.pause();
|
| + assert_equals(animation.finished, previousFinishedPromise,
|
| + 'Finished promise does not change when pausing');
|
| + animation.play();
|
| + assert_equals(animation.finished, previousFinishedPromise,
|
| + 'Finished promise does not change when play() unpauses');
|
| +
|
| + animation.currentTime = 100 * MS_PER_SEC;
|
| +
|
| + return animation.finished;
|
| + }).then(function() {
|
| + assert_equals(animation.finished, previousFinishedPromise,
|
| + 'Finished promise is the same object when playing completes');
|
| + });
|
| +}, 'Test pausing then playing does not change the finished promise');
|
| +
|
| +promise_test(function(t) {
|
| + var div = createDiv(t);
|
| + var animation = div.animate({}, 100 * MS_PER_SEC);
|
| + var previousFinishedPromise = animation.finished;
|
| + animation.finish();
|
| + return animation.finished.then(function() {
|
| + assert_equals(animation.finished, previousFinishedPromise,
|
| + 'Finished promise is the same object when playing completes');
|
| + animation.play();
|
| + assert_not_equals(animation.finished, previousFinishedPromise,
|
| + 'Finished promise changes when replaying animation');
|
| +
|
| + previousFinishedPromise = animation.finished;
|
| + animation.play();
|
| + assert_equals(animation.finished, previousFinishedPromise,
|
| + 'Finished promise is the same after redundant play() call');
|
| +
|
| + });
|
| +}, 'Test restarting a finished animation');
|
| +
|
| +promise_test(function(t) {
|
| + var div = createDiv(t);
|
| + var animation = div.animate({}, 100 * MS_PER_SEC);
|
| + var previousFinishedPromise;
|
| + animation.finish();
|
| + return animation.finished.then(function() {
|
| + previousFinishedPromise = animation.finished;
|
| + animation.playbackRate = -1;
|
| + assert_not_equals(animation.finished, previousFinishedPromise,
|
| + 'Finished promise should be replaced when reversing a ' +
|
| + 'finished promise');
|
| + animation.currentTime = 0;
|
| + return animation.finished;
|
| + }).then(function() {
|
| + previousFinishedPromise = animation.finished;
|
| + animation.play();
|
| + assert_not_equals(animation.finished, previousFinishedPromise,
|
| + 'Finished promise is replaced after play() call on ' +
|
| + 'finished, reversed animation');
|
| + });
|
| +}, 'Test restarting a reversed finished animation');
|
| +
|
| +promise_test(function(t) {
|
| + var div = createDiv(t);
|
| + var animation = div.animate({}, 100 * MS_PER_SEC);
|
| + var previousFinishedPromise = animation.finished;
|
| + animation.finish();
|
| + return animation.finished.then(function() {
|
| + animation.currentTime = 100 * MS_PER_SEC + 1000;
|
| + assert_equals(animation.finished, previousFinishedPromise,
|
| + 'Finished promise is unchanged jumping past end of ' +
|
| + 'finished animation');
|
| + });
|
| +}, 'Test redundant finishing of animation');
|
| +
|
| +promise_test(function(t) {
|
| + var div = createDiv(t);
|
| + var animation = div.animate({}, 100 * MS_PER_SEC);
|
| + // Setup callback to run if finished promise is resolved
|
| + var finishPromiseResolved = false;
|
| + animation.finished.then(function() {
|
| + finishPromiseResolved = true;
|
| + });
|
| + return animation.ready.then(function() {
|
| + // Jump to mid-way in interval and pause
|
| + animation.currentTime = 100 * MS_PER_SEC / 2;
|
| + animation.pause();
|
| + return animation.ready;
|
| + }).then(function() {
|
| + // Jump to the end
|
| + // (But don't use finish() since that should unpause as well)
|
| + animation.currentTime = 100 * MS_PER_SEC;
|
| + return waitForAnimationFrames(2);
|
| + }).then(function() {
|
| + assert_false(finishPromiseResolved,
|
| + 'Finished promise should not resolve when paused');
|
| + });
|
| +}, 'Finished promise does not resolve when paused');
|
| +
|
| +promise_test(function(t) {
|
| + var div = createDiv(t);
|
| + var animation = div.animate({}, 100 * MS_PER_SEC);
|
| + // Setup callback to run if finished promise is resolved
|
| + var finishPromiseResolved = false;
|
| + animation.finished.then(function() {
|
| + finishPromiseResolved = true;
|
| + });
|
| + return animation.ready.then(function() {
|
| + // Jump to mid-way in interval and pause
|
| + animation.currentTime = 100 * MS_PER_SEC / 2;
|
| + animation.pause();
|
| + // Jump to the end
|
| + animation.currentTime = 100 * MS_PER_SEC;
|
| + return waitForAnimationFrames(2);
|
| + }).then(function() {
|
| + assert_false(finishPromiseResolved,
|
| + 'Finished promise should not resolve when pause-pending');
|
| + });
|
| +}, 'Finished promise does not resolve when pause-pending');
|
| +
|
| +promise_test(function(t) {
|
| + var div = createDiv(t);
|
| + var animation = div.animate({}, 100 * MS_PER_SEC);
|
| + animation.finish();
|
| + return animation.finished.then(function(resolvedAnimation) {
|
| + assert_equals(resolvedAnimation, animation,
|
| + 'Object identity of animation passed to Promise callback'
|
| + + ' matches the animation object owning the Promise');
|
| + });
|
| +}, 'The finished promise is fulfilled with its Animation');
|
| +
|
| +promise_test(function(t) {
|
| + var div = createDiv(t);
|
| + var animation = div.animate({}, 100 * MS_PER_SEC);
|
| + var previousFinishedPromise = animation.finished;
|
| +
|
| + // Set up listeners on finished promise
|
| + var retPromise = animation.finished.then(function() {
|
| + assert_unreached('finished promise was fulfilled');
|
| + }).catch(function(err) {
|
| + assert_equals(err.name, 'AbortError',
|
| + 'finished promise is rejected with AbortError');
|
| + assert_not_equals(animation.finished, previousFinishedPromise,
|
| + 'Finished promise should change after the original is ' +
|
| + 'rejected');
|
| + });
|
| +
|
| + animation.cancel();
|
| +
|
| + return retPromise;
|
| +}, 'finished promise is rejected when an animation is cancelled by calling ' +
|
| + 'cancel()');
|
| +
|
| +promise_test(function(t) {
|
| + var div = createDiv(t);
|
| + var animation = div.animate({}, 100 * MS_PER_SEC);
|
| + var previousFinishedPromise = animation.finished;
|
| + animation.finish();
|
| + return animation.finished.then(function() {
|
| + animation.cancel();
|
| + assert_not_equals(animation.finished, previousFinishedPromise,
|
| + 'A new finished promise should be created when'
|
| + + ' cancelling a finished animation');
|
| + });
|
| +}, 'cancelling an already-finished animation replaces the finished promise');
|
| +
|
| +promise_test(function(t) {
|
| + var div = createDiv(t);
|
| + var animation = div.animate({}, 100 * MS_PER_SEC);
|
| + animation.cancel();
|
| + // The spec says we still create a new finished promise and reject the old
|
| + // one even if we're already idle. That behavior might change, but for now
|
| + // test that we do that.
|
| + var retPromise = animation.finished.catch(function(err) {
|
| + assert_equals(err.name, 'AbortError',
|
| + 'finished promise is rejected with AbortError');
|
| + });
|
| +
|
| + // Redundant call to cancel();
|
| + var previousFinishedPromise = animation.finished;
|
| + animation.cancel();
|
| + assert_not_equals(animation.finished, previousFinishedPromise,
|
| + 'A redundant call to cancel() should still generate a new'
|
| + + ' finished promise');
|
| + return retPromise;
|
| +}, 'cancelling an idle animation still replaces the finished promise');
|
| +
|
| +promise_test(function(t) {
|
| + var div = createDiv(t);
|
| + var animation = div.animate({}, 100 * MS_PER_SEC);
|
| + const HALF_DUR = 100 * MS_PER_SEC / 2;
|
| + const QUARTER_DUR = 100 * MS_PER_SEC / 4;
|
| + var gotNextFrame = false;
|
| + var currentTimeBeforeShortening;
|
| + animation.currentTime = HALF_DUR;
|
| + return animation.ready.then(function() {
|
| + currentTimeBeforeShortening = animation.currentTime;
|
| + animation.effect.timing.duration = QUARTER_DUR;
|
| + // Below we use gotNextFrame to check that shortening of the animation
|
| + // duration causes the finished promise to resolve, rather than it just
|
| + // getting resolved on the next animation frame. This relies on the fact
|
| + // that the promises are resolved as a micro-task before the next frame
|
| + // happens.
|
| + waitForAnimationFrames(1).then(function() {
|
| + gotNextFrame = true;
|
| + });
|
| +
|
| + return animation.finished;
|
| + }).then(function() {
|
| + assert_false(gotNextFrame, 'shortening of the animation duration should ' +
|
| + 'resolve the finished promise');
|
| + assert_equals(animation.currentTime, currentTimeBeforeShortening,
|
| + 'currentTime should be unchanged when duration shortened');
|
| + var previousFinishedPromise = animation.finished;
|
| + animation.effect.timing.duration = 100 * MS_PER_SEC;
|
| + assert_not_equals(animation.finished, previousFinishedPromise,
|
| + 'Finished promise should change after lengthening the ' +
|
| + 'duration causes the animation to become active');
|
| + });
|
| +}, 'Test finished promise changes for animation duration changes');
|
| +
|
| +promise_test(function(t) {
|
| + var div = createDiv(t);
|
| + var animation = div.animate({}, 100 * MS_PER_SEC);
|
| + var retPromise = animation.ready.then(function() {
|
| + animation.playbackRate = 0;
|
| + animation.currentTime = 100 * MS_PER_SEC + 1000;
|
| + return waitForAnimationFrames(2);
|
| + });
|
| +
|
| + animation.finished.then(t.step_func(function() {
|
| + assert_unreached('finished promise should not resolve when playbackRate ' +
|
| + 'is zero');
|
| + }));
|
| +
|
| + return retPromise;
|
| +}, 'Test finished promise changes when playbackRate == 0');
|
| +
|
| +promise_test(function(t) {
|
| + var div = createDiv(t);
|
| + var animation = div.animate({}, 100 * MS_PER_SEC);
|
| + return animation.ready.then(function() {
|
| + animation.playbackRate = -1;
|
| + return animation.finished;
|
| + });
|
| +}, 'Test finished promise resolves when reaching to the natural boundary.');
|
| +
|
| +promise_test(function(t) {
|
| + var div = createDiv(t);
|
| + var animation = div.animate({}, 100 * MS_PER_SEC);
|
| + var previousFinishedPromise = animation.finished;
|
| + animation.finish();
|
| + return animation.finished.then(function() {
|
| + animation.currentTime = 0;
|
| + assert_not_equals(animation.finished, previousFinishedPromise,
|
| + 'Finished promise should change once a prior ' +
|
| + 'finished promise resolved and the animation ' +
|
| + 'falls out finished state');
|
| + });
|
| +}, 'Test finished promise changes when a prior finished promise resolved ' +
|
| + 'and the animation falls out finished state');
|
| +
|
| +test(function(t) {
|
| + var div = createDiv(t);
|
| + var animation = div.animate({}, 100 * MS_PER_SEC);
|
| + var previousFinishedPromise = animation.finished;
|
| + animation.currentTime = 100 * MS_PER_SEC;
|
| + animation.currentTime = 100 * MS_PER_SEC / 2;
|
| + assert_equals(animation.finished, previousFinishedPromise,
|
| + 'No new finished promise generated when finished state ' +
|
| + 'is checked asynchronously');
|
| +}, 'Test no new finished promise generated when finished state ' +
|
| + 'is checked asynchronously');
|
| +
|
| +test(function(t) {
|
| + var div = createDiv(t);
|
| + var animation = div.animate({}, 100 * MS_PER_SEC);
|
| + var previousFinishedPromise = animation.finished;
|
| + animation.finish();
|
| + animation.currentTime = 100 * MS_PER_SEC / 2;
|
| + assert_not_equals(animation.finished, previousFinishedPromise,
|
| + 'New finished promise generated when finished state ' +
|
| + 'is checked synchronously');
|
| +}, 'Test new finished promise generated when finished state ' +
|
| + 'is checked synchronously');
|
| +
|
| +promise_test(function(t) {
|
| + var div = createDiv(t);
|
| + var animation = div.animate({}, 100 * MS_PER_SEC);
|
| + var resolvedFinished = false;
|
| + animation.finished.then(function() {
|
| + resolvedFinished = true;
|
| + });
|
| + return animation.ready.then(function() {
|
| + animation.finish();
|
| + animation.currentTime = 100 * MS_PER_SEC / 2;
|
| + }).then(function() {
|
| + assert_true(resolvedFinished,
|
| + 'Animation.finished should be resolved even if ' +
|
| + 'the finished state is changed soon');
|
| + });
|
| +
|
| +}, 'Test synchronous finished promise resolved even if finished state ' +
|
| + 'is changed soon');
|
| +
|
| +promise_test(function(t) {
|
| + var div = createDiv(t);
|
| + var animation = div.animate({}, 100 * MS_PER_SEC);
|
| + var resolvedFinished = false;
|
| + animation.finished.then(function() {
|
| + resolvedFinished = true;
|
| + });
|
| +
|
| + return animation.ready.then(function() {
|
| + animation.currentTime = 100 * MS_PER_SEC;
|
| + animation.finish();
|
| + }).then(function() {
|
| + assert_true(resolvedFinished,
|
| + 'Animation.finished should be resolved soon after finish() is ' +
|
| + 'called even if there are other asynchronous promises just before it');
|
| + });
|
| +}, 'Test synchronous finished promise resolved even if asynchronous ' +
|
| + 'finished promise happens just before synchronous promise');
|
| +
|
| +promise_test(function(t) {
|
| + var div = createDiv(t);
|
| + var animation = div.animate({}, 100 * MS_PER_SEC);
|
| + animation.finished.then(t.step_func(function() {
|
| + assert_unreached('Animation.finished should not be resolved');
|
| + }));
|
| +
|
| + return animation.ready.then(function() {
|
| + animation.currentTime = 100 * MS_PER_SEC;
|
| + animation.currentTime = 100 * MS_PER_SEC / 2;
|
| + });
|
| +}, 'Test finished promise is not resolved when the animation ' +
|
| + 'falls out finished state immediately');
|
| +
|
| +promise_test(function(t) {
|
| + var div = createDiv(t);
|
| + var animation = div.animate({}, 100 * MS_PER_SEC);
|
| + return animation.ready.then(function() {
|
| + animation.currentTime = 100 * MS_PER_SEC;
|
| + animation.finished.then(t.step_func(function() {
|
| + assert_unreached('Animation.finished should not be resolved');
|
| + }));
|
| + animation.currentTime = 0;
|
| + });
|
| +
|
| +}, 'Test finished promise is not resolved once the animation ' +
|
| + 'falls out finished state even though the current finished ' +
|
| + 'promise is generated soon after animation state became finished');
|
| +
|
| +</script>
|
| +</body>
|
|
|