1suite('player', function() {
2  setup(function() {
3    webAnimations1.timeline._players = [];
4  });
5  test('zero duration animation works', function() {
6    tick(90);
7    var p = document.body.animate([], 0);
8    tick(100);
9    assert.equal(p.startTime, 100);
10    assert.equal(p.currentTime, 0);
11  });
12  test('playing works as expected', function() {
13    tick(90);
14    var p = document.body.animate([], 2000);
15    tick(100);
16    assert.equal(p.startTime, 100);
17    assert.equal(p.currentTime, 0);
18    tick(300);
19    assert.equal(p.startTime, 100);
20    assert.equal(p.currentTime, 200);
21  });
22  test('pause at start of play', function() {
23    tick(90);
24    var p = document.body.animate([], 2000);
25    p.pause();
26    tick(100);
27    assert.equal(p.currentTime, 0);
28    tick(300);
29    p.play();
30    assert.equal(p.currentTime, 0);
31    tick(310);
32    assert.equal(p.currentTime, 0);
33    assert.equal(p.startTime, 310);
34
35    var p = document.body.animate([], 2000);
36    p.startTime = -690;
37    p.pause();
38    assert.equal(p.currentTime, null);
39    tick(700);
40    p.play();
41    tick(701);
42    assert.equal(p.currentTime, 1000);
43    tick(800);
44    assert.equal(p.currentTime, 1099);
45    assert.equal(p.startTime, -299);
46  });
47  test('pausing works as expected', function() {
48    tick(190);
49    var p = document.body.animate([], 3000);
50    tick(200);
51    tick(1500);
52    assert.equal(p.startTime, 200);
53    assert.equal(p.currentTime, 1300);
54    p.pause();
55    assert.equal(p.startTime, null);
56    assert.equal(p.currentTime, null);
57    tick(2500);
58    assert.equal(p.startTime, null);
59    assert.equal(p.currentTime, 1300);
60    p.play();
61    tick(2510);
62    assert.equal(p.startTime, 1210);
63    assert.equal(p.currentTime, 1300);
64    tick(3500);
65    assert.equal(p.startTime, 1210);
66    assert.equal(p.currentTime, 2290);
67  });
68  test('reversing works as expected', function() {
69    tick(290);
70    var p = document.body.animate([], 1000);
71    tick(300);
72    assert.equal(p.startTime, 300);
73    assert.equal(p.currentTime, 0);
74    tick(600);
75    assert.equal(p.startTime, 300);
76    assert.equal(p.currentTime, 300);
77    assert.equal(p.playbackRate, 1);
78    p.reverse();
79    tick(600);
80    assert.equal(p.startTime, 900);
81    assert.equal(p.currentTime, 300);
82    assert.equal(p.playbackRate, -1);
83    tick(700);
84    assert.equal(p.startTime, 900);
85    assert.equal(p.currentTime, 200);
86  });
87  test('reversing after pausing', function() {
88    tick(90);
89    var p = document.body.animate([], 1000);
90    tick(100);
91    tick(600);
92    p.reverse();
93    tick(601);
94    tick(700);
95    assert.equal(p.startTime, 1101);
96    assert.equal(p.currentTime, 401);
97  });
98  test('reversing after finishing works as expected', function() {
99    tick(90);
100    var p = document.body.animate([], 1000);
101    tick(100);
102    tick(1200);
103    assert.equal(p.finished, true);
104    assert.equal(p.startTime, 100);
105    assert.equal(p.currentTime, 1000);
106    tick(1500);
107    assert.equal(p.currentTime, 1000);
108    assert.equal(isTicking(), false);
109    p.reverse();
110    assert.equal(p._startTime, null);
111    assert.equal(p.currentTime, 1000);
112    tick(1600);
113    assert.equal(p.startTime, 2600);
114    assert.equal(p.currentTime, 1000);
115  });
116  test('playing after finishing works as expected', function() {
117    tick(90);
118    var p = document.body.animate([], 1000);
119    tick(100);
120    tick(1200);
121    assert.equal(p.finished, true);
122    assert.equal(p.startTime, 100);
123    assert.equal(p.currentTime, 1000);
124    tick(1500);
125    assert.equal(p.currentTime, 1000);
126    assert.equal(isTicking(), false);
127    p.play();
128    assert.equal(p.startTime, null);
129    assert.equal(p.currentTime, 0);
130    tick(1600);
131    assert.equal(p.startTime, 1600);
132    assert.equal(p.currentTime, 0);
133  });
134  test('limiting works as expected', function() {
135    tick(390);
136    var p = document.body.animate([], 1000);
137    tick(400);
138    assert.equal(p.startTime, 400);
139    assert.equal(p.currentTime, 0);
140    tick(900);
141    assert.equal(p.startTime, 400);
142    assert.equal(p.currentTime, 500);
143    tick(1400);
144    assert.equal(p.startTime, 400);
145    assert.equal(p.currentTime, 1000);
146    tick(1500);
147    assert.equal(p.startTime, 400);
148    assert.equal(p.currentTime, 1000);
149    p.reverse();
150    assert.equal(p.playbackRate, -1);
151    assert.equal(p.currentTime, 1000);
152    assert.equal(p._startTime, null);
153    tick(2000);
154    assert.equal(p.currentTime, 1000);
155    assert.equal(p.startTime, 3000);
156    tick(2200);
157    assert.equal(p.currentTime, 800);
158    assert.equal(p.startTime, 3000);
159    tick(3200);
160    assert.equal(p.currentTime, 0);
161    assert.equal(p.startTime, 3000);
162    tick(3500);
163    assert.equal(p.currentTime, 0);
164    assert.equal(p.startTime, 3000);
165  });
166  test('play after limit works as expected', function() {
167    tick(490);
168    var p = document.body.animate([], 2000);
169    tick(500);
170    tick(2600);
171    assert.equal(p.currentTime, 2000);
172    assert.equal(p.startTime, 500);
173    assert.equal(p.finished, true);
174    assert.equal(p.playbackRate, 1);
175    setTicking(true);
176    p.play();
177    tick(2700);
178    assert.equal(p.startTime, 2700);
179    assert.equal(p.currentTime, 0);
180    assert.equal(p.finished, false);
181    assert.equal(p.playbackRate, 1);
182  });
183  test('play after limit works as expected (reversed)', function() {
184    tick(590);
185    var p = document.body.animate([], 3000);
186    tick(600);
187    tick(700);
188    p.reverse();
189    tick(701);
190    tick(900);
191    assert.equal(p.startTime, 801);
192    assert.equal(p.currentTime, 0);
193    assert.equal(p.finished, true);
194    assert.equal(p.playbackRate, -1);
195    setTicking(true);
196    p.play();
197    tick(1000);
198    assert.equal(p.startTime, 4000);
199    assert.equal(p.currentTime, 3000);
200    assert.equal(p.finished, false);
201    assert.equal(p.playbackRate, -1);
202  });
203  test('seeking works as expected', function() {
204    tick(690);
205    var p = document.body.animate([], 2000);
206    tick(700);
207    tick(900);
208    assert.equal(p.currentTime, 200);
209    p.currentTime = 600;
210    assert.equal(p.currentTime, 600);
211    assert.equal(p.startTime, 300);
212    p.reverse();
213    tick(1000);
214    assert.equal(p.startTime, 1600);
215    p.currentTime = 300;
216    assert.equal(p.currentTime, 300);
217    assert.equal(p.startTime, 1300);
218  });
219  test('seeking while paused works as expected', function() {
220    tick(790);
221    var p = document.body.animate([], 1000);
222    tick(800);
223    tick(1000);
224    p.pause();
225    assert.equal(p.currentTime, null);
226    assert.equal(p.startTime, null);
227    assert.equal(p.paused, true);
228    p.currentTime = 500;
229    assert.equal(p.startTime, null);
230    assert.equal(p.paused, true);
231  });
232  test('setting start time while paused is ignored', function() {
233    tick(900);
234    var p = document.body.animate([], 1234);
235    p.pause();
236    assert.equal(p.startTime, null);
237    assert.equal(p.currentTime, null);
238    p.startTime = 2232;
239    assert.equal(p.startTime, null);
240    assert.equal(p.currentTime, null);
241  });
242  test('setting playbackRate does preserves the current time', function() {
243    tick(900);
244    var p = document.body.animate([], 1000);
245    tick(1100);
246    var oldCurrentTime = p.currentTime;
247    p.playbackRate = 2;
248    assert.equal(p.playbackRate, 2);
249    assert.equal(p.currentTime, oldCurrentTime);
250  });
251  test('finishing works as expected', function() {
252    tick(1000);
253    var p = document.body.animate([], 2000);
254    p.finish();
255    assert.equal(p.startTime, 0);
256    assert.equal(p.currentTime, 2000);
257    p.reverse();
258    p.finish();
259    assert.equal(p.currentTime, 0);
260    assert.equal(p.startTime, 2000);
261    tick(2000);
262  });
263  test('cancelling clears all effects', function() {
264    tick(0);
265    var target = document.createElement('div');
266    document.documentElement.appendChild(target);
267    var player = target.animate([{marginLeft: '50px'}, {marginLeft: '50px'}], 1000);
268    tick(10);
269    tick(110);
270    assert.equal(getComputedStyle(target).marginLeft, '50px');
271    player.cancel();
272    // getComputedStyle forces a tick.
273    assert.equal(getComputedStyle(target).marginLeft, '0px');
274    assert.deepEqual(webAnimations1.timeline._players, []);
275    tick(120);
276    assert.equal(getComputedStyle(target).marginLeft, '0px');
277    assert.deepEqual(webAnimations1.timeline._players, []);
278    document.documentElement.removeChild(target);
279  });
280  test('startTime is set on first tick if timeline hasn\'t started', function() {
281    webAnimations1.timeline.currentTime = undefined;
282    var p = document.body.animate([], 1000);
283    tick(0);
284    tick(100);
285    assert.equal(p.startTime, 0);
286  });
287  test('players which are finished and not filling get discarded', function() {
288    tick(90);
289    var nofill = document.body.animate([], 100);
290    var fill = document.body.animate([], {duration: 100, fill: 'forwards'});
291    assert.deepEqual(webAnimations1.timeline._players, [nofill._player || nofill, fill._player || fill]);
292    tick(100);
293    assert.deepEqual(webAnimations1.timeline._players, [nofill._player || nofill, fill._player || fill]);
294    tick(400);
295    assert.deepEqual(webAnimations1.timeline._players, [fill._player || fill]);
296  });
297  test('discarded players get re-added on modification', function() {
298    tick(90);
299    var player = document.body.animate([], 100);
300    tick(100);
301    tick(400);
302    assert.deepEqual(webAnimations1.timeline._players, []);
303    player.currentTime = 0;
304    assert.deepEqual(webAnimations1.timeline._players, [player._player || player]);
305  });
306  test('players in the before phase are not discarded', function() {
307    tick(100);
308    var player = document.body.animate([], 100);
309    player.currentTime = -50;
310    tick(110);
311    assert.deepEqual(webAnimations1.timeline._players, [player._player || player]);
312  });
313  test('players that go out of effect should not clear the effect of players that are in effect', function() {
314    var target = document.createElement('div');
315    document.body.appendChild(target);
316    tick(0);
317    var playerBehind = target.animate([{marginLeft: '200px'}, {marginLeft: '200px'}], 200);
318    var playerInfront = target.animate([{marginLeft: '100px'}, {marginLeft: '100px'}], 100);
319    tick(50);
320    assert.equal(getComputedStyle(target).marginLeft, '100px', 't = 50');
321    tick(150);
322    assert.equal(getComputedStyle(target).marginLeft, '200px', 't = 150');
323    tick(250);
324    assert.equal(getComputedStyle(target).marginLeft, '0px', 't = 250');
325    document.body.removeChild(target);
326  });
327  test('player modifications should update CSS effects immediately', function() {
328    var target = document.createElement('div');
329    document.body.appendChild(target);
330    tick(0);
331    var playerBehind = target.animate([{width: '1234px'}, {width: '1234px'}], {duration: 1, fill: 'both'});
332    var playerInfront = target.animate([{width: '0px'}, {width: '100px'}], 100);
333    assert.equal(getComputedStyle(target).width, '0px');
334    playerInfront.currentTime = 50;
335    assert.equal(getComputedStyle(target).width, '50px');
336    playerInfront.currentTime = 100;
337    assert.equal(getComputedStyle(target).width, '1234px');
338    playerInfront.play();
339    assert.equal(getComputedStyle(target).width, '0px');
340    playerInfront.startTime = -50;
341    assert.equal(getComputedStyle(target).width, '50px');
342    document.body.removeChild(target);
343  });
344  test('Player that hasn\'t been played has playState \'idle\'', function() {
345    var source = new webAnimations1Animation(document.body, [], 1000);
346    var p = new Player(source);
347    assert.equal(p.playState, 'idle');
348  });
349  test('playState works for a simple animation', function() {
350    var p = document.body.animate([], 1000);
351    tick(0);
352    assert.equal(p.playState, 'running');
353    tick(100);
354    assert.equal(p.playState, 'running');
355    p.pause();
356    assert.equal(p.playState, 'pending');
357    tick(101);
358    assert.equal(p.playState, 'paused');
359    p.play();
360    assert.equal(p.playState, 'pending');
361    tick(102);
362    assert.equal(p.playState, 'running');
363    tick(1002);
364    assert.equal(p.playState, 'finished');
365  });
366  test('Play after cancel', function() {
367    var p = document.body.animate([], 1000);
368    assert.equal(p.playState, 'pending');
369    tick(0);
370    p.cancel();
371    assert.equal(p.playState, 'idle');
372    assert.equal(p.currentTime, null);
373    assert.equal(p.startTime, null);
374    tick(1);
375    assert.equal(p.playState, 'idle');
376    assert.equal(p.currentTime, null);
377    assert.equal(p.startTime, null);
378    p.play();
379    assert.equal(p.playState, 'pending');
380    assert.equal(p.currentTime, 0);
381    assert.equal(p.startTime, null);
382    tick(10);
383    assert.equal(p.playState, 'running');
384    assert.equal(p.currentTime, 0);
385    assert.equal(p.startTime, 10);
386  });
387  test('Reverse after cancel', function() {
388    var p = document.body.animate([], 300);
389    tick(0);
390    p.cancel();
391    assert.equal(p.playState, 'idle');
392    assert.equal(p.currentTime, null);
393    assert.equal(p.startTime, null);
394    tick(1);
395    p.reverse();
396    assert.equal(p.playState, 'pending');
397    assert.equal(p.currentTime, 300);
398    assert.equal(p.startTime, null);
399    tick(100);
400    assert.equal(p.playState, 'running');
401    assert.equal(p.currentTime, 300);
402    assert.equal(p.startTime, 400);
403    tick(300);
404    assert.equal(p.playState, 'running');
405    assert.equal(p.currentTime, 100);
406    assert.equal(p.startTime, 400);
407    tick(400);
408    assert.equal(p.playState, 'finished');
409    assert.equal(p.currentTime, 0);
410    assert.equal(p.startTime, 400);
411  });
412  test('Finish after cancel', function() {
413    var p = document.body.animate([], 300);
414    tick(0);
415    p.cancel();
416    assert.equal(p.playState, 'idle');
417    assert.equal(p.currentTime, null);
418    assert.equal(p.startTime, null);
419    tick(1);
420    p.finish();
421    assert.equal(p.playState, 'idle');
422    assert.equal(p.currentTime, null);
423    assert.equal(p.startTime, null);
424    tick(2);
425    assert.equal(p.playState, 'idle');
426    assert.equal(p.currentTime, null);
427    assert.equal(p.startTime, null);
428  });
429  test('Pause after cancel', function() {
430    var p = document.body.animate([], 300);
431    tick(0);
432    p.cancel();
433    assert.equal(p.playState, 'idle');
434    assert.equal(p.currentTime, null);
435    assert.equal(p.startTime, null);
436    tick(1);
437    p.pause();
438    assert.equal(p.playState, 'idle');
439    assert.equal(p.currentTime, null);
440    assert.equal(p.startTime, null);
441  });
442  test('Players ignore NaN times', function() {
443    var p = document.body.animate([], 300);
444    p.startTime = 100;
445    tick(110);
446    assert.equal(p.currentTime, 10);
447    p.startTime = NaN;
448    assert.equal(p.startTime, 100);
449    p.currentTime = undefined;
450    assert.equal(p.currentTime, 10);
451  });
452  test('play() should not set a start time', function() {
453    var p = document.body.animate([], 1000);
454    p.cancel();
455    assert.equal(p.startTime, null);
456    assert.equal(p.playState, 'idle');
457    p.play();
458    assert.equal(p.startTime, null);
459    assert.equal(p.playState, 'pending');
460  });
461  test('reverse() should not set a start time', function() {
462    var p = document.body.animate([], 1000);
463    p.cancel();
464    assert.equal(p.startTime, null);
465    assert.equal(p.playState, 'idle');
466    p.reverse();
467    assert.equal(p.startTime, null);
468    assert.equal(p.playState, 'pending');
469  });
470});
471