diff options
Diffstat (limited to 'testing/web-platform/tests/web-animations/timing-model/animations/seamlessly-updating-the-playback-rate-of-an-animation.html')
-rw-r--r-- | testing/web-platform/tests/web-animations/timing-model/animations/seamlessly-updating-the-playback-rate-of-an-animation.html | 171 |
1 files changed, 171 insertions, 0 deletions
diff --git a/testing/web-platform/tests/web-animations/timing-model/animations/seamlessly-updating-the-playback-rate-of-an-animation.html b/testing/web-platform/tests/web-animations/timing-model/animations/seamlessly-updating-the-playback-rate-of-an-animation.html new file mode 100644 index 0000000000..dffbeabd59 --- /dev/null +++ b/testing/web-platform/tests/web-animations/timing-model/animations/seamlessly-updating-the-playback-rate-of-an-animation.html @@ -0,0 +1,171 @@ +<!doctype html> +<meta charset=utf-8> +<title>Seamlessly updating the playback rate of an animation</title> +<link rel="help" + href="https://drafts.csswg.org/web-animations-1/#seamlessly-updating-the-playback-rate-of-an-animation"> +<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'; + +promise_test(async t => { + const animation = createDiv(t).animate(null, 100 * MS_PER_SEC); + await animation.ready; + + animation.currentTime = 50 * MS_PER_SEC; + + animation.updatePlaybackRate(0.5); + await animation.ready; + // Since the animation is in motion (and we want to test it while it is in + // motion!) we can't assert that the current time == 50s but we can check + // that the current time is NOT re-calculated by simply substituting in the + // new playback rate (i.e. without adjusting the start time). If that were + // the case the currentTime would jump to 25s. So we just test the currentTime + // hasn't gone backwards. + assert_greater_than_equal(animation.currentTime, 50 * MS_PER_SEC, + 'Reducing the playback rate should not change the current time ' + + 'of a playing animation'); + + animation.updatePlaybackRate(2); + await animation.ready; + // Likewise, we test here that the current time does not jump to 100s as it + // would if we naively applied a playbackRate of 2 without adjusting the + // startTime. + assert_less_than(animation.currentTime, 100 * MS_PER_SEC, + 'Increasing the playback rate should not change the current time ' + + 'of a playing animation'); +}, 'Updating the playback rate maintains the current time'); + +promise_test(async t => { + const animation = createDiv(t).animate(null, 100 * MS_PER_SEC); + await animation.ready; + + assert_false(animation.pending); + animation.updatePlaybackRate(2); + assert_true(animation.pending); +}, 'Updating the playback rate while running makes the animation pending'); + +promise_test(async t => { + const animation = createDiv(t).animate(null, 100 * MS_PER_SEC); + animation.currentTime = 50 * MS_PER_SEC; + assert_true(animation.pending); + + animation.updatePlaybackRate(0.5); + + // Check that the hold time is updated as expected + assert_time_equals_literal(animation.currentTime, 50 * MS_PER_SEC); + + await animation.ready; + + // As above, check that the currentTime is not calculated by simply + // substituting in the updated playbackRate without updating the startTime. + assert_greater_than_equal(animation.currentTime, 50 * MS_PER_SEC, + 'Reducing the playback rate should not change the current time ' + + 'of a play-pending animation'); +}, 'Updating the playback rate on a play-pending animation maintains' + + ' the current time'); + +promise_test(async t => { + const animation = createDiv(t).animate(null, 100 * MS_PER_SEC); + animation.currentTime = 50 * MS_PER_SEC; + await animation.ready; + + animation.pause(); + animation.updatePlaybackRate(0.5); + + assert_greater_than_equal(animation.currentTime, 50 * MS_PER_SEC); +}, 'Updating the playback rate on a pause-pending animation maintains' + + ' the current time'); + +promise_test(async t => { + const animation = createDiv(t).animate(null, 100 * MS_PER_SEC); + + animation.updatePlaybackRate(2); + animation.updatePlaybackRate(3); + animation.updatePlaybackRate(4); + + assert_equals(animation.playbackRate, 1); + await animation.ready; + + assert_equals(animation.playbackRate, 4); +}, 'If a pending playback rate is set multiple times, the latest wins'); + +test(t => { + const animation = createDiv(t).animate(null, 100 * MS_PER_SEC); + animation.cancel(); + + animation.updatePlaybackRate(2); + assert_equals(animation.playbackRate, 2); + assert_false(animation.pending); +}, 'In the idle state, the playback rate is applied immediately'); + +promise_test(async t => { + const animation = createDiv(t).animate(null, 100 * MS_PER_SEC); + animation.pause(); + await animation.ready; + + animation.updatePlaybackRate(2); + assert_equals(animation.playbackRate, 2); + assert_false(animation.pending); +}, 'In the paused state, the playback rate is applied immediately'); + +promise_test(async t => { + const animation = createDiv(t).animate(null, 100 * MS_PER_SEC); + animation.finish(); + assert_time_equals_literal(animation.currentTime, 100 * MS_PER_SEC); + assert_false(animation.pending); + + animation.updatePlaybackRate(2); + assert_equals(animation.playbackRate, 2); + assert_time_equals_literal(animation.currentTime, 100 * MS_PER_SEC); + assert_false(animation.pending); +}, 'Updating the playback rate on a finished animation maintains' + + ' the current time'); + +promise_test(async t => { + const animation = createDiv(t).animate(null, 100 * MS_PER_SEC); + animation.finish(); + assert_time_equals_literal(animation.currentTime, 100 * MS_PER_SEC); + assert_false(animation.pending); + + animation.updatePlaybackRate(0); + assert_equals(animation.playbackRate, 0); + assert_time_equals_literal(animation.currentTime, 100 * MS_PER_SEC); + assert_false(animation.pending); +}, 'Updating the playback rate to zero on a finished animation maintains' + + ' the current time'); + +promise_test(async t => { + const animation = createDiv(t).animate(null, 100 * MS_PER_SEC); + await animation.ready; + + // Get the animation in a state where it has an unresolved current time, + // a resolved start time (so it is not 'idle') and but no pending play task. + animation.timeline = null; + animation.startTime = 0; + assert_equals(animation.currentTime, null); + assert_equals(animation.playState, 'running'); + + // Make the effect end infinite. + animation.effect.updateTiming({ endDelay: 1e38 }); + + // Now we want to check that when we go to set a negative playback rate we + // don't end up throwing an InvalidStateError (which would happen if we ended + // up applying the auto-rewind behavior). + animation.updatePlaybackRate(-1); + + // Furthermore, we should apply the playback rate immediately since the + // current time is unresolved. + assert_equals(animation.playbackRate, -1, + 'We apply the pending playback rate immediately if the current time is ' + + 'unresolved'); + assert_false(animation.pending); +}, 'Updating the negative playback rate with the unresolved current time and' + + ' a positive infinite associated effect end should not throw an' + + ' exception'); + +</script> +</body> |