summaryrefslogtreecommitdiffstats
path: root/dom/animation/test/css-animations/file_event-order.html
blob: da78b6541c9c4a24ae51c3bd029a45ea3e4ffa5a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
<!doctype html>
<meta charset=utf-8>
<title>Tests for CSS animation event order</title>
<link rel="help" href="https://drafts.csswg.org/css-animations-2/#event-dispatch"/>
<script src="../testcommon.js"></script>
<style>
  @keyframes anim {
    from { margin-left: 0px; }
    to { margin-left: 100px; }
  }
</style>
<body>
<script type='text/javascript'>
'use strict';

/**
 * Asserts that the set of actual and received events match.
 * @param actualEvents   An array of the received AnimationEvent objects.
 * @param expectedEvents A series of array objects representing the expected
 *        events, each having the form:
 *          [ event type, target element, elapsed time ]
 */
function checkEvents(actualEvents, ...expectedEvents) {
  assert_equals(actualEvents.length, expectedEvents.length,
                `Number of actual events (${actualEvents.length}: \
${actualEvents.map(event => event.type).join(', ')}) should match expected \
events (${expectedEvents.map(event => event.type).join(', ')})`);

  actualEvents.forEach((actualEvent, i) => {
    assert_equals(expectedEvents[i][0], actualEvent.type,
                  'Event type should match');
    assert_equals(expectedEvents[i][1], actualEvent.target,
                  'Event target should match');
    assert_equals(expectedEvents[i][2], actualEvent.elapsedTime,
                  'Event\'s elapsed time should match');
  });
}

function setupAnimation(t, animationStyle, receiveEvents) {
  const div = addDiv(t, { style: "animation: " + animationStyle });
  const watcher = new EventWatcher(t, div, [ 'animationstart',
                                             'animationiteration',
                                             'animationend' ]);

  ['start', 'iteration', 'end'].forEach(name => {
    div['onanimation' + name] = function(evt) {
    receiveEvents.push({ type:        evt.type,
                         target:      evt.target,
                         elapsedTime: evt.elapsedTime });
    }.bind(this);
  });

  const animation = div.getAnimations()[0];

  return [animation, watcher, div];
}

promise_test(function(t) {
  let events = [];
  const [animation1, watcher1, div1] =
    setupAnimation(t, 'anim 100s 2 paused', events);
  const [animation2, watcher2, div2] =
    setupAnimation(t, 'anim 100s 2 paused', events);

  return Promise.all([ watcher1.wait_for('animationstart'),
                       watcher2.wait_for('animationstart') ]).then(function() {
    checkEvents(events, ['animationstart', div1, 0],
                        ['animationstart', div2, 0]);

    events.length = 0;  // Clear received event array

    animation1.currentTime = 100 * MS_PER_SEC;
    animation2.currentTime = 100 * MS_PER_SEC;
    return Promise.all([ watcher1.wait_for('animationiteration'),
                         watcher2.wait_for('animationiteration') ]);
  }).then(function() {
    checkEvents(events, ['animationiteration', div1, 100],
                        ['animationiteration', div2, 100]);

    events.length = 0;  // Clear received event array

    animation1.finish();
    animation2.finish();

    return Promise.all([ watcher1.wait_for('animationend'),
                         watcher2.wait_for('animationend') ]);
  }).then(function() {
    checkEvents(events, ['animationend', div1, 200],
                        ['animationend', div2, 200]);
  });
}, 'Test same events are ordered by elements.');

promise_test(function(t) {
  let events = [];
  const [animation1, watcher1, div1] =
    setupAnimation(t, 'anim 200s 400s', events);
  const [animation2, watcher2, div2] =
    setupAnimation(t, 'anim 300s 2', events);

  return watcher2.wait_for('animationstart').then(function(evt) {
    animation1.currentTime = 400 * MS_PER_SEC;
    animation2.currentTime = 400 * MS_PER_SEC;

    events.length = 0;  // Clear received event array

    return Promise.all([ watcher1.wait_for('animationstart'),
                         watcher2.wait_for('animationiteration') ]);
  }).then(function() {
    checkEvents(events, ['animationiteration', div2, 300],
                        ['animationstart',     div1, 0]);
  });
}, 'Test start and iteration events are ordered by time.');

promise_test(function(t) {
  let events = [];
  const [animation1, watcher1, div1] =
    setupAnimation(t, 'anim 150s', events);
  const [animation2, watcher2, div2] =
    setupAnimation(t, 'anim 100s 2', events);

  return Promise.all([ watcher1.wait_for('animationstart'),
                       watcher2.wait_for('animationstart') ]).then(function() {
    animation1.currentTime = 150 * MS_PER_SEC;
    animation2.currentTime = 150 * MS_PER_SEC;

    events.length = 0;  // Clear received event array

    return Promise.all([ watcher1.wait_for('animationend'),
                         watcher2.wait_for('animationiteration') ]);
  }).then(function() {
    checkEvents(events, ['animationiteration', div2, 100],
                        ['animationend',       div1, 150]);
  });
}, 'Test iteration and end events are ordered by time.');

promise_test(function(t) {
  let events = [];
  const [animation1, watcher1, div1] =
    setupAnimation(t, 'anim 100s 100s', events);
  const [animation2, watcher2, div2] =
    setupAnimation(t, 'anim 100s 2', events);

  animation1.finish();
  animation2.finish();

  return Promise.all([ watcher1.wait_for([ 'animationstart',
                                           'animationend' ]),
                       watcher2.wait_for([ 'animationstart',
                                           'animationend' ]) ]).then(function() {
    checkEvents(events, ['animationstart', div2, 0],
                        ['animationstart', div1, 0],
                        ['animationend',   div1, 100],
                        ['animationend',   div2, 200]);
  });
}, 'Test start and end events are sorted correctly when fired simultaneously');

done();
</script>
</body>
</html>