78d830b73c2d4a208260b1aa83edb019e0ba4725
[WebKit-https.git] / LayoutTests / imported / mozilla / css-animations / test_document-get-animations.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 animLeft {
8   to { left: 100px }
9 }
10 @keyframes animTop {
11   to { top: 100px }
12 }
13 @keyframes animBottom {
14   to { bottom: 100px }
15 }
16 @keyframes animRight {
17   to { right: 100px }
18 }
19 ::before {
20   content: ''
21 }
22 ::after {
23   content: ''
24 }
25 </style>
26 <body>
27 <div id="log"></div>
28 <script>
29 'use strict';
30
31 test(function(t) {
32   assert_equals(document.getAnimations().length, 0,
33     'getAnimations returns an empty sequence for a document'
34     + ' with no animations');
35 }, 'getAnimations for non-animated content');
36
37 test(function(t) {
38   var div = addDiv(t);
39
40   // Add an animation
41   div.style.animation = 'animLeft 100s';
42   assert_equals(document.getAnimations().length, 1,
43                 'getAnimations returns a running CSS Animation');
44
45   // Add another animation
46   div.style.animation = 'animLeft 100s, animTop 100s';
47   assert_equals(document.getAnimations().length, 2,
48                 'getAnimations returns two running CSS Animations');
49
50   // Remove both
51   div.style.animation = '';
52   assert_equals(document.getAnimations().length, 0,
53                 'getAnimations returns no running CSS Animations');
54 }, 'getAnimations for CSS Animations');
55
56 test(function(t) {
57   var div = addDiv(t);
58   div.style.animation = 'animLeft 100s, animTop 100s, animRight 100s, ' +
59                         'animBottom 100s';
60
61   var animations = document.getAnimations();
62   assert_equals(animations.length, 4,
63                 'getAnimations returns all running CSS Animations');
64   assert_equals(animations[0].animationName, 'animLeft',
65                 'Order of first animation returned');
66   assert_equals(animations[1].animationName, 'animTop',
67                 'Order of second animation returned');
68   assert_equals(animations[2].animationName, 'animRight',
69                 'Order of third animation returned');
70   assert_equals(animations[3].animationName, 'animBottom',
71                 'Order of fourth animation returned');
72 }, 'Order of CSS Animations - within an element');
73
74 test(function(t) {
75   var div1 = addDiv(t, { style: 'animation: animLeft 100s' });
76   var div2 = addDiv(t, { style: 'animation: animLeft 100s' });
77   var div3 = addDiv(t, { style: 'animation: animLeft 100s' });
78   var div4 = addDiv(t, { style: 'animation: animLeft 100s' });
79
80   var animations = document.getAnimations();
81   assert_equals(animations.length, 4,
82                 'getAnimations returns all running CSS Animations');
83   assert_equals(animations[0].effect.target, div1,
84                 'Order of first animation returned');
85   assert_equals(animations[1].effect.target, div2,
86                 'Order of second animation returned');
87   assert_equals(animations[2].effect.target, div3,
88                 'Order of third animation returned');
89   assert_equals(animations[3].effect.target, div4,
90                 'Order of fourth animation returned');
91
92   // Order should be depth-first pre-order so add some depth as follows:
93   //
94   //      <parent>
95   //       /  |
96   //      2   3
97   //    /  \
98   //   1   4
99   //
100   // Which should give: 2, 1, 4, 3
101   div2.appendChild(div1);
102   div2.appendChild(div4);
103   animations = document.getAnimations();
104   assert_equals(animations[0].effect.target, div2,
105                 'Order of first animation returned after tree surgery');
106   assert_equals(animations[1].effect.target, div1,
107                 'Order of second animation returned after tree surgery');
108   assert_equals(animations[2].effect.target, div4,
109                 'Order of third animation returned after tree surgery');
110   assert_equals(animations[3].effect.target, div3,
111                 'Order of fourth animation returned after tree surgery');
112
113 }, 'Order of CSS Animations - across elements');
114
115 test(function(t) {
116   var div1 = addDiv(t, { style: 'animation: animLeft 100s, animTop 100s' });
117   var div2 = addDiv(t, { style: 'animation: animBottom 100s' });
118
119   var expectedResults = [ [ div1, 'animLeft' ],
120                           [ div1, 'animTop' ],
121                           [ div2, 'animBottom' ] ];
122   var animations = document.getAnimations();
123   assert_equals(animations.length, expectedResults.length,
124                 'getAnimations returns all running CSS Animations');
125   animations.forEach(function(anim, i) {
126     assert_equals(anim.effect.target, expectedResults[i][0],
127                   'Target of animation in position ' + i);
128     assert_equals(anim.animationName, expectedResults[i][1],
129                   'Name of animation in position ' + i);
130   });
131
132   // Modify tree structure and animation list
133   div2.appendChild(div1);
134   div1.style.animation = 'animLeft 100s, animRight 100s, animTop 100s';
135
136   expectedResults = [ [ div2, 'animBottom' ],
137                       [ div1, 'animLeft' ],
138                       [ div1, 'animRight' ],
139                       [ div1, 'animTop' ] ];
140   animations = document.getAnimations();
141   assert_equals(animations.length, expectedResults.length,
142                 'getAnimations returns all running CSS Animations after ' +
143                 'making changes');
144   animations.forEach(function(anim, i) {
145     assert_equals(anim.effect.target, expectedResults[i][0],
146                   'Target of animation in position ' + i + ' after changes');
147     assert_equals(anim.animationName, expectedResults[i][1],
148                   'Name of animation in position ' + i + ' after changes');
149   });
150 }, 'Order of CSS Animations - across and within elements');
151
152 test(function(t) {
153   var div = addDiv(t, { style: 'animation: animLeft 100s, animTop 100s' });
154   var animLeft = document.getAnimations()[0];
155   assert_equals(animLeft.animationName, 'animLeft',
156                 'Originally, animLeft animation comes first');
157
158   // Disassociate animLeft from markup and restart
159   div.style.animation = 'animTop 100s';
160   animLeft.play();
161
162   var animations = document.getAnimations();
163   assert_equals(animations.length, 2,
164                 'getAnimations returns markup-bound and free animations');
165   assert_equals(animations[0].animationName, 'animTop',
166                 'Markup-bound animations come first');
167   assert_equals(animations[1], animLeft, 'Free animations come last');
168 }, 'Order of CSS Animations - markup-bound vs free animations');
169
170 test(function(t) {
171   var div = addDiv(t, { style: 'animation: animLeft 100s, animTop 100s' });
172   var animLeft = document.getAnimations()[0];
173   var animTop  = document.getAnimations()[1];
174
175   // Disassociate both animations from markup and restart in opposite order
176   div.style.animation = '';
177   animTop.play();
178   animLeft.play();
179
180   var animations = document.getAnimations();
181   assert_equals(animations.length, 2,
182                 'getAnimations returns free animations');
183   assert_equals(animations[0], animTop,
184                 'Free animations are returned in the order they are started');
185   assert_equals(animations[1], animLeft,
186                 'Animations started later are returned later');
187
188   // Restarting an animation should have no effect
189   animTop.cancel();
190   animTop.play();
191   assert_equals(document.getAnimations()[0], animTop,
192                 'After restarting, the ordering of free animations' +
193                 ' does not change');
194 }, 'Order of CSS Animations - free animations');
195
196 test(function(t) {
197   // Add an animation first
198   var div = addDiv(t, { style: 'animation: animLeft 100s' });
199   div.style.top = '0px';
200   div.style.transition = 'all 100s';
201   flushComputedStyle(div);
202
203   // *Then* add a transition
204   div.style.top = '100px';
205   flushComputedStyle(div);
206
207   // Although the transition was added later, it should come first in the list
208   var animations = document.getAnimations();
209   assert_equals(animations.length, 2,
210                 'Both CSS animations and transitions are returned');
211   assert_class_string(animations[0], 'CSSTransition', 'Transition comes first');
212   assert_class_string(animations[1], 'CSSAnimation', 'Animation comes second');
213 }, 'Order of CSS Animations and CSS Transitions');
214
215 test(function(t) {
216   var div = addDiv(t, { style: 'animation: animLeft 100s forwards' });
217   div.getAnimations()[0].finish();
218   assert_equals(document.getAnimations().length, 1,
219                 'Forwards-filling CSS animations are returned');
220 }, 'Finished but filling CSS Animations are returned');
221
222 test(function(t) {
223   var div = addDiv(t, { style: 'animation: animLeft 100s' });
224   div.getAnimations()[0].finish();
225   assert_equals(document.getAnimations().length, 0,
226                 'Non-filling finished CSS animations are not returned');
227 }, 'Finished but not filling CSS Animations are not returned');
228
229 test(function(t) {
230   var div = addDiv(t, { style: 'animation: animLeft 100s 100s' });
231   assert_equals(document.getAnimations().length, 1,
232                 'Yet-to-start CSS animations are returned');
233 }, 'Yet-to-start CSS Animations are returned');
234
235 test(function(t) {
236   var div = addDiv(t, { style: 'animation: animLeft 100s' });
237   div.getAnimations()[0].cancel();
238   assert_equals(document.getAnimations().length, 0,
239                 'CSS animations cancelled by the API are not returned');
240 }, 'CSS Animations cancelled via the API are not returned');
241
242 test(function(t) {
243   var div = addDiv(t, { style: 'animation: animLeft 100s' });
244   var anim = div.getAnimations()[0];
245   anim.cancel();
246   anim.play();
247   assert_equals(document.getAnimations().length, 1,
248                 'CSS animations cancelled and restarted by the API are ' +
249                 'returned');
250 }, 'CSS Animations cancelled and restarted via the API are returned');
251
252 test(function(t) {
253   addStyle(t, { '#parent::after': 'animation: animLeft 10s;',
254                 '#parent::before': 'animation: animRight 10s;' });
255   // create two divs with these arrangement:
256   //       parent
257   //     ::before,
258   //     ::after
259   //        |
260   //       child
261   var parent = addDiv(t, { 'id': 'parent' });
262   var child = addDiv(t);
263   parent.appendChild(child);
264   [parent, child].forEach((div) => {
265     div.setAttribute('style', 'animation: animBottom 10s');
266   });
267
268   var anims = document.getAnimations();
269   assert_equals(anims.length, 4,
270                 'CSS animations on both pseudo-elements and elements ' +
271                 'are returned');
272   assert_equals(anims[0].effect.target, parent,
273                 'The animation targeting the parent element comes first');
274   assert_equals(anims[1].effect.target.type, '::before',
275                 'The animation targeting the ::before element comes second');
276   assert_equals(anims[2].effect.target.type, '::after',
277                 'The animation targeting the ::after element comes third');
278   assert_equals(anims[3].effect.target, child,
279                 'The animation targeting the child element comes last');
280 }, 'CSS Animations targetting (pseudo-)elements should have correct order ' +
281    'after sorting');
282
283 </script>
284 </body>