diff options
Diffstat (limited to 'testing/web-platform/tests/web-animations/interfaces/AnimationEffect')
2 files changed, 689 insertions, 0 deletions
diff --git a/testing/web-platform/tests/web-animations/interfaces/AnimationEffect/getComputedTiming.html b/testing/web-platform/tests/web-animations/interfaces/AnimationEffect/getComputedTiming.html new file mode 100644 index 0000000000..10bd193361 --- /dev/null +++ b/testing/web-platform/tests/web-animations/interfaces/AnimationEffect/getComputedTiming.html @@ -0,0 +1,214 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<title>AnimationEffect.getComputedTiming</title> +<link rel="help" href="https://drafts.csswg.org/web-animations/#dom-animationeffect-getcomputedtiming"> +<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(t => { + const effect = new KeyframeEffect(null, null); + + const ct = effect.getComputedTiming(); + assert_equals(ct.delay, 0, 'computed delay'); + assert_equals(ct.endDelay, 0, 'computed endDelay'); + assert_equals(ct.fill, 'none', 'computed fill'); + assert_equals(ct.iterationStart, 0.0, 'computed iterationStart'); + assert_equals(ct.iterations, 1.0, 'computed iterations'); + assert_equals(ct.duration, 0, 'computed duration'); + assert_equals(ct.direction, 'normal', 'computed direction'); + assert_equals(ct.easing, 'linear', 'computed easing'); +}, 'values of getComputedTiming() when a KeyframeEffect is ' + + 'constructed without any KeyframeEffectOptions object'); + +const gGetComputedTimingTests = [ + { desc: 'an empty KeyframeEffectOptions object', + input: { }, + expected: { } }, + { desc: 'a normal KeyframeEffectOptions object', + input: { delay: 1000, + endDelay: 2000, + fill: 'auto', + iterationStart: 0.5, + iterations: 5.5, + duration: 'auto', + direction: 'alternate', + easing: 'steps(2)' }, + expected: { delay: 1000, + endDelay: 2000, + fill: 'none', + iterationStart: 0.5, + iterations: 5.5, + duration: 0, + direction: 'alternate', + easing: 'steps(2)' } }, + { desc: 'a double value', + input: 3000, + timing: { duration: 3000 }, + expected: { delay: 0, + fill: 'none', + iterations: 1, + duration: 3000, + direction: 'normal' } }, + { desc: '+Infinity', + input: Infinity, + expected: { duration: Infinity } }, + { desc: 'an Infinity duration', + input: { duration: Infinity }, + expected: { duration: Infinity } }, + { desc: 'an auto duration', + input: { duration: 'auto' }, + expected: { duration: 0 } }, + { desc: 'an Infinity iterations', + input: { iterations: Infinity }, + expected: { iterations: Infinity } }, + { desc: 'an auto fill', + input: { fill: 'auto' }, + expected: { fill: 'none' } }, + { desc: 'a forwards fill', + input: { fill: 'forwards' }, + expected: { fill: 'forwards' } } +]; + +for (const stest of gGetComputedTimingTests) { + test(t => { + const effect = new KeyframeEffect(null, null, stest.input); + + // Helper function to provide default expected values when the test does + // not supply them. + const expected = (field, defaultValue) => { + return field in stest.expected ? stest.expected[field] : defaultValue; + }; + + const ct = effect.getComputedTiming(); + assert_equals(ct.delay, expected('delay', 0), + 'computed delay'); + assert_equals(ct.endDelay, expected('endDelay', 0), + 'computed endDelay'); + assert_equals(ct.fill, expected('fill', 'none'), + 'computed fill'); + assert_equals(ct.iterationStart, expected('iterationStart', 0), + 'computed iterations'); + assert_equals(ct.iterations, expected('iterations', 1), + 'computed iterations'); + assert_equals(ct.duration, expected('duration', 0), + 'computed duration'); + assert_equals(ct.direction, expected('direction', 'normal'), + 'computed direction'); + assert_equals(ct.easing, expected('easing', 'linear'), + 'computed easing'); + + }, 'values of getComputedTiming() when a KeyframeEffect is' + + ` constructed by ${stest.desc}`); +} + +const gActiveDurationTests = [ + { desc: 'an empty KeyframeEffectOptions object', + input: { }, + expected: 0 }, + { desc: 'a non-zero duration and default iteration count', + input: { duration: 1000 }, + expected: 1000 }, + { desc: 'a non-zero duration and integral iteration count', + input: { duration: 1000, iterations: 7 }, + expected: 7000 }, + { desc: 'a non-zero duration and fractional iteration count', + input: { duration: 1000, iterations: 2.5 }, + expected: 2500 }, + { desc: 'an non-zero duration and infinite iteration count', + input: { duration: 1000, iterations: Infinity }, + expected: Infinity }, + { desc: 'an non-zero duration and zero iteration count', + input: { duration: 1000, iterations: 0 }, + expected: 0 }, + { desc: 'a zero duration and default iteration count', + input: { duration: 0 }, + expected: 0 }, + { desc: 'a zero duration and fractional iteration count', + input: { duration: 0, iterations: 2.5 }, + expected: 0 }, + { desc: 'a zero duration and infinite iteration count', + input: { duration: 0, iterations: Infinity }, + expected: 0 }, + { desc: 'a zero duration and zero iteration count', + input: { duration: 0, iterations: 0 }, + expected: 0 }, + { desc: 'an infinite duration and default iteration count', + input: { duration: Infinity }, + expected: Infinity }, + { desc: 'an infinite duration and zero iteration count', + input: { duration: Infinity, iterations: 0 }, + expected: 0 }, + { desc: 'an infinite duration and fractional iteration count', + input: { duration: Infinity, iterations: 2.5 }, + expected: Infinity }, + { desc: 'an infinite duration and infinite iteration count', + input: { duration: Infinity, iterations: Infinity }, + expected: Infinity }, +]; + +for (const stest of gActiveDurationTests) { + test(t => { + const effect = new KeyframeEffect(null, null, stest.input); + + assert_equals(effect.getComputedTiming().activeDuration, + stest.expected); + + }, `getComputedTiming().activeDuration for ${stest.desc}`); +} + +const gEndTimeTests = [ + { desc: 'an empty KeyframeEffectOptions object', + input: { }, + expected: 0 }, + { desc: 'a non-zero duration and default iteration count', + input: { duration: 1000 }, + expected: 1000 }, + { desc: 'a non-zero duration and non-default iteration count', + input: { duration: 1000, iterations: 2.5 }, + expected: 2500 }, + { desc: 'a non-zero duration and non-zero delay', + input: { duration: 1000, delay: 1500 }, + expected: 2500 }, + { desc: 'a non-zero duration, non-zero delay and non-default iteration', + input: { duration: 1000, delay: 1500, iterations: 2 }, + expected: 3500 }, + { desc: 'an infinite iteration count', + input: { duration: 1000, iterations: Infinity }, + expected: Infinity }, + { desc: 'an infinite duration', + input: { duration: Infinity, iterations: 10 }, + expected: Infinity }, + { desc: 'an infinite duration and delay', + input: { duration: Infinity, iterations: 10, delay: 1000 }, + expected: Infinity }, + { desc: 'an infinite duration and negative delay', + input: { duration: Infinity, iterations: 10, delay: -1000 }, + expected: Infinity }, + { desc: 'an non-zero duration and negative delay', + input: { duration: 1000, iterations: 2, delay: -1000 }, + expected: 1000 }, + { desc: 'an non-zero duration and negative delay greater than active ' + + 'duration', + input: { duration: 1000, iterations: 2, delay: -3000 }, + expected: 0 }, + { desc: 'a zero duration and negative delay', + input: { duration: 0, iterations: 2, delay: -1000 }, + expected: 0 } +]; + +for (const stest of gEndTimeTests) { + test(t => { + const effect = new KeyframeEffect(null, null, stest.input); + + assert_equals(effect.getComputedTiming().endTime, + stest.expected); + + }, `getComputedTiming().endTime for ${stest.desc}`); +} +</script> +</body> diff --git a/testing/web-platform/tests/web-animations/interfaces/AnimationEffect/updateTiming.html b/testing/web-platform/tests/web-animations/interfaces/AnimationEffect/updateTiming.html new file mode 100644 index 0000000000..6a340c0bf4 --- /dev/null +++ b/testing/web-platform/tests/web-animations/interfaces/AnimationEffect/updateTiming.html @@ -0,0 +1,475 @@ +<!doctype html> +<meta charset=utf-8> +<title>AnimationEffect.updateTiming</title> +<link rel="help" href="https://drafts.csswg.org/web-animations-1/#dom-animationeffect-updatetiming"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="../../testcommon.js"></script> +<script src="../../resources/easing-tests.js"></script> +<script src="../../resources/timing-tests.js"></script> +<body> +<div id="log"></div> +<script> +'use strict'; + +// ------------------------------ +// delay +// ------------------------------ + +test(t => { + const anim = createDiv(t).animate(null, 100); + anim.effect.updateTiming({ delay: 100 }); + assert_equals(anim.effect.getTiming().delay, 100, 'set delay 100'); + assert_equals(anim.effect.getComputedTiming().delay, 100, + 'getComputedTiming() after set delay 100'); +}, 'Allows setting the delay to a positive number'); + +test(t => { + const anim = createDiv(t).animate(null, 100); + anim.effect.updateTiming({ delay: -100 }); + assert_equals(anim.effect.getTiming().delay, -100, 'set delay -100'); + assert_equals(anim.effect.getComputedTiming().delay, -100, + 'getComputedTiming() after set delay -100'); +}, 'Allows setting the delay to a negative number'); + +test(t => { + const anim = createDiv(t).animate(null, 100); + anim.effect.updateTiming({ delay: 100 }); + assert_equals(anim.effect.getComputedTiming().progress, null); + assert_equals(anim.effect.getComputedTiming().currentIteration, null); +}, 'Allows setting the delay of an animation in progress: positive delay that' + + ' causes the animation to be no longer in-effect'); + +test(t => { + const anim = createDiv(t).animate(null, { fill: 'both', duration: 100 }); + anim.effect.updateTiming({ delay: -50 }); + assert_equals(anim.effect.getComputedTiming().progress, 0.5); +}, 'Allows setting the delay of an animation in progress: negative delay that' + + ' seeks into the active interval'); + +test(t => { + const anim = createDiv(t).animate(null, { fill: 'both', duration: 100 }); + anim.effect.updateTiming({ delay: -100 }); + assert_equals(anim.effect.getComputedTiming().progress, 1); + assert_equals(anim.effect.getComputedTiming().currentIteration, 0); +}, 'Allows setting the delay of an animation in progress: large negative delay' + + ' that causes the animation to be finished'); + +for (const invalid of gBadDelayValues) { + test(t => { + const anim = createDiv(t).animate(null); + assert_throws_js(TypeError, () => { + anim.effect.updateTiming({ delay: invalid }); + }); + }, `Throws when setting invalid delay value: ${invalid}`); +} + + +// ------------------------------ +// endDelay +// ------------------------------ + +test(t => { + const anim = createDiv(t).animate(null, 2000); + anim.effect.updateTiming({ endDelay: 123.45 }); + assert_time_equals_literal(anim.effect.getTiming().endDelay, 123.45, + 'set endDelay 123.45'); + assert_time_equals_literal(anim.effect.getComputedTiming().endDelay, 123.45, + 'getComputedTiming() after set endDelay 123.45'); +}, 'Allows setting the endDelay to a positive number'); + +test(t => { + const anim = createDiv(t).animate(null, 2000); + anim.effect.updateTiming({ endDelay: -1000 }); + assert_equals(anim.effect.getTiming().endDelay, -1000, 'set endDelay -1000'); + assert_equals(anim.effect.getComputedTiming().endDelay, -1000, + 'getComputedTiming() after set endDelay -1000'); +}, 'Allows setting the endDelay to a negative number'); + +test(t => { + const anim = createDiv(t).animate(null, 2000); + assert_throws_js(TypeError, () => { + anim.effect.updateTiming({ endDelay: Infinity }); + }); +}, 'Throws when setting the endDelay to infinity'); + +test(t => { + const anim = createDiv(t).animate(null, 2000); + assert_throws_js(TypeError, () => { + anim.effect.updateTiming({ endDelay: -Infinity }); + }); +}, 'Throws when setting the endDelay to negative infinity'); + + +// ------------------------------ +// fill +// ------------------------------ + +for (const fill of ['none', 'forwards', 'backwards', 'both']) { + test(t => { + const anim = createDiv(t).animate(null, 100); + anim.effect.updateTiming({ fill }); + assert_equals(anim.effect.getTiming().fill, fill, 'set fill ' + fill); + assert_equals(anim.effect.getComputedTiming().fill, fill, + 'getComputedTiming() after set fill ' + fill); + }, `Allows setting the fill to '${fill}'`); +} + + +// ------------------------------ +// iterationStart +// ------------------------------ + +test(t => { + const anim = createDiv(t).animate(null, + { iterationStart: 0.2, + iterations: 1, + fill: 'both', + duration: 100, + delay: 1 }); + anim.effect.updateTiming({ iterationStart: 2.5 }); + assert_time_equals_literal(anim.effect.getComputedTiming().progress, 0.5); + assert_equals(anim.effect.getComputedTiming().currentIteration, 2); +}, 'Allows setting the iterationStart of an animation in progress:' + + ' backwards-filling'); + +test(t => { + const anim = createDiv(t).animate(null, + { iterationStart: 0.2, + iterations: 1, + fill: 'both', + duration: 100, + delay: 0 }); + anim.effect.updateTiming({ iterationStart: 2.5 }); + assert_time_equals_literal(anim.effect.getComputedTiming().progress, 0.5); + assert_equals(anim.effect.getComputedTiming().currentIteration, 2); +}, 'Allows setting the iterationStart of an animation in progress:' + + ' active phase'); + +test(t => { + const anim = createDiv(t).animate(null, + { iterationStart: 0.2, + iterations: 1, + fill: 'both', + duration: 100, + delay: 0 }); + anim.finish(); + anim.effect.updateTiming({ iterationStart: 2.5 }); + assert_time_equals_literal(anim.effect.getComputedTiming().progress, 0.5); + assert_equals(anim.effect.getComputedTiming().currentIteration, 3); +}, 'Allows setting the iterationStart of an animation in progress:' + + ' forwards-filling'); + +for (const invalid of gBadIterationStartValues) { + test(t => { + const anim = createDiv(t).animate(null); + assert_throws_js(TypeError, () => { + anim.effect.updateTiming({ iterationStart: invalid }); + }, `setting ${invalid}`); + }, `Throws when setting invalid iterationStart value: ${invalid}`); +} + +// ------------------------------ +// iterations +// ------------------------------ + +test(t => { + const anim = createDiv(t).animate(null, 2000); + anim.effect.updateTiming({ iterations: 2 }); + assert_equals(anim.effect.getTiming().iterations, 2, 'set duration 2'); + assert_equals(anim.effect.getComputedTiming().iterations, 2, + 'getComputedTiming() after set iterations 2'); +}, 'Allows setting iterations to a double value'); + +test(t => { + const anim = createDiv(t).animate(null, 2000); + anim.effect.updateTiming({ iterations: Infinity }); + assert_equals(anim.effect.getTiming().iterations, Infinity, + 'set duration Infinity'); + assert_equals(anim.effect.getComputedTiming().iterations, Infinity, + 'getComputedTiming() after set iterations Infinity'); +}, 'Allows setting iterations to infinity'); + +for (const invalid of gBadIterationsValues) { + test(t => { + const anim = createDiv(t).animate(null); + assert_throws_js(TypeError, () => { + anim.effect.updateTiming({ iterations: invalid }); + }); + }, `Throws when setting invalid iterations value: ${invalid}`); +} + +test(t => { + const anim = createDiv(t).animate(null, { duration: 100000, fill: 'both' }); + + anim.finish(); + + assert_equals(anim.effect.getComputedTiming().progress, 1, + 'progress when animation is finished'); + assert_equals(anim.effect.getComputedTiming().currentIteration, 0, + 'current iteration when animation is finished'); + + anim.effect.updateTiming({ iterations: 2 }); + + assert_time_equals_literal(anim.effect.getComputedTiming().progress, + 0, + 'progress after adding an iteration'); + assert_time_equals_literal(anim.effect.getComputedTiming().currentIteration, + 1, + 'current iteration after adding an iteration'); + + anim.effect.updateTiming({ iterations: 0 }); + + assert_equals(anim.effect.getComputedTiming().progress, 0, + 'progress after setting iterations to zero'); + assert_equals(anim.effect.getComputedTiming().currentIteration, 0, + 'current iteration after setting iterations to zero'); + + anim.effect.updateTiming({ iterations: Infinity }); + + assert_equals(anim.effect.getComputedTiming().progress, 0, + 'progress after setting iterations to Infinity'); + assert_equals(anim.effect.getComputedTiming().currentIteration, 1, + 'current iteration after setting iterations to Infinity'); +}, 'Allows setting the iterations of an animation in progress'); + + +// ------------------------------ +// duration +// ------------------------------ + +for (const duration of gGoodDurationValues) { + test(t => { + const anim = createDiv(t).animate(null, 2000); + anim.effect.updateTiming({ duration: duration.specified }); + if (typeof duration.specified === 'number') { + assert_time_equals_literal(anim.effect.getTiming().duration, + duration.specified, + 'Updates specified duration'); + } else { + assert_equals(anim.effect.getTiming().duration, duration.specified, + 'Updates specified duration'); + } + assert_time_equals_literal(anim.effect.getComputedTiming().duration, + duration.computed, + 'Updates computed duration'); + }, `Allows setting the duration to ${duration.specified}`); +} + +for (const invalid of gBadDurationValues) { + test(t => { + assert_throws_js(TypeError, () => { + createDiv(t).animate(null, { duration: invalid }); + }); + }, 'Throws when setting invalid duration: ' + + (typeof invalid === 'string' ? `"${invalid}"` : invalid)); +} + +test(t => { + const anim = createDiv(t).animate(null, { duration: 100000, fill: 'both' }); + anim.finish(); + assert_equals(anim.effect.getComputedTiming().progress, 1, + 'progress when animation is finished'); + anim.effect.updateTiming({ duration: anim.effect.getTiming().duration * 2 }); + assert_time_equals_literal(anim.effect.getComputedTiming().progress, 0.5, + 'progress after doubling the duration'); + anim.effect.updateTiming({ duration: 0 }); + assert_equals(anim.effect.getComputedTiming().progress, 1, + 'progress after setting duration to zero'); + anim.effect.updateTiming({ duration: 'auto' }); + assert_equals(anim.effect.getComputedTiming().progress, 1, + 'progress after setting duration to \'auto\''); +}, 'Allows setting the duration of an animation in progress'); + +promise_test(t => { + const anim = createDiv(t).animate(null, 100 * MS_PER_SEC); + return anim.ready.then(() => { + const originalStartTime = anim.startTime; + const originalCurrentTime = anim.currentTime; + assert_time_equals_literal( + anim.effect.getComputedTiming().duration, + 100 * MS_PER_SEC, + 'Initial duration should be as set on KeyframeEffect' + ); + + anim.effect.updateTiming({ duration: 200 * MS_PER_SEC }); + assert_time_equals_literal( + anim.effect.getComputedTiming().duration, + 200 * MS_PER_SEC, + 'Effect duration should have been updated' + ); + assert_times_equal(anim.startTime, originalStartTime, + 'startTime should be unaffected by changing effect ' + + 'duration'); + assert_times_equal(anim.currentTime, originalCurrentTime, + 'currentTime should be unaffected by changing effect ' + + 'duration'); + }); +}, 'Allows setting the duration of an animation in progress such that the' + + ' the start and current time do not change'); + + +// ------------------------------ +// direction +// ------------------------------ + +test(t => { + const anim = createDiv(t).animate(null, 2000); + + const directions = ['normal', 'reverse', 'alternate', 'alternate-reverse']; + for (const direction of directions) { + anim.effect.updateTiming({ direction: direction }); + assert_equals(anim.effect.getTiming().direction, direction, + `set direction to ${direction}`); + } +}, 'Allows setting the direction to each of the possible keywords'); + +test(t => { + const anim = createDiv(t).animate(null, { + duration: 10000, + direction: 'normal', + }); + anim.currentTime = 7000; + assert_time_equals_literal(anim.effect.getComputedTiming().progress, 0.7, + 'progress before updating direction'); + + anim.effect.updateTiming({ direction: 'reverse' }); + + assert_time_equals_literal(anim.effect.getComputedTiming().progress, 0.3, + 'progress after updating direction'); +}, 'Allows setting the direction of an animation in progress from \'normal\' to' + + ' \'reverse\''); + +test(t => { + const anim = createDiv(t).animate(null, + { duration: 10000, direction: 'normal' }); + assert_equals(anim.effect.getComputedTiming().progress, 0, + 'progress before updating direction'); + + anim.effect.updateTiming({ direction: 'reverse' }); + + assert_equals(anim.effect.getComputedTiming().progress, 1, + 'progress after updating direction'); +}, 'Allows setting the direction of an animation in progress from \'normal\' to' + + ' \'reverse\' while at start of active interval'); + +test(t => { + const anim = createDiv(t).animate(null, + { fill: 'backwards', + duration: 10000, + delay: 10000, + direction: 'normal' }); + assert_equals(anim.effect.getComputedTiming().progress, 0, + 'progress before updating direction'); + + anim.effect.updateTiming({ direction: 'reverse' }); + + assert_equals(anim.effect.getComputedTiming().progress, 1, + 'progress after updating direction'); +}, 'Allows setting the direction of an animation in progress from \'normal\' to' + + ' \'reverse\' while filling backwards'); + +test(t => { + const anim = createDiv(t).animate(null, + { iterations: 2, + duration: 10000, + direction: 'normal' }); + anim.currentTime = 17000; + assert_time_equals_literal(anim.effect.getComputedTiming().progress, 0.7, + 'progress before updating direction'); + + anim.effect.updateTiming({ direction: 'alternate' }); + + assert_time_equals_literal(anim.effect.getComputedTiming().progress, 0.3, + 'progress after updating direction'); +}, 'Allows setting the direction of an animation in progress from \'normal\' to' + + ' \'alternate\''); + +test(t => { + const anim = createDiv(t).animate(null, + { iterations: 2, + duration: 10000, + direction: 'alternate' }); + anim.currentTime = 17000; + assert_time_equals_literal(anim.effect.getComputedTiming().progress, 0.3, + 'progress before updating direction'); + + anim.effect.updateTiming({ direction: 'alternate-reverse' }); + + assert_time_equals_literal(anim.effect.getComputedTiming().progress, 0.7, + 'progress after updating direction'); +}, 'Allows setting the direction of an animation in progress from \'alternate\'' + + ' to \'alternate-reverse\''); + + +// ------------------------------ +// easing +// ------------------------------ + +function assert_progress(animation, currentTime, easingFunction) { + animation.currentTime = currentTime; + const portion = currentTime / animation.effect.getTiming().duration; + assert_approx_equals(animation.effect.getComputedTiming().progress, + easingFunction(portion), + 0.01, + 'The progress of the animation should be approximately' + + ` ${easingFunction(portion)} at ${currentTime}ms`); +} + +for (const options of gEasingTests) { + test(t => { + const target = createDiv(t); + const anim = target.animate(null, + { duration: 1000 * MS_PER_SEC, + fill: 'forwards' }); + anim.effect.updateTiming({ easing: options.easing }); + assert_equals(anim.effect.getTiming().easing, + options.serialization || options.easing); + + const easing = options.easingFunction; + assert_progress(anim, 0, easing); + assert_progress(anim, 250 * MS_PER_SEC, easing); + assert_progress(anim, 500 * MS_PER_SEC, easing); + assert_progress(anim, 750 * MS_PER_SEC, easing); + assert_progress(anim, 1000 * MS_PER_SEC, easing); + }, `Allows setting the easing to a ${options.desc}`); +} + +for (const easing of gRoundtripEasings) { + test(t => { + const anim = createDiv(t).animate(null); + anim.effect.updateTiming({ easing: easing }); + assert_equals(anim.effect.getTiming().easing, easing); + }, `Updates the specified value when setting the easing to '${easing}'`); +} + +test(t => { + const delay = 1000 * MS_PER_SEC; + + const target = createDiv(t); + const anim = target.animate(null, + { duration: 1000 * MS_PER_SEC, + fill: 'both', + delay: delay, + easing: 'steps(2, start)' }); + + anim.effect.updateTiming({ easing: 'steps(2, end)' }); + assert_equals(anim.effect.getComputedTiming().progress, 0, + 'easing replace to steps(2, end) at before phase'); + + anim.currentTime = delay + 750 * MS_PER_SEC; + assert_equals(anim.effect.getComputedTiming().progress, 0.5, + 'change currentTime to active phase'); + + anim.effect.updateTiming({ easing: 'steps(2, start)' }); + assert_equals(anim.effect.getComputedTiming().progress, 1, + 'easing replace to steps(2, start) at active phase'); + + anim.currentTime = delay + 1500 * MS_PER_SEC; + anim.effect.updateTiming({ easing: 'steps(2, end)' }); + assert_equals(anim.effect.getComputedTiming().progress, 1, + 'easing replace to steps(2, end) again at after phase'); +}, 'Allows setting the easing of an animation in progress'); + +</script> +</body> |