3 <script src="../../../resources/testharness.js"></script>
4 <script src="../../../resources/testharnessreport.js"></script>
5 <script src="../resources/testcommon.js"></script>
7 @keyframes moveAnimation {
8 from { margin-left: 100px }
9 to { margin-left: 200px }
18 // --------------------
20 // --------------------
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');
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');
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');
43 // --------------------
45 // --------------------
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');
54 // --------------------
56 // --------------------
58 var getEffectWithFill = function(fill) {
59 var div = addDiv(t, {style: 'animation: moveAnimation 100s ' + fill});
60 return div.getAnimations()[0].effect;
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',
69 effect = getEffectWithFill('backwards');
70 assert_equals(effect.getComputedTiming().fill, 'backwards',
72 effect = getEffectWithFill('both');
73 assert_equals(effect.getComputedTiming().fill, 'both',
74 'Fill forwards and backwards');
75 }, 'fill of a new animation');
78 // --------------------
80 // --------------------
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');
89 // --------------------
91 // --------------------
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');
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');
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');
114 // --------------------
116 // --------------------
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');
125 // --------------------
127 // --------------------
129 var getEffectWithDir = function(dir) {
130 var div = addDiv(t, {style: 'animation: moveAnimation 100s ' + dir});
131 return div.getAnimations()[0].effect;
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');
149 // --------------------
151 // --------------------
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');
160 // ------------------------------
162 // = max(start delay + active duration + end delay, 0)
163 // --------------------
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');
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');
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');
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');
194 // Fill forwards so div.getAnimations()[0] won't return an
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');
203 // --------------------
205 // = iteration duration * iteration count
206 // --------------------
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');
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');
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');
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');
241 // --------------------
243 // --------------------
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');
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');
259 promise_test(function(t) {
260 var div = addDiv(t, {style: 'animation: moveAnimation 100s'});
262 var anim = div.getAnimations()[0];
263 anim.playbackRate = 2; // 2 times faster
265 return anim.ready.then(function() {
266 assert_equals(anim.effect.getComputedTiming().localTime, anim.currentTime,
267 'localTime is equal to currentTime');
268 return waitForFrame();
270 assert_equals(anim.effect.getComputedTiming().localTime, anim.currentTime,
271 'localTime is equal to currentTime');
273 }, 'localTime reflects playbackRate immediately');
277 var effect = new KeyframeEffect(div, {left: ["0px", "100px"]});
279 assert_equals(effect.getComputedTiming().localTime, null,
280 'localTime for orphaned effect');
281 }, 'localTime of an AnimationEffect without an Animation');
284 // --------------------
286 // Note: Default timing function is linear.
287 // --------------------
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) {
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');
301 assert_true(anim.effect.getComputedTiming().progress === test.progress[1],
302 'finished progress with "' + test.fill + '" fill');
304 }, 'progress of an animation with different fill modes');
307 var div = addDiv(t, {style: 'animation: moveAnimation 10s 10 both'});
308 var anim = div.getAnimations()[0];
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');
322 assert_equals(anim.effect.getComputedTiming().progress, 1.0,
323 'Value of progress');
324 }, 'progress of an integral repeating animation with normal direction');
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];
336 assert_equals(anim.effect.getComputedTiming().progress, 1.0,
337 'Initial value of progress in after phase');
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');
346 // Default iterations = 1
347 var div = addDiv(t, {style: 'animation: moveAnimation 0s both'});
348 var anim = div.getAnimations()[0];
350 assert_equals(anim.effect.getComputedTiming().progress, 1.0,
351 'Initial value of progress in after phase');
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');
360 var div = addDiv(t, {style: 'animation: moveAnimation 0s 5s 10.25 both'});
361 var anim = div.getAnimations()[0];
363 assert_equals(anim.effect.getComputedTiming().progress, 0.0,
364 'Initial value of progress (before phase)');
366 // Using iteration duration of 1 now.
367 // currentIteration now is floor(10.25) = 10, so progress should be 25%.
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');
374 var div = addDiv(t, {style: 'animation: moveAnimation 0s 5s 10.25 both reverse'});
375 var anim = div.getAnimations()[0];
377 assert_equals(anim.effect.getComputedTiming().progress, 1.0,
378 'Initial value of progress (before phase)');
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');
388 var div = addDiv(t, {style: 'animation: moveAnimation 10s 10.25 both alternate'});
389 var anim = div.getAnimations()[0];
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');
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');
409 var div = addDiv(t, {style: 'animation: moveAnimation 10s 10.25 both alternate-reverse'});
410 var anim = div.getAnimations()[0];
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');
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');
430 var div = addDiv(t, {style: 'animation: moveAnimation 0s 10.25 both alternate'});
431 var anim = div.getAnimations()[0];
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');
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');
448 var div = addDiv(t, {style: 'animation: moveAnimation 0s 10.25 both alternate-reverse'});
449 var anim = div.getAnimations()[0];
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');
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');
466 // --------------------
468 // --------------------
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 ' +
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');
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];
493 assert_equals(anim.effect.getComputedTiming().currentIteration, Infinity,
494 'Initial value of currentIteration in after phase');
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');
503 var div = addDiv(t, {style: 'animation: moveAnimation 0s 10.5 both'});
504 var anim = div.getAnimations()[0];
506 // Note: currentIteration = ceil(iteration start + iteration count) - 1
507 assert_equals(anim.effect.getComputedTiming().currentIteration, 10,
508 'Initial value of currentIteration');
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');
517 var div = addDiv(t, {style: 'animation: moveAnimation 100s 5.5 forwards'});
518 var anim = div.getAnimations()[0];
520 assert_equals(anim.effect.getComputedTiming().currentIteration, 0,
521 'Initial value of currentIteration');
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');
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');
534 var div = addDiv(t, {style: 'animation: moveAnimation 100s 2 forwards'});
535 var anim = div.getAnimations()[0];
537 assert_equals(anim.effect.getComputedTiming().currentIteration, 0,
538 'Initial value of currentIteration');
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');
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');
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');
558 var effect = new KeyframeEffect(div, {left: ["0px", "100px"]});
560 assert_equals(effect.getComputedTiming().currentIteration, null,
561 'currentIteration for orphaned effect');
562 }, 'currentIteration of an AnimationEffect without an Animation');
564 // TODO: If iteration duration is Infinity, currentIteration is 0.
565 // However, we cannot set iteration duration to Infinity in CSS Animation now.