Bug 1202333 part 4 - Add test of event order for CSS-Animation. r?birtles draft
authorMantaroh Yoshinaga <mantaroh@gmail.com>
Mon, 12 Dec 2016 10:30:06 +0900
changeset 448620 9946dc8ab2943fe59f26346ab16013c3270a5729
parent 448618 cc8ade36a442b29f607efaa9311028f4a3cb95e9
child 539330 e93ac17ab5f3380135b1c6617d43a3cb605f3b49
push id38387
push usermantaroh@gmail.com
push dateMon, 12 Dec 2016 01:31:08 +0000
reviewersbirtles
bugs1202333
milestone53.0a1
Bug 1202333 part 4 - Add test of event order for CSS-Animation. r?birtles MozReview-Commit-ID: 2SPFd1hkHZ0
dom/animation/test/css-animations/file_events-order.html
dom/animation/test/css-animations/test_events-order.html
dom/animation/test/mochitest.ini
new file mode 100644
--- /dev/null
+++ b/dom/animation/test/css-animations/file_events-order.html
@@ -0,0 +1,201 @@
+<!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';
+
+/**
+ * This is EventWatcher for two element.
+ * It can determine the order of tow element's event.
+ */
+function EventWatcherWithTwoElement(test, target1, target2, eventTypes)
+{
+  var waitingFor = null;
+  target1.resultEvents = [];
+  target2.resultEvents = [];
+
+  var eventHandler = test.step_func(function(evt) {
+    assert_true(!!waitingFor,
+                'Not expecting event, but got ' + evt.type + ' event');
+    assert_equals(evt.type, waitingFor.types[0][1],
+                  'Expected ' + waitingFor.types[0][1] + ' event, but got ' +
+                  evt.type + ' event instead');
+    assert_equals(evt.target, waitingFor.types[0][0],
+                  'Expected ' + waitingFor.types[0][0] + ' target of event,' +
+                  'but got ' + evt.type + ' event instead');
+    evt.target.resultEvents.push(evt);
+    if (waitingFor.types.length > 1) {
+      // Pop first event from array
+      waitingFor.types.shift();
+      return;
+    }
+
+    // We need to null out waitingFor before calling the resolve function
+    // since the Promise's resolve handlers may call wait_for() which will
+    // need to set waitingFor.
+    var resolveFunc = waitingFor.resolve;
+    waitingFor = null;
+    resolveFunc();
+  });
+
+  for (var i = 0; i < eventTypes.length; i++) {
+    target1.addEventListener(eventTypes[i], eventHandler);
+    target2.addEventListener(eventTypes[i], eventHandler);
+  }
+
+  this.wait_for = function(types) {
+    if (waitingFor) {
+      return Promise.reject('Already waiting for an event or events');
+    }
+
+    target1.resultEvents = [];
+    target2.resultEvents = [];
+
+    return new Promise(function(resolve, reject) {
+      waitingFor = {
+        types: types,
+        resolve: resolve,
+        reject: reject
+      };
+    });
+  };
+
+  function stop_watching() {
+    for (var i = 0; i < eventTypes.length; i++) {
+      target1.removeEventListener(eventTypes[i], eventHandler);
+      target2.removeEventListener(eventTypes[i], eventHandler);
+    }
+  };
+
+  test.add_cleanup(stop_watching);
+  return this;
+}
+
+function setupAnimationWithTwoElement(t, animationStyle1, animationStyle2) {
+  var div1 = addDiv(t, { style: "animation: " + animationStyle1 });
+  var div2 = addDiv(t, { style: "animation: " + animationStyle2 });
+  var watcher = new EventWatcherWithTwoElement(t, div1, div2,
+                                               [ 'animationstart',
+                                                 'animationiteration',
+                                                 'animationend' ]);
+  var animation1 = div1.getAnimations()[0];
+  var animation2 = div2.getAnimations()[0];
+
+  return [animation1, animation2, watcher, div1, div2];
+}
+
+promise_test(function(t) {
+  var [animation1, animation2, watcher, div1, div2] =
+    setupAnimationWithTwoElement(t, 'anim 5s 2 paused', 'anim 5s 2 paused');
+
+  return watcher.wait_for([ [ div1, 'animationstart' ],
+                            [ div2, 'animationstart' ] ]).then(function() {
+    assert_equals(div1.resultEvents.length, 1);
+    assert_equals(div2.resultEvents.length, 1);
+    assert_equals(div1.resultEvents[0].elapsedTime, 0);
+    assert_equals(div2.resultEvents[0].elapsedTime, 0);
+
+    // Seek to first iteration
+    animation1.currentTime = 5 * MS_PER_SEC;
+    animation2.currentTime = 5 * MS_PER_SEC;
+    return  watcher.wait_for([ [ div1, 'animationiteration' ],
+                               [ div2, 'animationiteration' ] ]);
+  }).then(function() {
+    assert_equals(div1.resultEvents.length, 1);
+    assert_equals(div2.resultEvents.length, 1);
+    assert_equals(div1.resultEvents[0].elapsedTime, 5);
+    assert_equals(div2.resultEvents[0].elapsedTime, 5);
+
+    // Seek to end
+    animation1.finish();
+    animation2.finish();
+
+    return watcher.wait_for([ [ div1, 'animationend' ],
+                              [ div2, 'animationend' ] ]);
+  }).then(function() {
+    assert_equals(div1.resultEvents.length, 1);
+    assert_equals(div2.resultEvents.length, 1);
+    assert_equals(div1.resultEvents[0].elapsedTime, 10);
+    assert_equals(div2.resultEvents[0].elapsedTime, 10);
+  });
+}, 'Fire same events on different element');
+
+promise_test(function(t) {
+  var [animation1, animation2, watcher, div1, div2] =
+    setupAnimationWithTwoElement(t, 'anim 5s 6s', 'anim 5s 2');
+
+  return watcher.wait_for([ [ div2, 'animationstart'] ]).then(function() {
+    // Seek to start of animation1
+    animation1.currentTime = 6 * MS_PER_SEC;
+    animation2.currentTime = 6 * MS_PER_SEC;
+
+    return watcher.wait_for([ [ div2, 'animationiteration' ],
+                              [ div1, 'animationstart' ] ]);
+  }).then(function() {
+    assert_equals(div1.resultEvents.length, 1);
+    assert_equals(div2.resultEvents.length, 1);
+    assert_equals(div1.resultEvents[0].elapsedTime, 0);
+    assert_equals(div2.resultEvents[0].elapsedTime, 5);
+  });
+}, 'Fire the start and iteration event');
+
+promise_test(function(t) {
+  var [animation1, animation2, watcher, div1, div2] =
+    setupAnimationWithTwoElement(t, 'anim 5s 4s', 'anim 5s 2');
+
+  // Seek to start position.
+  animation1.currentTime = 4 * MS_PER_SEC;
+  animation2.currentTime = 4 * MS_PER_SEC;
+
+  return watcher.wait_for([ [ div2, 'animationstart' ],
+                            [ div1, 'animationstart' ] ]).then(function() {
+    // Seek to end of animation1
+    animation1.currentTime = 9 * MS_PER_SEC;
+    animation2.currentTime = 9 * MS_PER_SEC;
+
+    return watcher.wait_for([ [ div2, 'animationiteration' ],
+                              [ div1, 'animationend' ] ]);
+  }).then(function() {
+    assert_equals(div1.resultEvents.length, 1);
+    assert_equals(div2.resultEvents.length, 1);
+    assert_equals(div1.resultEvents[0].elapsedTime, 5);
+    assert_equals(div2.resultEvents[0].elapsedTime, 5);
+  });
+}, 'Fire the iteration and end event');
+
+promise_test(function(t) {
+  var [animation1, animation2, watcher, div1, div2] =
+    setupAnimationWithTwoElement(t,
+                                 'anim 5s 4s',
+                                 'anim 5s 2');
+
+  // Make after phase.
+  animation1.finish();
+  animation2.finish();
+
+  return watcher.wait_for([ [ div2, 'animationstart' ],
+                            [ div1, 'animationstart' ],
+                            [ div1, 'animationend' ],
+                            [div2, 'animationend' ] ]).then(function() {
+    assert_equals(div1.resultEvents.length, 2);
+    assert_equals(div2.resultEvents.length, 2);
+    assert_equals(div1.resultEvents[0].elapsedTime, 0);
+    assert_equals(div1.resultEvents[1].elapsedTime, 5);
+    assert_equals(div2.resultEvents[0].elapsedTime, 0);
+    assert_equals(div2.resultEvents[1].elapsedTime, 10);
+  });
+}, 'Fire the start and end event');
+
+done();
+</script>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/animation/test/css-animations/test_events-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_events-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_events-dispatch.html
+  css-animations/file_events-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_events-dispatch.html]
+[css-animations/test_events-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]