chromium/third_party/blink/web_tests/animations/direction-and-fill/fill-mode-missing-from-to-keyframes.html

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
   "http://www.w3.org/TR/html4/loose.dtd">
<title>Test missing keyframes with fill modes</title>
<style type="text/css" media="screen">
.box {
  position: relative;
  background:  blue;
  left: 100px;
  top: 10px;
  height: 30px;
  width: 200px;
  animation-duration: 0.1s;
  animation-play-state: paused;
}

@keyframes anim1 {
  from { left: 200px; }
  50% { left: 250px; }
  to   { left: 300px; }
}
@keyframes anim2 {
  50% { left: 250px; }
  to   { left: 300px; }
}
@keyframes anim3 {
  from { left: 200px; }
  50% { left: 250px; }
}
@keyframes anim4 {
  50% { left: 250px; }
}

.fill-none {
  animation-fill-mode:  none;
}

.fill-forwards {
  animation-fill-mode:  forwards;
}

.fill-backwards {
  animation-fill-mode:  backwards;
}

.fill-both {
  animation-fill-mode:  both;
}

.from-to {
  animation-name:  anim1;
}

.missing-from {
  animation-name:  anim2;
}

.missing-to {
  animation-name:  anim3;
}

.missing-from-to {
  animation-name:  anim4;
}
</style>
<body>
  <!-- Dynamically inject content here. -->
</body>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<script type="text/javascript" charset="utf-8">

  function createDiv(test, classList) {
    const el = document.createElement('div');
    document.body.appendChild(el);
    el.classList.add('box');
    classList.forEach(className => {
      el.classList.add(className);
    });
    test.add_cleanup(() => {
      el.remove();
    });
    return el;
  }

  // Validates the computed style when the animations is in the before and
  // after phases.
  function assert_before_and_after_styles(element, expected_before,
                                          expected_after) {
    const anim = element.getAnimations()[0];
    anim.currentTime = -1;
    assert_equals(getComputedStyle(element).left, expected_before,
                  `${element.classList}: unexpected value in the before phase`);
    anim.currentTime = 100;
    assert_equals(getComputedStyle(element).left, expected_after,
                  `${element.classList}: unexpected value in the after phase`);
  }

  test(t => {
    const fillNone = createDiv(t, ['fill-none', 'from-to']);
    const fillForwards = createDiv(t, ['fill-forwards', 'from-to']);
    const fillBackwards = createDiv(t, ['fill-backwards', 'from-to']);
    const fillBoth = createDiv(t, ['fill-both', 'from-to']);
    assert_before_and_after_styles(fillNone, '100px', '100px');
    assert_before_and_after_styles(fillForwards, '100px', '300px');
    assert_before_and_after_styles(fillBackwards, '200px', '100px');
    assert_before_and_after_styles(fillBoth, '200px', '300px');
  }, 'Values in before and after phase when both "from" and "to" are present');

  test(t => {
    const fillNone = createDiv(t, ['fill-none', 'missing-from']);
    const fillForwards = createDiv(t, ['fill-forwards', 'missing-from']);
    const fillBackwards = createDiv(t, ['fill-backwards', 'missing-from']);
    const fillBoth = createDiv(t, ['fill-both', 'missing-from']);
    assert_before_and_after_styles(fillNone, '100px', '100px');
    assert_before_and_after_styles(fillForwards, '100px', '300px');
    assert_before_and_after_styles(fillBackwards, '100px', '100px');
    assert_before_and_after_styles(fillBoth, '100px', '300px');
  }, 'Values in before and after phase when missing "from" keyframe');

  test(t => {
    const fillNone = createDiv(t, ['fill-none', 'missing-to']);
    const fillForwards = createDiv(t, ['fill-forwards', 'missing-to']);
    const fillBackwards = createDiv(t, ['fill-backwards', 'missing-to']);
    const fillBoth = createDiv(t, ['fill-both', 'missing-to']);
    assert_before_and_after_styles(fillNone, '100px', '100px');
    assert_before_and_after_styles(fillForwards, '100px', '100px');
    assert_before_and_after_styles(fillBackwards, '200px', '100px');
    assert_before_and_after_styles(fillBoth, '200px', '100px');
  }, 'Values in before and after phase when missing "to" keyframe');

  test(t => {
    const fillNone = createDiv(t, ['fill-none', 'missing-from-to']);
    const fillForwards = createDiv(t, ['fill-forwards', 'missing-from-to']);
    const fillBackwards = createDiv(t, ['fill-backwards', 'missing-from-to']);
    const fillBoth = createDiv(t, ['fill-both', 'missing-from-to']);
    assert_before_and_after_styles(fillNone, '100px', '100px');
    assert_before_and_after_styles(fillForwards, '100px', '100px');
    assert_before_and_after_styles(fillBackwards, '100px', '100px');
    assert_before_and_after_styles(fillBoth, '100px', '100px');
  }, 'Values in before and after phase when missing "from" and "to" keyframes');
</script>