Bug 1406381 - Extend assert_computed_timing_for_each_phase to accommodate negative playback rates; r?hiro draft
authorBrian Birtles <birtles@gmail.com>
Fri, 13 Oct 2017 12:27:56 +0900
changeset 679929 acf69a25294f35b73d67aa8bad0895d4181858d6
parent 679913 4df775e4bfed31b4df7403f7a592a213cab999a7
child 679930 c291f71fc9f8dc86caf2030b0af91288b8073516
push id84346
push userbmo:bbirtles@mozilla.com
push dateFri, 13 Oct 2017 07:36:54 +0000
reviewershiro
bugs1406381
milestone58.0a1
Bug 1406381 - Extend assert_computed_timing_for_each_phase to accommodate negative playback rates; r?hiro MozReview-Commit-ID: LpTRS6aMaWw
testing/web-platform/tests/web-animations/resources/effect-tests.js
testing/web-platform/tests/web-animations/timing-model/animation-effects/current-iteration.html
testing/web-platform/tests/web-animations/timing-model/animation-effects/simple-iteration-progress.html
--- a/testing/web-platform/tests/web-animations/resources/effect-tests.js
+++ b/testing/web-platform/tests/web-animations/resources/effect-tests.js
@@ -2,43 +2,67 @@
 
 // Tests the |property| member of |animation's| target effect's computed timing
 // at the various points indicated by |values|.
 //
 // |values| has the format:
 //
 //   {
 //     before, // value to test during before phase
-//     active, // value to test during at the very beginning of the active phase
-//             // or undefined if the active duration is zero,
+//     activeBoundary, // value to test at the very beginning of the active
+//                     // phase when playing forwards, or the very end of
+//                     // the active phase when playing backwards.
+//                     // This should be undefined if the active duration of
+//                     // the effect is zero.
 //     after,  // value to test during the after phase or undefined if the
 //             // active duration is infinite
 //   }
 //
 function assert_computed_timing_for_each_phase(animation, property, values) {
   const effect = animation.effect;
+  const timing = effect.getComputedTiming();
+
+  // The following calculations are based on the definitions here:
+  // https://w3c.github.io/web-animations/#animation-effect-phases-and-states
+  const beforeActive = Math.max(Math.min(timing.delay, timing.endTime), 0);
+  const activeAfter =
+    Math.max(Math.min(timing.delay + timing.activeDuration, timing.endTime), 0);
+  const direction = animation.playbackRate < 0 ? 'backwards' : 'forwards';
 
   // Before phase
+  if (direction === 'forwards') {
+    animation.currentTime = beforeActive - 1;
+  } else {
+    animation.currentTime = beforeActive;
+  }
   assert_equals(effect.getComputedTiming()[property], values.before,
                 `Value of ${property} in the before phase`);
 
   // Active phase
   if (effect.getComputedTiming().activeDuration > 0) {
-    animation.currentTime = effect.getComputedTiming().delay;
-    assert_equals(effect.getComputedTiming()[property], values.active,
-                  `Value of ${property} in the active phase`);
+    if (direction === 'forwards') {
+      animation.currentTime = beforeActive;
+    } else {
+      animation.currentTime = activeAfter;
+    }
+    assert_equals(effect.getComputedTiming()[property], values.activeBoundary,
+                  `Value of ${property} at the boundary of the active phase`);
   } else {
-    assert_equals(values.active, undefined,
+    assert_equals(values.activeBoundary, undefined,
                   'Test specifies a value to check during the active phase but'
                   + ' the animation has a zero duration');
   }
 
   // After phase
   if (effect.getComputedTiming().activeDuration !== Infinity) {
-    animation.finish();
+    if (direction === 'forwards') {
+      animation.currentTime = activeAfter;
+    } else {
+      animation.currentTime = activeAfter + 1;
+    }
     assert_equals(effect.getComputedTiming()[property], values.after,
                   `Value of ${property} in the after phase`);
   } else {
     assert_equals(values.after, undefined,
                   'Test specifies a value to check during the after phase but'
                   + ' the animation has an infinite duration');
   }
 }
--- a/testing/web-platform/tests/web-animations/timing-model/animation-effects/current-iteration.html
+++ b/testing/web-platform/tests/web-animations/timing-model/animation-effects/current-iteration.html
@@ -8,29 +8,35 @@
 <script src="../../resources/effect-tests.js"></script>
 <body>
 <div id="log"></div>
 <script>
 'use strict';
 
 function runTests(tests, description) {
   for (const currentTest of tests) {
-    const testParams = Object.entries(currentTest.input)
-                             .map(([attr, value]) => `${attr}:${value}`)
-                             .join(' ');
+    let testParams = Object.entries(currentTest.input)
+                           .map(([attr, value]) => `${attr}:${value}`)
+                           .join(' ');
+    if (currentTest.playbackRate !== undefined) {
+      testParams += ` playbackRate:${currentTest.playbackRate}`;
+    }
 
     test(t => {
       const div = createDiv(t);
       const anim = div.animate({}, currentTest.input);
+      if (currentTest.playbackRate !== undefined) {
+        anim.playbackRate = currentTest.playbackRate;
+      }
 
       assert_computed_timing_for_each_phase(
         anim,
         'currentIteration',
         { before: currentTest.before,
-          active: currentTest.active,
+          activeBoundary: currentTest.active,
           after: currentTest.after },
       );
     }, `${description}: ${testParams}`);
   }
 }
 
 async_test(function(t) {
   var div = createDiv(t);
--- a/testing/web-platform/tests/web-animations/timing-model/animation-effects/simple-iteration-progress.html
+++ b/testing/web-platform/tests/web-animations/timing-model/animation-effects/simple-iteration-progress.html
@@ -9,29 +9,35 @@
 <script src="../../resources/effect-tests.js"></script>
 <body>
 <div id="log"></div>
 <script>
 'use strict';
 
 function runTests(tests, description) {
   for (const currentTest of tests) {
-    const testParams = Object.entries(currentTest.input)
-                             .map(([attr, value]) => `${attr}:${value}`)
-                             .join(' ');
+    let testParams = Object.entries(currentTest.input)
+                           .map(([attr, value]) => `${attr}:${value}`)
+                           .join(' ');
+    if (currentTest.playbackRate !== undefined) {
+      testParams += ` playbackRate:${currentTest.playbackRate}`;
+    }
 
     test(t => {
       const div = createDiv(t);
       const anim = div.animate({}, currentTest.input);
+      if (currentTest.playbackRate !== undefined) {
+        anim.playbackRate = currentTest.playbackRate;
+      }
 
       assert_computed_timing_for_each_phase(
         anim,
         'progress',
         { before: currentTest.before,
-          active: currentTest.active,
+          activeBoundary: currentTest.active,
           after: currentTest.after },
       );
     }, `${description}: ${testParams}`);
   }
 }
 
 
 // --------------------------------------------------------------------