Bug 1202333 part 4 - Add test of event order for CSS-Animation. r?birtles draft
authorMantaroh Yoshinaga <mantaroh@gmail.com>
Tue, 20 Dec 2016 15:57:20 +0900
changeset 451385 6bdc5256f5dc4cb8235a86b04260b6d339778866
parent 451384 372c46443915f450facda59321f9cafda3191bdb
child 539996 158780c1d33b14bba9c5f63ba0d2421ab070febb
push id39145
push usermantaroh@gmail.com
push dateTue, 20 Dec 2016 06:59:18 +0000
reviewersbirtles
bugs1202333
milestone53.0a1
Bug 1202333 part 4 - Add test of event order for CSS-Animation. r?birtles MozReview-Commit-ID: 9XxHLiohXJ2
dom/animation/test/css-animations/file_event-order.html
dom/animation/test/css-animations/test_event-order.html
dom/animation/test/mochitest.ini
new file mode 100644
--- /dev/null
+++ b/dom/animation/test/css-animations/file_event-order.html
@@ -0,0 +1,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>
new file mode 100644
--- /dev/null
+++ b/dom/animation/test/css-animations/test_event-order.html
@@ -0,0 +1,15 @@
+<!doctype html>
+<meta charset=utf-8>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+'use strict';
+setup({explicit_done: true});
+SpecialPowers.pushPrefEnv(
+  { "set": [["dom.animations-api.core.enabled", true]]},
+  function() {
+    window.open("file_event-order.html");
+  });
+</script>
+</html>
--- a/dom/animation/test/mochitest.ini
+++ b/dom/animation/test/mochitest.ini
@@ -15,16 +15,17 @@ support-files =
   css-animations/file_animation-reverse.html
   css-animations/file_animation-starttime.html
   css-animations/file_animations-dynamic-changes.html
   css-animations/file_cssanimation-animationname.html
   css-animations/file_document-get-animations.html
   css-animations/file_effect-target.html
   css-animations/file_element-get-animations.html
   css-animations/file_event-dispatch.html
+  css-animations/file_event-order.html
   css-animations/file_keyframeeffect-getkeyframes.html
   css-animations/file_pseudoElement-get-animations.html
   css-transitions/file_animation-cancel.html
   css-transitions/file_animation-computed-timing.html
   css-transitions/file_animation-currenttime.html
   css-transitions/file_animation-finished.html
   css-transitions/file_animation-pausing.html
   css-transitions/file_animation-ready.html
@@ -71,16 +72,17 @@ support-files =
 [css-animations/test_animation-ready.html]
 [css-animations/test_animation-reverse.html]
 [css-animations/test_animation-starttime.html]
 [css-animations/test_cssanimation-animationname.html]
 [css-animations/test_document-get-animations.html]
 [css-animations/test_effect-target.html]
 [css-animations/test_element-get-animations.html]
 [css-animations/test_event-dispatch.html]
+[css-animations/test_event-order.html]
 [css-animations/test_keyframeeffect-getkeyframes.html]
 [css-animations/test_pseudoElement-get-animations.html]
 [css-transitions/test_animation-cancel.html]
 [css-transitions/test_animation-computed-timing.html]
 [css-transitions/test_animation-currenttime.html]
 [css-transitions/test_animation-finished.html]
 [css-transitions/test_animation-pausing.html]
 [css-transitions/test_animation-ready.html]