diff options
Diffstat (limited to 'dom/animation/test/css-animations/file_animation-currenttime.html')
-rw-r--r-- | dom/animation/test/css-animations/file_animation-currenttime.html | 345 |
1 files changed, 345 insertions, 0 deletions
diff --git a/dom/animation/test/css-animations/file_animation-currenttime.html b/dom/animation/test/css-animations/file_animation-currenttime.html new file mode 100644 index 000000000..ec6fb3f1a --- /dev/null +++ b/dom/animation/test/css-animations/file_animation-currenttime.html @@ -0,0 +1,345 @@ +<!doctype html> +<html> + <head> + <meta charset=utf-8> + <title>Tests for the effect of setting a CSS animation's + Animation.currentTime</title> + <style> + +.animated-div { + margin-left: 10px; + /* Make it easier to calculate expected values: */ + animation-timing-function: linear ! important; +} + +@keyframes anim { + from { margin-left: 100px; } + to { margin-left: 200px; } +} + + </style> + <script src="../testcommon.js"></script> + </head> + <body> + <script type="text/javascript"> + +'use strict'; + +// TODO: We should separate this test(Testing for CSS Animation events / +// Testing for currentTime of Web Animation). +// e.g: +// CSS Animation events test : +// - check the firing an event using Animation.currentTime +// The current Time of Web Animation test : +// - check an current time value on several situation(init / processing..) +// - Based on W3C Spec, check the behavior of setting current time. + +// TODO: Once the computedTiming property is implemented, add checks to the +// checker helpers to ensure that computedTiming's properties are updated as +// expected. +// See https://bugzilla.mozilla.org/show_bug.cgi?id=1108055 + +const CSS_ANIM_EVENTS = + ['animationstart', 'animationiteration', 'animationend']; + +test(function(t) +{ + var div = addDiv(t, {'class': 'animated-div'}); + div.style.animation = "anim 100s"; + var animation = div.getAnimations()[0]; + + // Animations shouldn't start until the next paint tick, so: + assert_equals(animation.currentTime, 0, + 'Animation.currentTime should be zero when an animation ' + + 'is initially created'); + + // Make sure the animation is running before we set the current time. + animation.startTime = animation.timeline.currentTime; + + animation.currentTime = 50 * MS_PER_SEC; + assert_times_equal(animation.currentTime, 50 * MS_PER_SEC, + 'Check setting of currentTime actually works'); +}, 'Sanity test to check round-tripping assigning to new animation\'s ' + + 'currentTime'); + +promise_test(function(t) { + var div = addDiv(t, {'class': 'animated-div'}); + var eventWatcher = new EventWatcher(t, div, CSS_ANIM_EVENTS); + div.style.animation = "anim 100s 100s"; + var animation = div.getAnimations()[0]; + + return animation.ready.then(function() { + // the 0.0001 here is for rounding error + assert_less_than_equal(animation.currentTime, + animation.timeline.currentTime - animation.startTime + 0.0001, + 'Animation.currentTime should be less than the local time ' + + 'equivalent of the timeline\'s currentTime on the first paint tick ' + + 'after animation creation'); + + animation.currentTime = 100 * MS_PER_SEC; + return eventWatcher.wait_for('animationstart'); + }).then(function() { + animation.currentTime = 200 * MS_PER_SEC; + return eventWatcher.wait_for('animationend'); + }); +}, 'Skipping forward through animation'); + +promise_test(function(t) { + var div = addDiv(t, {'class': 'animated-div'}); + var eventWatcher = new EventWatcher(t, div, CSS_ANIM_EVENTS); + div.style.animation = "anim 100s 100s"; + var animation = div.getAnimations()[0]; + animation.currentTime = 200 * MS_PER_SEC; + var previousTimelineTime = animation.timeline.currentTime; + + return eventWatcher.wait_for(['animationstart', + 'animationend']).then(function() { + assert_true(document.timeline.currentTime - previousTimelineTime < + 100 * MS_PER_SEC, + 'Sanity check that seeking worked rather than the events ' + + 'firing after normal playback through the very long ' + + 'animation duration'); + + animation.currentTime = 150 * MS_PER_SEC; + return eventWatcher.wait_for('animationstart'); + }).then(function() { + animation.currentTime = 0; + return eventWatcher.wait_for('animationend'); + }); +}, 'Skipping backwards through animation'); + +// Next we have multiple tests to check that redundant currentTime changes do +// NOT dispatch events. It's impossible to distinguish between events not being +// dispatched and events just taking an incredibly long time to dispatch +// without waiting an infinitely long time. Obviously we don't want to do that +// (block this test from finishing forever), so instead we just listen for +// events until two animation frames (i.e. requestAnimationFrame callbacks) +// have happened, then assume that no events will ever be dispatched for the +// redundant changes if no events were detected in that time. + +promise_test(function(t) { + var div = addDiv(t, {'class': 'animated-div'}); + var eventWatcher = new EventWatcher(t, div, CSS_ANIM_EVENTS); + div.style.animation = "anim 100s 100s"; + var animation = div.getAnimations()[0]; + + animation.currentTime = 150 * MS_PER_SEC; + animation.currentTime = 50 * MS_PER_SEC; + + return waitForAnimationFrames(2); +}, 'Redundant change, before -> active, then back'); + +promise_test(function(t) { + var div = addDiv(t, {'class': 'animated-div'}); + var eventWatcher = new EventWatcher(t, div, CSS_ANIM_EVENTS); + div.style.animation = "anim 100s 100s"; + var animation = div.getAnimations()[0]; + + animation.currentTime = 250 * MS_PER_SEC; + animation.currentTime = 50 * MS_PER_SEC; + + return waitForAnimationFrames(2); +}, 'Redundant change, before -> after, then back'); + +promise_test(function(t) { + var div = addDiv(t, {'class': 'animated-div'}); + var eventWatcher = new EventWatcher(t, div, CSS_ANIM_EVENTS); + div.style.animation = "anim 100s 100s"; + var animation = div.getAnimations()[0]; + + var retPromise = eventWatcher.wait_for('animationstart').then(function() { + animation.currentTime = 50 * MS_PER_SEC; + animation.currentTime = 150 * MS_PER_SEC; + + return waitForAnimationFrames(2); + }); + // get us into the initial state: + animation.currentTime = 150 * MS_PER_SEC; + + return retPromise; +}, 'Redundant change, active -> before, then back'); + +promise_test(function(t) { + var div = addDiv(t, {'class': 'animated-div'}); + var eventWatcher = new EventWatcher(t, div, CSS_ANIM_EVENTS); + div.style.animation = "anim 100s 100s"; + var animation = div.getAnimations()[0]; + + var retPromise = eventWatcher.wait_for('animationstart').then(function() { + animation.currentTime = 250 * MS_PER_SEC; + animation.currentTime = 150 * MS_PER_SEC; + + return waitForAnimationFrames(2); + }); + // get us into the initial state: + animation.currentTime = 150 * MS_PER_SEC; + + return retPromise; +}, 'Redundant change, active -> after, then back'); + +promise_test(function(t) { + var div = addDiv(t, {'class': 'animated-div'}); + var eventWatcher = new EventWatcher(t, div, CSS_ANIM_EVENTS); + div.style.animation = "anim 100s 100s"; + var animation = div.getAnimations()[0]; + + var retPromise = eventWatcher.wait_for(['animationstart', + 'animationend']).then(function() { + animation.currentTime = 50 * MS_PER_SEC; + animation.currentTime = 250 * MS_PER_SEC; + + return waitForAnimationFrames(2); + }); + // get us into the initial state: + animation.currentTime = 250 * MS_PER_SEC; + + return retPromise; +}, 'Redundant change, after -> before, then back'); + +promise_test(function(t) { + var div = addDiv(t, {'class': 'animated-div'}); + var eventWatcher = new EventWatcher(t, div, CSS_ANIM_EVENTS); + div.style.animation = "anim 100s 100s"; + var animation = div.getAnimations()[0]; + + var retPromise = eventWatcher.wait_for(['animationstart', + 'animationend']).then(function() { + animation.currentTime = 150 * MS_PER_SEC; + animation.currentTime = 250 * MS_PER_SEC; + + return waitForAnimationFrames(2); + }); + // get us into the initial state: + animation.currentTime = 250 * MS_PER_SEC; + + return retPromise; +}, 'Redundant change, after -> active, then back'); + +promise_test(function(t) { + var div = addDiv(t, {'class': 'animated-div'}); + var eventWatcher = new EventWatcher(t, div, CSS_ANIM_EVENTS); + div.style.animation = "anim 100s" + var animation = div.getAnimations()[0]; + + animation.pause(); + animation.currentTime = 150 * MS_PER_SEC; + + return eventWatcher.wait_for(['animationstart', + 'animationend']).then(function() { + animation.currentTime = 50 * MS_PER_SEC; + return eventWatcher.wait_for('animationstart'); + }); +}, 'Seeking finished -> paused dispatches animationstart'); + +promise_test(function(t) { + var div = addDiv(t, {'class': 'animated-div'}); + div.style.animation = "anim 100s"; + + var animation = div.getAnimations()[0]; + + return animation.ready.then(function() { + var exception; + try { + animation.currentTime = null; + } catch (e) { + exception = e; + } + assert_equals(exception.name, 'TypeError', + 'Expect TypeError exception on trying to set ' + + 'Animation.currentTime to null'); + }); +}, 'Setting currentTime to null'); + +promise_test(function(t) { + var div = addDiv(t, {'class': 'animated-div'}); + div.style.animation = 'anim 100s'; + + var animation = div.getAnimations()[0]; + var pauseTime; + + return animation.ready.then(function() { + assert_not_equals(animation.currentTime, null, + 'Animation.currentTime not null on ready Promise resolve'); + animation.pause(); + return animation.ready; + }).then(function() { + pauseTime = animation.currentTime; + return waitForFrame(); + }).then(function() { + assert_equals(animation.currentTime, pauseTime, + 'Animation.currentTime is unchanged after pausing'); + }); +}, 'Animation.currentTime after pausing'); + +promise_test(function(t) { + var div = addDiv(t, {'class': 'animated-div'}); + div.style.animation = "anim 100s"; + var animation = div.getAnimations()[0]; + + return animation.ready.then(function() { + // just before animation ends: + animation.currentTime = 100 * MS_PER_SEC - 1; + return waitForAnimationFrames(2); + }).then(function() { + assert_equals(animation.currentTime, 100 * MS_PER_SEC, + 'Animation.currentTime should not continue to increase after the ' + + 'animation has finished'); + }); +}, 'Animation.currentTime clamping'); + +promise_test(function(t) { + var div = addDiv(t, {'class': 'animated-div'}); + div.style.animation = "anim 100s"; + var animation = div.getAnimations()[0]; + + return animation.ready.then(function() { + // play backwards: + animation.playbackRate = -1; + + // just before animation ends (at the "start"): + animation.currentTime = 1; + + return waitForAnimationFrames(2); + }).then(function() { + assert_equals(animation.currentTime, 0, + 'Animation.currentTime should not continue to decrease after an ' + + 'animation running in reverse has finished and currentTime is zero'); + }); +}, 'Animation.currentTime clamping for reversed animation'); + +test(function(t) { + var div = addDiv(t, {'class': 'animated-div'}); + div.style.animation = 'anim 100s'; + var animation = div.getAnimations()[0]; + animation.cancel(); + + assert_equals(animation.currentTime, null, + 'The currentTime of a cancelled animation should be null'); +}, 'Animation.currentTime after cancelling'); + +promise_test(function(t) { + var div = addDiv(t, {'class': 'animated-div'}); + div.style.animation = 'anim 100s'; + var animation = div.getAnimations()[0]; + + return animation.ready.then(function() { + animation.finish(); + + // Initiate a pause then abort it + animation.pause(); + animation.play(); + + // Wait to return to running state + return animation.ready; + }).then(function() { + assert_true(animation.currentTime < 100 * 1000, + 'After aborting a pause when finished, the currentTime should' + + ' jump back towards the start of the animation'); + }); +}, 'After aborting a pause when finished, the call to play() should rewind' + + ' the current time'); + +done(); + </script> + </body> +</html> |