d2ad6f6da7c18615fa626989413519cecaca70ee
[WebKit-https.git] / LayoutTests / imported / mozilla / css-animations / test_animation-computed-timing.html
1 <!doctype html>
2 <meta charset=utf-8>
3 <script src="../../../resources/testharness.js"></script>
4 <script src="../../../resources/testharnessreport.js"></script>
5 <script src="../resources/testcommon.js"></script>
6 <style>
7 @keyframes moveAnimation {
8   from { margin-left: 100px }
9   to { margin-left: 200px }
10 }
11 </style>
12 <body>
13 <div id="log"></div>
14 <script>
15
16 'use strict';
17
18 // --------------------
19 // delay
20 // --------------------
21 test(function(t) {
22   var div = addDiv(t, {style: 'animation: moveAnimation 100s'});
23   var effect = div.getAnimations()[0].effect;
24   assert_equals(effect.getComputedTiming().delay, 0,
25                 'Initial value of delay');
26 }, 'delay of a new animation');
27
28 test(function(t) {
29   var div = addDiv(t, {style: 'animation: moveAnimation 100s -10s'});
30   var effect = div.getAnimations()[0].effect;
31   assert_equals(effect.getComputedTiming().delay, -10 * MS_PER_SEC,
32                 'Initial value of delay');
33 }, 'Negative delay of a new animation');
34
35 test(function(t) {
36   var div = addDiv(t, {style: 'animation: moveAnimation 100s 10s'});
37   var effect = div.getAnimations()[0].effect;
38   assert_equals(effect.getComputedTiming().delay, 10 * MS_PER_SEC,
39                 'Initial value of delay');
40 }, 'Positive delay of a new animation');
41
42
43 // --------------------
44 // endDelay
45 // --------------------
46 test(function(t) {
47   var div = addDiv(t, {style: 'animation: moveAnimation 100s'});
48   var effect = div.getAnimations()[0].effect;
49   assert_equals(effect.getComputedTiming().endDelay, 0,
50                 'Initial value of endDelay');
51 }, 'endDelay of a new animation');
52
53
54 // --------------------
55 // fill
56 // --------------------
57 test(function(t) {
58   var getEffectWithFill = function(fill) {
59     var div = addDiv(t, {style: 'animation: moveAnimation 100s ' + fill});
60     return div.getAnimations()[0].effect;
61   };
62
63   var effect = getEffectWithFill('');
64   assert_equals(effect.getComputedTiming().fill, 'none',
65                 'Initial value of fill');
66   effect = getEffectWithFill('forwards');
67   assert_equals(effect.getComputedTiming().fill, 'forwards',
68                 'Fill forwards');
69   effect = getEffectWithFill('backwards');
70   assert_equals(effect.getComputedTiming().fill, 'backwards',
71                 'Fill backwards');
72   effect = getEffectWithFill('both');
73   assert_equals(effect.getComputedTiming().fill, 'both',
74                 'Fill forwards and backwards');
75 }, 'fill of a new animation');
76
77
78 // --------------------
79 // iterationStart
80 // --------------------
81 test(function(t) {
82   var div = addDiv(t, {style: 'animation: moveAnimation 100s'});
83   var effect = div.getAnimations()[0].effect;
84   assert_equals(effect.getComputedTiming().iterationStart, 0,
85                 'Initial value of iterationStart');
86 }, 'iterationStart of a new animation');
87
88
89 // --------------------
90 // iterations
91 // --------------------
92 test(function(t) {
93   var div = addDiv(t, {style: 'animation: moveAnimation 100s'});
94   var effect = div.getAnimations()[0].effect;
95   assert_equals(effect.getComputedTiming().iterations, 1,
96                 'Initial value of iterations');
97 }, 'iterations of a new animation');
98
99 test(function(t) {
100   var div = addDiv(t, {style: 'animation: moveAnimation 100s 2016.5'});
101   var effect = div.getAnimations()[0].effect;
102   assert_equals(effect.getComputedTiming().iterations, 2016.5,
103                 'Initial value of iterations');
104 }, 'iterations of a finitely repeating animation');
105
106 test(function(t) {
107   var div = addDiv(t, {style: 'animation: moveAnimation 100s infinite'});
108   var effect = div.getAnimations()[0].effect;
109   assert_equals(effect.getComputedTiming().iterations, Infinity,
110                 'Initial value of iterations');
111 }, 'iterations of an infinitely repeating animation');
112
113
114 // --------------------
115 // duration
116 // --------------------
117 test(function(t) {
118   var div = addDiv(t, {style: 'animation: moveAnimation 100s -10s infinite'});
119   var effect = div.getAnimations()[0].effect;
120   assert_equals(effect.getComputedTiming().duration, 100 * MS_PER_SEC,
121                 'Initial value of duration');
122 }, 'duration of a new animation');
123
124
125 // --------------------
126 // direction
127 // --------------------
128 test(function(t) {
129   var getEffectWithDir = function(dir) {
130     var div = addDiv(t, {style: 'animation: moveAnimation 100s ' + dir});
131     return div.getAnimations()[0].effect;
132   };
133
134   var effect = getEffectWithDir('');
135   assert_equals(effect.getComputedTiming().direction, 'normal',
136                 'Initial value of normal direction');
137   effect = getEffectWithDir('reverse');
138   assert_equals(effect.getComputedTiming().direction, 'reverse',
139                 'Initial value of reverse direction');
140   effect = getEffectWithDir('alternate');
141   assert_equals(effect.getComputedTiming().direction, 'alternate',
142                 'Initial value of alternate direction');
143   effect = getEffectWithDir('alternate-reverse');
144   assert_equals(effect.getComputedTiming().direction, 'alternate-reverse',
145                 'Initial value of alternate-reverse direction');
146 }, 'direction of a new animation');
147
148
149 // --------------------
150 // easing
151 // --------------------
152 test(function(t) {
153   var div = addDiv(t, {style: 'animation: moveAnimation 100s'});
154   var effect = div.getAnimations()[0].effect;
155   assert_equals(effect.getComputedTiming().easing, 'linear',
156                 'Initial value of easing');
157 }, 'easing of a new animation');
158
159
160 // ------------------------------
161 // endTime
162 // = max(start delay + active duration + end delay, 0)
163 // --------------------
164 test(function(t) {
165   var div = addDiv(t, {style: 'animation: moveAnimation 100s'});
166   var effect = div.getAnimations()[0].effect;
167   assert_equals(effect.getComputedTiming().endTime, 100 * MS_PER_SEC,
168                 'Initial value of endTime');
169 }, 'endTime of an new animation');
170
171 test(function(t) {
172   var div = addDiv(t, {style: 'animation: moveAnimation 100s -5s'});
173   var effect = div.getAnimations()[0].effect;
174   var answer = (100 - 5) * MS_PER_SEC;
175   assert_equals(effect.getComputedTiming().endTime, answer,
176                 'Initial value of endTime');
177 }, 'endTime of an animation with a negative delay');
178
179 test(function(t) {
180   var div = addDiv(t, {style: 'animation: moveAnimation 10s -100s infinite'});
181   var effect = div.getAnimations()[0].effect;
182   assert_equals(effect.getComputedTiming().endTime, Infinity,
183                 'Initial value of endTime');
184 }, 'endTime of an infinitely repeating animation');
185
186 test(function(t) {
187   var div = addDiv(t, {style: 'animation: moveAnimation 0s 100s infinite'});
188   var effect = div.getAnimations()[0].effect;
189   assert_equals(effect.getComputedTiming().endTime, 100 * MS_PER_SEC,
190                 'Initial value of endTime');
191 }, 'endTime of an infinitely repeating zero-duration animation');
192
193 test(function(t) {
194   // Fill forwards so div.getAnimations()[0] won't return an
195   // undefined value.
196   var div = addDiv(t, {style: 'animation: moveAnimation 10s -100s forwards'});
197   var effect = div.getAnimations()[0].effect;
198   assert_equals(effect.getComputedTiming().endTime, 0,
199                 'Initial value of endTime');
200 }, 'endTime of an animation that finishes before its startTime');
201
202
203 // --------------------
204 // activeDuration
205 // = iteration duration * iteration count
206 // --------------------
207 test(function(t) {
208   var div = addDiv(t, {style: 'animation: moveAnimation 100s 5'});
209   var effect = div.getAnimations()[0].effect;
210   var answer = 100 * MS_PER_SEC * 5;
211   assert_equals(effect.getComputedTiming().activeDuration, answer,
212                 'Initial value of activeDuration');
213 }, 'activeDuration of a new animation');
214
215 test(function(t) {
216   var div = addDiv(t, {style: 'animation: moveAnimation 100s infinite'});
217   var effect = div.getAnimations()[0].effect;
218   assert_equals(effect.getComputedTiming().activeDuration, Infinity,
219                 'Initial value of activeDuration');
220 }, 'activeDuration of an infinitely repeating animation');
221
222 test(function(t) {
223   var div = addDiv(t, {style: 'animation: moveAnimation 0s 1s infinite'});
224   var effect = div.getAnimations()[0].effect;
225   // If either the iteration duration or iteration count are zero,
226   // the active duration is zero.
227   assert_equals(effect.getComputedTiming().activeDuration, 0,
228                 'Initial value of activeDuration');
229 }, 'activeDuration of an infinitely repeating zero-duration animation');
230
231 test(function(t) {
232   var div = addDiv(t, {style: 'animation: moveAnimation 100s 1s 0'});
233   var effect = div.getAnimations()[0].effect;
234   // If either the iteration duration or iteration count are zero,
235   // the active duration is zero.
236   assert_equals(effect.getComputedTiming().activeDuration, 0,
237                 'Initial value of activeDuration');
238 }, 'activeDuration of an animation with zero iterations');
239
240
241 // --------------------
242 // localTime
243 // --------------------
244 test(function(t) {
245   var div = addDiv(t, {style: 'animation: moveAnimation 100s'});
246   var effect = div.getAnimations()[0].effect;
247   assert_equals(effect.getComputedTiming().localTime, 0,
248                 'Initial value of localTime');
249 }, 'localTime of a new animation');
250
251 test(function(t) {
252   var div = addDiv(t, {style: 'animation: moveAnimation 100s'});
253   var anim = div.getAnimations()[0];
254   anim.currentTime = 5 * MS_PER_SEC;
255   assert_equals(anim.effect.getComputedTiming().localTime, anim.currentTime,
256                 'current localTime after setting currentTime');
257 }, 'localTime of an animation is always equal to currentTime');
258
259 promise_test(function(t) {
260   var div = addDiv(t, {style: 'animation: moveAnimation 100s'});
261
262   var anim = div.getAnimations()[0];
263   anim.playbackRate = 2; // 2 times faster
264
265   return anim.ready.then(function() {
266     assert_equals(anim.effect.getComputedTiming().localTime, anim.currentTime,
267                   'localTime is equal to currentTime');
268     return waitForFrame();
269   }).then(function() {
270     assert_equals(anim.effect.getComputedTiming().localTime, anim.currentTime,
271                   'localTime is equal to currentTime');
272   });
273 }, 'localTime reflects playbackRate immediately');
274
275 test(function(t) {
276   var div = addDiv(t);
277   var effect = new KeyframeEffect(div, {left: ["0px", "100px"]});
278
279   assert_equals(effect.getComputedTiming().localTime, null,
280                 'localTime for orphaned effect');
281 }, 'localTime of an AnimationEffect without an Animation');
282
283
284 // --------------------
285 // progress
286 // Note: Default timing function is linear.
287 // --------------------
288 test(function(t) {
289   [{fill: '',          progress: [ null, null ]},
290    {fill: 'none',      progress: [ null, null ]},
291    {fill: 'forwards',  progress: [ null, 1.0 ]},
292    {fill: 'backwards', progress: [ 0.0, null ]},
293    {fill: 'both',      progress: [ 0.0, 1.0 ]}]
294   .forEach(function(test) {
295     var div =
296       addDiv(t, {style: 'animation: moveAnimation 100s 10s ' + test.fill});
297     var anim = div.getAnimations()[0];
298     assert_true(anim.effect.getComputedTiming().progress === test.progress[0],
299                 'initial progress with "' + test.fill + '" fill');
300     anim.finish();
301     assert_true(anim.effect.getComputedTiming().progress === test.progress[1],
302                 'finished progress with "' + test.fill + '" fill');
303   });
304 }, 'progress of an animation with different fill modes');
305
306 test(function(t) {
307   var div = addDiv(t, {style: 'animation: moveAnimation 10s 10 both'});
308   var anim = div.getAnimations()[0];
309
310   assert_equals(anim.effect.getComputedTiming().progress, 0.0,
311                 'Initial value of progress');
312   anim.currentTime += 2.5 * MS_PER_SEC;
313   assert_equals(anim.effect.getComputedTiming().progress, 0.25,
314                 'Value of progress');
315   anim.currentTime += 5 * MS_PER_SEC;
316   assert_equals(anim.effect.getComputedTiming().progress, 0.75,
317                 'Value of progress');
318   anim.currentTime += 5 * MS_PER_SEC;
319   assert_equals(anim.effect.getComputedTiming().progress, 0.25,
320                 'Value of progress');
321   anim.finish()
322   assert_equals(anim.effect.getComputedTiming().progress, 1.0,
323                 'Value of progress');
324 }, 'progress of an integral repeating animation with normal direction');
325
326 test(function(t) {
327   var div = addDiv(t);
328   // Note: FillMode here is "both" because
329   // 1. Since this a zero-duration animation, it will already have finished
330   //    so it won't be returned by getAnimations() unless it fills forwards.
331   // 2. Fill backwards, so the progress before phase wouldn't be
332   //    unresolved (null value).
333   var div = addDiv(t, {style: 'animation: moveAnimation 0s infinite both'});
334   var anim = div.getAnimations()[0];
335
336   assert_equals(anim.effect.getComputedTiming().progress, 1.0,
337                 'Initial value of progress in after phase');
338
339   // Seek backwards
340   anim.currentTime -= 1 * MS_PER_SEC;
341   assert_equals(anim.effect.getComputedTiming().progress, 0.0,
342                 'Value of progress before phase');
343 }, 'progress of an infinitely repeating zero-duration animation');
344
345 test(function(t) {
346   // Default iterations = 1
347   var div = addDiv(t, {style: 'animation: moveAnimation 0s both'});
348   var anim = div.getAnimations()[0];
349
350   assert_equals(anim.effect.getComputedTiming().progress, 1.0,
351                 'Initial value of progress in after phase');
352
353   // Seek backwards
354   anim.currentTime -= 1 * MS_PER_SEC;
355   assert_equals(anim.effect.getComputedTiming().progress, 0.0,
356                 'Value of progress before phase');
357 }, 'progress of a finitely repeating zero-duration animation');
358
359 test(function(t) {
360   var div = addDiv(t, {style: 'animation: moveAnimation 0s 5s 10.25 both'});
361   var anim = div.getAnimations()[0];
362
363   assert_equals(anim.effect.getComputedTiming().progress, 0.0,
364                 'Initial value of progress (before phase)');
365
366   // Using iteration duration of 1 now.
367   // currentIteration now is floor(10.25) = 10, so progress should be 25%.
368   anim.finish();
369   assert_equals(anim.effect.getComputedTiming().progress, 0.25,
370                 'Value of progress in after phase');
371 }, 'progress of a non-integral repeating zero-duration animation');
372
373 test(function(t) {
374   var div = addDiv(t, {style: 'animation: moveAnimation 0s 5s 10.25 both reverse'});
375   var anim = div.getAnimations()[0];
376
377   assert_equals(anim.effect.getComputedTiming().progress, 1.0,
378                 'Initial value of progress (before phase)');
379
380   // Seek forwards
381   anim.finish();
382   assert_equals(anim.effect.getComputedTiming().progress, 0.75,
383                 'Value of progress in after phase');
384 }, 'Progress of a non-integral repeating zero-duration animation ' +
385    'with reversing direction');
386
387 test(function(t) {
388   var div = addDiv(t, {style: 'animation: moveAnimation 10s 10.25 both alternate'});
389   var anim = div.getAnimations()[0];
390
391   assert_equals(anim.effect.getComputedTiming().progress, 0.0,
392                 'Initial value of progress');
393   anim.currentTime += 2.5 * MS_PER_SEC;
394   assert_equals(anim.effect.getComputedTiming().progress, 0.25,
395                 'Value of progress');
396   anim.currentTime += 5 * MS_PER_SEC;
397   assert_equals(anim.effect.getComputedTiming().progress, 0.75,
398                 'Value of progress');
399   anim.currentTime += 5 * MS_PER_SEC;
400   assert_equals(anim.effect.getComputedTiming().progress, 0.75,
401                 'Value of progress');
402   anim.finish()
403   assert_equals(anim.effect.getComputedTiming().progress, 0.25,
404                 'Value of progress');
405 }, 'progress of a non-integral repeating animation ' +
406    'with alternate direction');
407
408 test(function(t) {
409   var div = addDiv(t, {style: 'animation: moveAnimation 10s 10.25 both alternate-reverse'});
410   var anim = div.getAnimations()[0];
411
412   assert_equals(anim.effect.getComputedTiming().progress, 1.0,
413                 'Initial value of progress');
414   anim.currentTime += 2.5 * MS_PER_SEC;
415   assert_equals(anim.effect.getComputedTiming().progress, 0.75,
416                 'Value of progress');
417   anim.currentTime += 5 * MS_PER_SEC;
418   assert_equals(anim.effect.getComputedTiming().progress, 0.25,
419                 'Value of progress');
420   anim.currentTime += 5 * MS_PER_SEC;
421   assert_equals(anim.effect.getComputedTiming().progress, 0.25,
422                 'Value of progress');
423   anim.finish()
424   assert_equals(anim.effect.getComputedTiming().progress, 0.75,
425                 'Value of progress');
426 }, 'progress of a non-integral repeating animation ' +
427    'with alternate-reversing direction');
428
429 test(function(t) {
430   var div = addDiv(t, {style: 'animation: moveAnimation 0s 10.25 both alternate'});
431   var anim = div.getAnimations()[0];
432
433   assert_equals(anim.effect.getComputedTiming().progress, 0.25,
434                 'Initial value of progress');
435   anim.currentTime += 2.5 * MS_PER_SEC;
436   assert_equals(anim.effect.getComputedTiming().progress, 0.25,
437                 'Value of progress');
438   anim.currentTime -= 5 * MS_PER_SEC;
439   assert_equals(anim.effect.getComputedTiming().progress, 0.0,
440                 'Value of progress');
441   anim.finish()
442   assert_equals(anim.effect.getComputedTiming().progress, 0.25,
443                 'Value of progress');
444 }, 'progress of a non-integral repeating zero-duration animation ' +
445    'with alternate direction');
446
447 test(function(t) {
448   var div = addDiv(t, {style: 'animation: moveAnimation 0s 10.25 both alternate-reverse'});
449   var anim = div.getAnimations()[0];
450
451   assert_equals(anim.effect.getComputedTiming().progress, 0.75,
452                 'Initial value of progress');
453   anim.currentTime += 2.5 * MS_PER_SEC;
454   assert_equals(anim.effect.getComputedTiming().progress, 0.75,
455                 'Value of progress');
456   anim.currentTime -= 5 * MS_PER_SEC;
457   assert_equals(anim.effect.getComputedTiming().progress, 1.0,
458                 'Value of progress');
459   anim.finish()
460   assert_equals(anim.effect.getComputedTiming().progress, 0.75,
461                 'Value of progress');
462 }, 'progress of a non-integral repeating zero-duration animation ' +
463    'with alternate-reverse direction');
464
465
466 // --------------------
467 // currentIteration
468 // --------------------
469 test(function(t) {
470   var div = addDiv(t, {style: 'animation: moveAnimation 100s 2s'});
471   var effect = div.getAnimations()[0].effect;
472   assert_equals(effect.getComputedTiming().currentIteration, null,
473                 'Initial value of currentIteration before phase');
474 }, 'currentIteration of a new animation with no backwards fill is unresolved ' +
475    'in before phase');
476
477 test(function(t) {
478   var div = addDiv(t, {style: 'animation: moveAnimation 100s'});
479   var anim = div.getAnimations()[0];
480   assert_equals(anim.effect.getComputedTiming().currentIteration, 0,
481                 'Initial value of currentIteration');
482 }, 'currentIteration of a new animation is zero');
483
484 test(function(t) {
485   // Note: FillMode here is "both" because
486   // 1. Since this a zero-duration animation, it will already have finished
487   //    so it won't be returned by getAnimations() unless it fills forwards.
488   // 2. Fill backwards, so the currentIteration (before phase) wouldn't be
489   //    unresolved (null value).
490   var div = addDiv(t, {style: 'animation: moveAnimation 0s infinite both'});
491   var anim = div.getAnimations()[0];
492
493   assert_equals(anim.effect.getComputedTiming().currentIteration, Infinity,
494                 'Initial value of currentIteration in after phase');
495
496   // Seek backwards
497   anim.currentTime -= 2 * MS_PER_SEC;
498   assert_equals(anim.effect.getComputedTiming().currentIteration, 0,
499                 'Value of currentIteration count during before phase');
500 }, 'currentIteration of an infinitely repeating zero-duration animation');
501
502 test(function(t) {
503   var div = addDiv(t, {style: 'animation: moveAnimation 0s 10.5 both'});
504   var anim = div.getAnimations()[0];
505
506   // Note: currentIteration = ceil(iteration start + iteration count) - 1
507   assert_equals(anim.effect.getComputedTiming().currentIteration, 10,
508                 'Initial value of currentIteration');
509
510   // Seek backwards
511   anim.currentTime -= 2 * MS_PER_SEC;
512   assert_equals(anim.effect.getComputedTiming().currentIteration, 0,
513                 'Value of currentIteration count during before phase');
514 }, 'currentIteration of a finitely repeating zero-duration animation');
515
516 test(function(t) {
517   var div = addDiv(t, {style: 'animation: moveAnimation 100s 5.5 forwards'});
518   var anim = div.getAnimations()[0];
519
520   assert_equals(anim.effect.getComputedTiming().currentIteration, 0,
521                 'Initial value of currentIteration');
522   // The 3rd iteration
523   // Note: currentIteration = floor(scaled active time / iteration duration)
524   anim.currentTime = 250 * MS_PER_SEC;
525   assert_equals(anim.effect.getComputedTiming().currentIteration, 2,
526                 'Value of currentIteration during the 3rd iteration');
527   // Finish
528   anim.finish();
529   assert_equals(anim.effect.getComputedTiming().currentIteration, 5,
530                 'Value of currentIteration in after phase');
531 }, 'currentIteration of an animation with a non-integral iteration count');
532
533 test(function(t) {
534   var div = addDiv(t, {style: 'animation: moveAnimation 100s 2 forwards'});
535   var anim = div.getAnimations()[0];
536
537   assert_equals(anim.effect.getComputedTiming().currentIteration, 0,
538                 'Initial value of currentIteration');
539   // Finish
540   anim.finish();
541   assert_equals(anim.effect.getComputedTiming().currentIteration, 1,
542                 'Value of currentIteration in after phase');
543 }, 'currentIteration of an animation with an integral iteration count');
544
545 test(function(t) {
546   var div = addDiv(t, {style: 'animation: moveAnimation 100s forwards'});
547   var anim = div.getAnimations()[0];
548   assert_equals(anim.effect.getComputedTiming().currentIteration, 0,
549                 'Initial value of currentIteration');
550   // Finish
551   anim.finish();
552   assert_equals(anim.effect.getComputedTiming().currentIteration, 0,
553                 'Value of currentIteration in after phase');
554 }, 'currentIteration of an animation with a default iteration count');
555
556 test(function(t) {
557   var div = addDiv(t);
558   var effect = new KeyframeEffect(div, {left: ["0px", "100px"]});
559
560   assert_equals(effect.getComputedTiming().currentIteration, null,
561                 'currentIteration for orphaned effect');
562 }, 'currentIteration of an AnimationEffect without an Animation');
563
564 // TODO: If iteration duration is Infinity, currentIteration is 0.
565 // However, we cannot set iteration duration to Infinity in CSS Animation now.
566
567 </script>
568 </body>