Source code
Revision control
Copy as Markdown
Other Tools
Test Info:
- This WPT test may be referenced by the following Test IDs:
            
- /css/css-animations/CSSAnimation-pausing.tentative.html - WPT Dashboard Interop Dashboard
 
 
<!doctype html>
<meta charset=utf-8>
<title>Pausing a CSSAnimation</title>
<link rel="help"
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="support/testcommon.js"></script>
<style>
@keyframes anim {
  0% { margin-left: 0px }
  100% { margin-left: 10000px }
}
</style>
<div id="log"></div>
<script>
'use strict';
promise_test(async t => {
  const div = addDiv(t);
  div.style.animation = 'anim 1000s paused';
  const animation = div.getAnimations()[0];
  animation.play();
  await animation.ready;
  await waitForNextFrame();
  assert_equals(
    animation.playState,
    'running',
    'Play state is running after calling play()'
  );
  // Flip the animation-play-state back and forth to check it has no effect
  div.style.animationPlayState = 'running';
  getComputedStyle(div).animationPlayState;
  div.style.animationPlayState = 'paused';
  getComputedStyle(div).animationPlayState;
  assert_equals(
    animation.playState,
    'running',
    'Should still be running even after flipping the animation-play-state'
  );
}, 'play() overrides animation-play-state');
promise_test(async t => {
  const div = addDiv(t);
  div.style.animation = 'anim 100s infinite paused';
  const animation = div.getAnimations()[0];
  animation.playbackRate = -1;
  animation.currentTime = -1;
  assert_throws_dom('InvalidStateError', () => {
    animation.play();
  }, 'Trying to play a reversed infinite animation should throw');
  assert_equals(
    animation.playState,
    'paused',
    'Animation should still be paused'
  );
  animation.playbackRate = 1;
  div.style.animationPlayState = 'running';
  assert_equals(
    animation.playState,
    'running',
    'Changing the animation-play-state should play the animation'
  );
}, 'play() does NOT override the animation-play-state if there was an error');
promise_test(async t => {
  const div = addDiv(t);
  div.style.animation = 'anim 1000s paused';
  const animation = div.getAnimations()[0];
  animation.pause();
  div.style.animationPlayState = 'running';
  getComputedStyle(div).animationPlayState;
  await animation.ready;
  await waitForNextFrame();
  assert_equals(animation.playState, 'paused', 'playState is paused ');
  // Flip the animation-play-state back and forth to check it has no effect
  div.style.animationPlayState = 'paused';
  getComputedStyle(div).animationPlayState;
  div.style.animationPlayState = 'running';
  getComputedStyle(div).animationPlayState;
  assert_equals(
    animation.playState,
    'paused',
    'Should still be paused even after flipping the animation-play-state'
  );
}, 'pause() overrides animation-play-state');
promise_test(async t => {
  const div = addDiv(t);
  div.style.animation = 'anim 100s paused';
  const animation = div.getAnimations()[0];
  animation.reverse();
  assert_equals(
    animation.playState,
    'running',
    'Play state is running after calling reverse()'
  );
  // Flip the animation-play-state back and forth to check it has no effect
  div.style.animationPlayState = 'running';
  getComputedStyle(div).animationPlayState;
  div.style.animationPlayState = 'paused';
  getComputedStyle(div).animationPlayState;
  assert_equals(
    animation.playState,
    'running',
    'Should still be running even after flipping the animation-play-state'
  );
}, 'reverse() overrides animation-play-state when it starts playing the'
   + ' animation');
promise_test(async t => {
  const div = addDiv(t);
  div.style.animation = 'anim 100s';
  const animation = div.getAnimations()[0];
  animation.reverse();
  assert_equals(
    animation.playState,
    'running',
    'Play state is running after calling reverse()'
  );
  div.style.animationPlayState = 'paused';
  getComputedStyle(div).animationPlayState;
  assert_equals(
    animation.playState,
    'paused',
    'Should be paused after changing the animation-play-state'
  );
}, 'reverse() does NOT override animation-play-state if the animation is'
   + ' already running');
promise_test(async t => {
  const div = addDiv(t);
  div.style.animation = 'anim 100s';
  const animation = div.getAnimations()[0];
  animation.startTime = null;
  assert_equals(
    animation.playState,
    'paused',
    'Play state is paused after setting the start time to null'
  );
  // Flip the animation-play-state back and forth to check it has no effect
  div.style.animationPlayState = 'paused';
  getComputedStyle(div).animationPlayState;
  div.style.animationPlayState = 'running';
  getComputedStyle(div).animationPlayState;
  assert_equals(
    animation.playState,
    'paused',
    'Should still be paused even after flipping the animation-play-state'
  );
}, 'Setting the startTime to null overrides animation-play-state if the'
   + ' animation is already running');
promise_test(async t => {
  const div = addDiv(t);
  div.style.animation = 'anim 100s paused';
  const animation = div.getAnimations()[0];
  animation.startTime = document.timeline.currentTime;
  assert_equals(
    animation.playState,
    'running',
    'Play state is running after setting the start time to non-null'
  );
  // Flip the animation-play-state back and forth to check it has no effect
  div.style.animationPlayState = 'running';
  getComputedStyle(div).animationPlayState;
  div.style.animationPlayState = 'paused';
  getComputedStyle(div).animationPlayState;
  assert_equals(
    animation.playState,
    'running',
    'Should still be running even after flipping the animation-play-state'
  );
}, 'Setting the startTime to non-null overrides animation-play-state if the'
   + ' animation is paused');
promise_test(async t => {
  const div = addDiv(t);
  div.style.animation = 'anim 100s';
  const animation = div.getAnimations()[0];
  animation.startTime = document.timeline.currentTime;
  div.style.animationPlayState = 'paused';
  getComputedStyle(div).animationPlayState;
  assert_equals(
    animation.playState,
    'paused',
    'Should be paused after changing the animation-play-state'
  );
}, 'Setting the startTime to non-null does NOT override the'
   + ' animation-play-state if the animation is already running');
promise_test(async t => {
  const div = addDiv(t, { style: 'animation: anim 1000s' });
  const animation = div.getAnimations()[0];
  let readyPromiseRun = false;
  await animation.ready;
  div.style.animationPlayState = 'paused';
  assert_true(animation.pending && animation.playState === 'paused',
              'Animation is pause-pending');
  // Set current time
  animation.currentTime = 5 * MS_PER_SEC;
  assert_equals(animation.playState, 'paused',
                'Animation is paused immediately after setting currentTime');
  assert_equals(animation.startTime, null,
                'Animation startTime is unresolved immediately after ' +
                'setting currentTime');
  assert_equals(animation.currentTime, 5 * MS_PER_SEC,
                'Animation currentTime does not change when forcing a ' +
                'pause operation to complete');
  // The ready promise should now be resolved. If it's not then test will
  // probably time out before anything else happens that causes it to resolve.
  await animation.ready;
}, 'Setting the current time completes a pending pause');
</script>