[Web Animations] Update WPT tests and move them to imported/w3c/web-platform-tests
[WebKit-https.git] / LayoutTests / imported / w3c / web-platform-tests / web-animations / interfaces / Animation / finish.html
1 <!DOCTYPE html>
2 <meta charset=utf-8>
3 <title>Animation.finish</title>
4 <link rel="help" href="https://drafts.csswg.org/web-animations/#dom-animation-finish">
5 <script src="/resources/testharness.js"></script>
6 <script src="/resources/testharnessreport.js"></script>
7 <script src="../../testcommon.js"></script>
8 <body>
9 <div id="log"></div>
10 <script>
11 'use strict';
12
13 const gKeyFrames = { 'marginLeft': ['100px', '200px'] };
14
15 test(t => {
16   const div = createDiv(t);
17   const animation = div.animate(gKeyFrames, 100 * MS_PER_SEC);
18   animation.playbackRate = 0;
19
20   assert_throws({name: 'InvalidStateError'}, () => {
21     animation.finish();
22   });
23 }, 'Test exceptions when finishing non-running animation');
24
25 test(t => {
26   const div = createDiv(t);
27   const animation = div.animate(gKeyFrames,
28                                 { duration : 100 * MS_PER_SEC,
29                                   iterations : Infinity });
30
31   assert_throws({name: 'InvalidStateError'}, () => {
32     animation.finish();
33   });
34 }, 'Test exceptions when finishing infinite animation');
35
36 test(t => {
37   const div = createDiv(t);
38   const animation = div.animate(gKeyFrames, 100 * MS_PER_SEC);
39   animation.finish();
40
41   assert_equals(animation.currentTime, 100 * MS_PER_SEC,
42                 'After finishing, the currentTime should be set to the end ' +
43                 'of the active duration');
44 }, 'Test finishing of animation');
45
46 test(t => {
47   const div = createDiv(t);
48   const animation = div.animate(gKeyFrames, 100 * MS_PER_SEC);
49    // 1s past effect end
50   animation.currentTime =
51     animation.effect.getComputedTiming().endTime + 1 * MS_PER_SEC;
52   animation.finish();
53
54   assert_equals(animation.currentTime, 100 * MS_PER_SEC,
55                 'After finishing, the currentTime should be set back to the ' +
56                 'end of the active duration');
57 }, 'Test finishing of animation with a current time past the effect end');
58
59 promise_test(t => {
60   const div = createDiv(t);
61   const animation = div.animate(gKeyFrames, 100 * MS_PER_SEC);
62   animation.currentTime = 100 * MS_PER_SEC;
63   return animation.finished.then(() => {
64     animation.playbackRate = -1;
65     animation.finish();
66
67     assert_equals(animation.currentTime, 0,
68                   'After finishing a reversed animation the currentTime ' +
69                   'should be set to zero');
70   });
71 }, 'Test finishing of reversed animation');
72
73 promise_test(t => {
74   const div = createDiv(t);
75   const animation = div.animate(gKeyFrames, 100 * MS_PER_SEC);
76   animation.currentTime = 100 * MS_PER_SEC;
77   return animation.finished.then(() => {
78     animation.playbackRate = -1;
79     animation.currentTime = -1000;
80     animation.finish();
81
82     assert_equals(animation.currentTime, 0,
83                   'After finishing a reversed animation the currentTime ' +
84                   'should be set back to zero');
85   });
86 }, 'Test finishing of reversed animation with a current time less than zero');
87
88 promise_test(t => {
89   const div = createDiv(t);
90   const animation = div.animate(gKeyFrames, 100 * MS_PER_SEC);
91   animation.pause();
92   return animation.ready.then(() => {
93     animation.finish();
94
95     assert_equals(animation.playState, 'finished',
96                   'The play state of a paused animation should become ' +
97                   '"finished" after finish() is called');
98     assert_times_equal(animation.startTime,
99                        animation.timeline.currentTime - 100 * MS_PER_SEC,
100                        'The start time of a paused animation should be set ' +
101                        'after calling finish()');
102   });
103 }, 'Test finish() while paused');
104
105 test(t => {
106   const div = createDiv(t);
107   const animation = div.animate(gKeyFrames, 100 * MS_PER_SEC);
108   animation.pause();
109   // Update playbackRate so we can test that the calculated startTime
110   // respects it
111   animation.playbackRate = 2;
112   // While animation is still pause-pending call finish()
113   animation.finish();
114
115   assert_equals(animation.playState, 'finished',
116                 'The play state of a pause-pending animation should become ' +
117                 '"finished" after finish() is called');
118   assert_times_equal(animation.startTime,
119                      animation.timeline.currentTime - 100 * MS_PER_SEC / 2,
120                      'The start time of a pause-pending animation should ' +
121                      'be set after calling finish()');
122 }, 'Test finish() while pause-pending with positive playbackRate');
123
124 test(t => {
125   const div = createDiv(t);
126   const animation = div.animate(gKeyFrames, 100 * MS_PER_SEC);
127   animation.pause();
128   animation.playbackRate = -2;
129   animation.finish();
130
131   assert_equals(animation.playState, 'finished',
132                 'The play state of a pause-pending animation should become ' +
133                 '"finished" after finish() is called');
134   assert_equals(animation.startTime, animation.timeline.currentTime,
135                 'The start time of a pause-pending animation should be ' +
136                 'set after calling finish()');
137 }, 'Test finish() while pause-pending with negative playbackRate');
138
139 test(t => {
140   const div = createDiv(t);
141   const animation = div.animate(gKeyFrames, 100 * MS_PER_SEC);
142   animation.playbackRate = 0.5;
143   animation.finish();
144
145   assert_equals(animation.playState, 'finished',
146                 'The play state of a play-pending animation should become ' +
147                 '"finished" after finish() is called');
148   assert_times_equal(animation.startTime,
149                      animation.timeline.currentTime - 100 * MS_PER_SEC / 0.5,
150                      'The start time of a play-pending animation should ' +
151                      'be set after calling finish()');
152 }, 'Test finish() while play-pending');
153
154 // FIXME: Add a test for when we are play-pending without an active timeline.
155 // - In that case even after calling finish() we should still be pending but
156 //   the current time should be updated
157
158 promise_test(t => {
159   const div = createDiv(t);
160   const animation = div.animate(gKeyFrames, 100 * MS_PER_SEC);
161   return animation.ready.then(() => {
162     animation.pause();
163     animation.play();
164     // We are now in the unusual situation of being play-pending whilst having
165     // a resolved start time. Check that finish() still triggers a transition
166     // to the finished state immediately.
167     animation.finish();
168
169     assert_equals(animation.playState, 'finished',
170                   'After aborting a pause then calling finish() the play ' +
171                   'state of an animation should become "finished" immediately');
172   });
173 }, 'Test finish() during aborted pause');
174
175 promise_test(t => {
176   const div = createDiv(t);
177   div.style.marginLeft = '10px';
178   const animation = div.animate(gKeyFrames, 100 * MS_PER_SEC);
179   return animation.ready.then(() => {
180     animation.finish();
181     const marginLeft = parseFloat(getComputedStyle(div).marginLeft);
182
183     assert_equals(marginLeft, 10,
184                   'The computed style should be reset when finish() is ' +
185                   'called');
186   });
187 }, 'Test resetting of computed style');
188
189 promise_test(t => {
190   const div = createDiv(t);
191   const animation = div.animate(gKeyFrames, 100 * MS_PER_SEC);
192   let resolvedFinished = false;
193   animation.finished.then(() => {
194     resolvedFinished = true;
195   });
196
197   return animation.ready.then(() => {
198     animation.finish();
199   }).then(() => {
200     assert_true(resolvedFinished,
201       'Animation.finished should be resolved soon after ' +
202       'Animation.finish()');
203   });
204 }, 'Test finish() resolves finished promise synchronously');
205
206 promise_test(t => {
207   const effect = new KeyframeEffectReadOnly(null, gKeyFrames, 100 * MS_PER_SEC);
208   const animation = new Animation(effect, document.timeline);
209   let resolvedFinished = false;
210   animation.finished.then(() => {
211     resolvedFinished = true;
212   });
213
214   return animation.ready.then(() => {
215     animation.finish();
216   }).then(() => {
217     assert_true(resolvedFinished,
218                 'Animation.finished should be resolved soon after ' +
219                 'Animation.finish()');
220   });
221 }, 'Test finish() resolves finished promise synchronously with an animation ' +
222    'without a target');
223
224 promise_test(t => {
225   const effect = new KeyframeEffectReadOnly(null, gKeyFrames, 100 * MS_PER_SEC);
226   const animation = new Animation(effect, document.timeline);
227   animation.play();
228
229   let resolvedFinished = false;
230   animation.finished.then(() => {
231     resolvedFinished = true;
232   });
233
234   return animation.ready.then(() => {
235     animation.currentTime = animation.effect.getComputedTiming().endTime - 1;
236     return waitForAnimationFrames(2);
237   }).then(() => {
238     assert_true(resolvedFinished,
239                 'Animation.finished should be resolved soon after ' +
240                 'Animation finishes normally');
241   });
242 }, 'Test normally finished animation resolves finished promise synchronously ' +
243    'with an animation without a target');
244
245 </script>
246 </body>