chromium/third_party/blink/web_tests/animations/events/animation-iteration-event.html

<!DOCTYPE html>
<title>Tests that correct number of iteration events is fired.</title>
<style>
  #box {
    position: relative;
    left: 100px;
    top: 10px;
    height: 100px;
    width: 100px;
    background-color: #999;
  }

  .animated {
    animation-duration: 1s;
    animation-name: anim;
    animation-iteration-count: 2;
    animation-play-state: paused;
  }

  @keyframes anim {
    from { left: 200px; }
    to   { left: 300px; }
  }
</style>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<script src="../../animations/web-animations/resources/testcommon.js"></script>

<script>
function startTest() {
  let iteration_count = 0;
  document.addEventListener('animationiteration', () => { iteration_count++; });

  promise_test(async t => {
    const duration = 1000;
    const animation = document.getAnimations()[0];

    await animation.ready;
    assert_equals(iteration_count, 0, 'After animation.ready should be 0');

    animation.currentTime = duration - 1;
    await waitForAnimationFrames(2);
    assert_equals(iteration_count, 0, 'Just before the end of first iteration should be 0');

    animation.currentTime = duration + 1;
    await waitForAnimationFrames(2);
    assert_equals(iteration_count, 1, 'Just after the end of first iteration should be 1');

    animation.currentTime = 2 * duration - 1;
    await waitForAnimationFrames(2);
    assert_equals(iteration_count, 1, 'Just before the end of second iteration should be 1');

    animation.currentTime = 2 * duration + 1;
    await waitForAnimationFrames(2);
    assert_equals(iteration_count, 1, 'After animation finishes should still be 1');
  });
}
</script>

<body onload="startTest()">
<div id=box class="animated"></div>
</body>