Bug 1267893 part 3 - Add tests for start time draft
authorBrian Birtles <birtles@gmail.com>
Wed, 27 Apr 2016 11:30:10 +0900
changeset 356757 a576a3a90dd544190b162e53c91c6f8a5fb756fd
parent 356756 443d8a05d2f0660e10c6f54a9ae059849193747b
child 356758 742ed5a19836333c5795ea010054002dc759b60d
push id16592
push userbbirtles@mozilla.com
push dateWed, 27 Apr 2016 04:53:51 +0000
bugs1267893
milestone49.0a1
Bug 1267893 part 3 - Add tests for start time MozReview-Commit-ID: 7yhUVSEIR2v
testing/web-platform/meta/MANIFEST.json
testing/web-platform/meta/web-animations/timing-model/animations/set-the-animation-start-time.html.ini
testing/web-platform/tests/web-animations/animation/startTime.html
testing/web-platform/tests/web-animations/timing-model/animations/set-the-animation-start-time.html
--- a/testing/web-platform/meta/MANIFEST.json
+++ b/testing/web-platform/meta/MANIFEST.json
@@ -35295,16 +35295,22 @@
           }
         ],
         "service-workers/service-worker/navigate-window.https.html": [
           {
             "path": "service-workers/service-worker/navigate-window.https.html",
             "url": "/service-workers/service-worker/navigate-window.https.html"
           }
         ],
+        "web-animations/animation/startTime.html": [
+          {
+            "path": "web-animations/animation/startTime.html",
+            "url": "/web-animations/animation/startTime.html"
+          }
+        ],
         "web-animations/timing-model/animation-effects/active-time.html": [
           {
             "path": "web-animations/timing-model/animation-effects/active-time.html",
             "url": "/web-animations/timing-model/animation-effects/active-time.html"
           }
         ],
         "web-animations/timing-model/animation-effects/current-iteration.html": [
           {
@@ -35312,16 +35318,22 @@
             "url": "/web-animations/timing-model/animation-effects/current-iteration.html"
           }
         ],
         "web-animations/timing-model/animation-effects/simple-iteration-progress.html": [
           {
             "path": "web-animations/timing-model/animation-effects/simple-iteration-progress.html",
             "url": "/web-animations/timing-model/animation-effects/simple-iteration-progress.html"
           }
+        ],
+        "web-animations/timing-model/animations/set-the-animation-start-time.html": [
+          {
+            "path": "web-animations/timing-model/animations/set-the-animation-start-time.html",
+            "url": "/web-animations/timing-model/animations/set-the-animation-start-time.html"
+          }
         ]
       }
     },
     "reftest_nodes": {
       "compat/webkit-text-fill-color-property-002.html": [
         {
           "path": "compat/webkit-text-fill-color-property-002.html",
           "references": [
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/web-animations/timing-model/animations/set-the-animation-start-time.html.ini
@@ -0,0 +1,13 @@
+[set-the-animation-start-time.html]
+  type: testharness
+  [Setting the start time of an animation without an active timeline]
+    expected: FAIL
+    bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1096776
+
+  [Setting an unresolved start time an animation without an active timeline does not clear the current time]
+    expected: FAIL
+    bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1096776
+
+  [Setting the start time updates the finished state]
+    expected: FAIL
+    bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1267893
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/web-animations/animation/startTime.html
@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Animation.startTime tests</title>
+<link rel="help"
+href="https://w3c.github.io/web-animations/#dom-animation-starttime">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../testcommon.js"></script>
+<link rel="stylesheet" href="/resources/testharness.css">
+<body>
+<div id="log"></div>
+<script>
+'use strict';
+
+test(function(t)
+{
+  var animation = new Animation(new KeyframeEffect(createDiv(t), null),
+                                document.timeline);
+  assert_equals(animation.startTime, null, 'startTime is unresolved');
+}, 'startTime of a newly created (idle) animation is unresolved');
+
+test(function(t)
+{
+  var animation = new Animation(new KeyframeEffect(createDiv(t), null),
+                                document.timeline);
+  animation.play();
+  assert_equals(animation.startTime, null, 'startTime is unresolved');
+}, 'startTime of a pause-pending animation is unresolved');
+
+test(function(t)
+{
+  var animation = new Animation(new KeyframeEffect(createDiv(t), null),
+                                document.timeline);
+  animation.pause();
+  assert_equals(animation.startTime, null, 'startTime is unresolved');
+}, 'startTime of a pause-pending animation is unresolved');
+
+test(function(t)
+{
+  var animation = createDiv(t).animate(null);
+  assert_equals(animation.startTime, null, 'startTime is unresolved');
+}, 'startTime of a play-pending animation created using Element.animate'
+   + ' shortcut is unresolved');
+
+promise_test(function(t)
+{
+  var animation = createDiv(t).animate(null, 100 * MS_PER_SEC);
+  return animation.ready.then(function() {
+    assert_greater_than(animation.startTime, 0, 'startTime when running');
+  });
+}, 'startTime is resolved when running');
+
+</script>
+</body>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/web-animations/timing-model/animations/set-the-animation-start-time.html
@@ -0,0 +1,205 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Setting the start time tests</title>
+<link rel="help" href="https://w3c.github.io/web-animations/#set-the-animation-start-time">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../../testcommon.js"></script>
+<body>
+<div id="log"></div>
+<script>
+'use strict';
+
+test(function(t)
+{
+  // It should only be possible to set *either* the start time or the current
+  // time for an animation that does not have an active timeline.
+
+  var animation =
+    new Animation(new KeyframeEffect(createDiv(t), null, 100 * MS_PER_SEC));
+
+  assert_equals(animation.currentTime, null, 'Intial current time');
+  assert_equals(animation.startTuime, null, 'Intial start time');
+
+  animation.currentTime = 1000;
+  assert_equals(animation.currentTime, 1000,
+                'Setting the current time succeeds');
+  assert_equals(animation.startTime, null,
+                'Start time remains null after setting current time');
+
+  animation.startTime = 1000;
+  assert_equals(animation.startTime, 1000,
+                'Setting the start time succeeds');
+  assert_equals(animation.currentTime, null,
+                'Setting the start time clears the current time');
+
+  animation.startTime = null;
+  assert_equals(animation.startTime, null,
+                'Setting the start time to an unresolved time succeeds');
+  assert_equals(animation.currentTime, null, 'The current time is unaffected');
+
+}, 'Setting the start time of an animation without an active timeline');
+
+test(function(t)
+{
+  // Setting an unresolved start time on an animation without an active
+  // timeline should not clear the current time.
+
+  var animation =
+    new Animation(new KeyframeEffect(createDiv(t), null, 100 * MS_PER_SEC));
+
+  assert_equals(animation.currentTime, null, 'Intial current time');
+  assert_equals(animation.startTuime, null, 'Intial start time');
+
+  animation.currentTime = 1000;
+  assert_equals(animation.currentTime, 1000,
+                'Setting the current time succeeds');
+  assert_equals(animation.startTime, null,
+                'Start time remains null after setting current time');
+
+  animation.startTime = null;
+  assert_equals(animation.startTime, null, 'Start time remains unresolved');
+  assert_equals(animation.currentTime, 1000, 'Current time is unaffected');
+
+}, 'Setting an unresolved start time an animation without an active timeline'
+   + ' does not clear the current time');
+
+test(function(t)
+{
+  var animation =
+    new Animation(new KeyframeEffect(createDiv(t), null, 100 * MS_PER_SEC),
+                  document.timeline);
+
+  // So long as a hold time is set, querying the current time will return
+  // the hold time.
+
+  // Since the start time is unresolved at this point, setting the current time
+  // will set the hold time
+  animation.currentTime = 1000;
+  assert_equals(animation.currentTime, 1000,
+                'The current time is calculated from the hold time');
+
+  // If we set the start time, however, we should clear the hold time.
+  animation.startTime = document.timeline.currentTime - 2000;
+  assert_times_equal(animation.currentTime, 2000,
+                     'The current time is calculated from the start time,'
+                     + ' not the hold time');
+
+  // Sanity check
+  assert_equals(animation.playState, 'running',
+                'Animation reports it is running after setting a resolved'
+                + ' start time');
+}, 'Setting the start time clears the hold time');
+
+promise_test(function(t)
+{
+  var animation =
+    new Animation(new KeyframeEffect(createDiv(t), null, 100 * MS_PER_SEC),
+                  document.timeline);
+
+  // Set up a running animation (i.e. both start time and current time
+  // are resolved).
+  animation.startTime = document.timeline.currentTime - 1000;
+  assert_equals(animation.playState, 'running');
+  assert_times_equal(animation.currentTime, 1000,
+                     'Current time is resolved for a running animation')
+
+  // Clear start time
+  animation.startTime = null;
+  assert_times_equal(animation.currentTime, 1000,
+                     'Hold time is set after start time is made unresolved');
+  assert_equals(animation.playState, 'paused',
+                'Animation reports it is paused after setting an unresolved'
+                + ' start time');
+}, 'Setting an unresolved start time sets the hold time');
+
+promise_test(function(t)
+{
+  var animation =
+    new Animation(new KeyframeEffect(createDiv(t), null, 100 * MS_PER_SEC),
+                  document.timeline);
+
+  var readyPromiseCallbackCalled = false;
+  animation.ready.then(function() { readyPromiseCallbackCalled = true; } );
+
+  // Put the animation in the play-pending state
+  animation.play();
+
+  // Sanity check
+  assert_equals(animation.playState, 'pending',
+                'Animation is in play-pending state');
+
+  // Setting the start time should resolve the 'ready' promise, i.e.
+  // it should schedule a microtask to run the promise callbacks.
+  animation.startTime = document.timeline.currentTime;
+  assert_false(readyPromiseCallbackCalled,
+               'Ready promise callback is not called synchronously');
+
+  // If we schedule another microtask then it should run immediately after
+  // the ready promise resolution microtask.
+  return Promise.resolve().then(function() {
+    assert_true(readyPromiseCallbackCalled,
+                'Ready promise callback called after setting startTime');
+  });
+}, 'Setting the start time resolves a pending ready promise');
+
+promise_test(function(t)
+{
+  var animation =
+    new Animation(new KeyframeEffect(createDiv(t), null, 100 * MS_PER_SEC),
+                  document.timeline);
+
+  var readyPromiseCallbackCalled = false;
+  animation.ready.then(function() { readyPromiseCallbackCalled = true; } );
+
+  // Put the animation in the pause-pending state
+  animation.startTime = document.timeline.currentTime;
+  animation.pause();
+
+  // Sanity check
+  assert_equals(animation.playState, 'pending',
+                'Animation is in pause-pending state');
+
+  // Setting the start time should resolve the 'ready' promise although
+  // the resolution callbacks when be run in a separate microtask.
+  animation.startTime = null;
+  assert_false(readyPromiseCallbackCalled,
+               'Ready promise callback is not called synchronously');
+
+  return Promise.resolve().then(function() {
+    assert_true(readyPromiseCallbackCalled,
+                'Ready promise callback called after setting startTime');
+  });
+}, 'Setting the start time resolves a pending pause task');
+
+promise_test(function(t)
+{
+  var animation =
+    new Animation(new KeyframeEffect(createDiv(t), null, 100 * MS_PER_SEC),
+                  document.timeline);
+
+  // Set start time such that the current time is past the end time
+  animation.startTime = document.timeline.currentTime
+                        - 110 * MS_PER_SEC;
+  assert_equals(animation.playState, 'finished',
+                'Seeked to finished state using the startTime');
+
+  // If the 'did seek' flag is true, the current should be greater than
+  // the effect end.
+  assert_greater_than(animation.currentTime,
+                      animation.effect.getComputedTiming().endTime,
+                      'Setting the start time updated the finished state with'
+                      + ' the \'did seek\' flag set to true');
+
+  // Furthermore, that time should persist if we have correctly updated
+  // the hold time
+  var finishedCurrentTime = animation.currentTime;
+  return waitForAnimationFrames(1).then(function() {
+    assert_equals(animation.currentTime, finishedCurrentTime,
+                  'Current time does not change after seeking past the effect'
+                  + ' end time by setting the current time');
+  });
+}, 'Setting the start time updates the finished state');
+
+</script>
+</body>