gecko-dev/testing/web-platform/tests/css/css-animations/KeyframeEffect-getKeyframes.tentative.html
Emilio Cobos Álvarez dc03ea30c7 Bug 1532134 - Remove Options from TransformOperation. r=xidorn
This may or may not be part of the plan to get rid of nsCSSValue ;)

Option is not usable via FFI, and they should not be needed (we should be
following the shortest serialization principle instead). These patches also do
that, which matches the other transform properties. I think that slight change
is fine, if we can make it work, and consistent with other properties.

Alternative is adding more TransformOperation variants or such, which I rather
not do.

Differential Revision: https://phabricator.services.mozilla.com/D21862

--HG--
extra : moz-landing-system : lando
2019-03-03 11:31:54 +00:00

757 lines
25 KiB
HTML

<!doctype html>
<meta charset=utf-8>
<title>KeyframeEffect.getKeyframes() for CSS animations</title>
<!-- TODO: Add a more specific link for this once it is specified. -->
<link rel="help" href="https://drafts.csswg.org/css-animations-2/">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="support/testcommon.js"></script>
<style>
@keyframes anim-empty { }
@keyframes anim-empty-frames {
from { }
to { }
}
@keyframes anim-only-timing {
from { animation-timing-function: linear; }
to { }
}
@keyframes anim-only-non-animatable {
from { animation-duration: 3s; }
to { animation-duration: 5s; }
}
@keyframes anim-simple {
from { color: rgb(0, 0, 0); }
to { color: rgb(255, 255, 255); }
}
@keyframes anim-simple-three {
from { color: rgb(0, 0, 0); }
50% { color: rgb(0, 0, 255); }
to { color: rgb(255, 255, 255); }
}
@keyframes anim-simple-timing {
from { color: rgb(0, 0, 0); animation-timing-function: linear; }
50% { color: rgb(0, 0, 255); animation-timing-function: ease-in-out; }
to { color: rgb(255, 255, 255); animation-timing-function: step-end; }
}
@keyframes anim-simple-timing-some {
from { color: rgb(0, 0, 0); animation-timing-function: linear; }
50% { color: rgb(0, 0, 255); }
to { color: rgb(255, 255, 255); }
}
@keyframes anim-simple-shorthand {
from { margin: 8px; }
to { margin: 16px; }
}
@keyframes anim-omit-to {
from { color: rgb(0, 0, 255); }
}
@keyframes anim-omit-from {
to { color: rgb(0, 0, 255); }
}
@keyframes anim-omit-from-to {
50% { color: rgb(0, 0, 255); }
}
@keyframes anim-partially-omit-to {
from { margin-top: 50px;
margin-bottom: 100px; }
to { margin-top: 150px !important; /* ignored */
margin-bottom: 200px; }
}
@keyframes anim-different-props {
from { color: rgb(0, 0, 0); margin-top: 8px; }
25% { color: rgb(0, 0, 255); }
75% { margin-top: 12px; }
to { color: rgb(255, 255, 255); margin-top: 16px }
}
@keyframes anim-different-props-and-easing {
from { color: rgb(0, 0, 0); margin-top: 8px; animation-timing-function: linear; }
25% { color: rgb(0, 0, 255); animation-timing-function: step-end; }
75% { margin-top: 12px; animation-timing-function: ease-in; }
to { color: rgb(255, 255, 255); margin-top: 16px }
}
@keyframes anim-merge-offset {
from { color: rgb(0, 0, 0); }
to { color: rgb(255, 255, 255); }
from { margin-top: 8px; }
to { margin-top: 16px; }
}
@keyframes anim-merge-offset-and-easing {
from { color: rgb(0, 0, 0); animation-timing-function: step-end; }
to { color: rgb(255, 255, 255); }
from { margin-top: 8px; animation-timing-function: linear; }
to { margin-top: 16px; }
from { font-size: 16px; animation-timing-function: step-end; }
to { font-size: 32px; }
from { padding-left: 2px; animation-timing-function: linear; }
to { padding-left: 4px; }
}
@keyframes anim-no-merge-equiv-easing {
from { margin-top: 0px; animation-timing-function: steps(1, end); }
from { margin-right: 0px; animation-timing-function: step-end; }
from { margin-bottom: 0px; animation-timing-function: steps(1); }
50% { margin-top: 10px; animation-timing-function: step-end; }
50% { margin-right: 10px; animation-timing-function: step-end; }
50% { margin-bottom: 10px; animation-timing-function: step-end; }
to { margin-top: 20px; margin-right: 20px; margin-bottom: 20px; }
}
@keyframes anim-overriding {
from { padding-top: 50px }
50%, from { padding-top: 30px } /* wins: 0% */
75%, 85%, 50% { padding-top: 20px } /* wins: 75%, 50% */
100%, 85% { padding-top: 70px } /* wins: 100% */
85.1% { padding-top: 60px } /* wins: 85.1% */
85% { padding-top: 30px } /* wins: 85% */
}
@keyframes anim-filter {
to { filter: blur(5px) sepia(60%) saturate(30%); }
}
@keyframes anim-filter-drop-shadow {
from { filter: drop-shadow(10px 10px 10px rgb(0, 255, 0)); }
to { filter: drop-shadow(50px 30px 10px rgb(255, 0, 0)); }
}
@keyframes anim-text-shadow {
to { text-shadow: none; }
}
@keyframes anim-background-size {
to { background-size: 50%, 6px, contain }
}
:root {
--var-100px: 100px;
--end-color: rgb(255, 0, 0);
}
@keyframes anim-variables {
to { transform: translate(var(--var-100px), 0) }
}
@keyframes anim-variables-shorthand {
to { margin: var(--var-100px) }
}
@keyframes anim-custom-property-in-keyframe {
to { --end-color: rgb(0, 255, 0); color: var(--end-color) }
}
@keyframes anim-only-custom-property-in-keyframe {
from { transform: translate(100px, 0) }
to { --not-used: 200px }
}
</style>
<body>
<div id="log"></div>
<script>
"use strict";
const getKeyframes = elem => elem.getAnimations()[0].effect.getKeyframes();
const assert_frames_equal = (a, b, name) => {
assert_equals(Object.keys(a).sort().toString(),
Object.keys(b).sort().toString(),
"properties on " + name);
for (const p in a) {
if (p === 'offset' || p === 'computedOffset') {
assert_approx_equals(a[p], b[p], 0.00001,
"value for '" + p + "' on " + name);
} else {
assert_equals(a[p], b[p], "value for '" + p + "' on " + name);
}
}
};
// animation-timing-function values to test with, where the value
// is exactly the same as its serialization, sorted by the order
// getKeyframes() will group frames with the same easing function
// together (by nsTimingFunction::Compare).
const kTimingFunctionValues = [
"ease",
"linear",
"ease-in",
"ease-out",
"ease-in-out",
"steps(1, start)",
"steps(2, start)",
"steps(1)",
"steps(2)",
"cubic-bezier(0, 0, 1, 1)",
"cubic-bezier(0, 0.25, 0.75, 1)"
];
test(t => {
const div = addDiv(t);
div.style.animation = 'anim-empty 100s';
assert_equals(getKeyframes(div).length, 0,
"number of frames with empty @keyframes");
div.style.animation = 'anim-empty-frames 100s';
assert_equals(getKeyframes(div).length, 0,
"number of frames when @keyframes has empty keyframes");
div.style.animation = 'anim-only-timing 100s';
assert_equals(getKeyframes(div).length, 0,
"number of frames when @keyframes only has keyframes with " +
"animation-timing-function");
div.style.animation = 'anim-only-non-animatable 100s';
assert_equals(getKeyframes(div).length, 0,
"number of frames when @keyframes only has frames with " +
"non-animatable properties");
}, 'KeyframeEffect.getKeyframes() returns no frames for various kinds'
+ ' of empty enimations');
test(t => {
const div = addDiv(t);
div.style.animation = 'anim-simple 100s';
const frames = getKeyframes(div);
assert_equals(frames.length, 2, "number of frames");
const expected = [
{ offset: 0, computedOffset: 0, easing: "ease",
color: "rgb(0, 0, 0)", composite: "auto" },
{ offset: 1, computedOffset: 1, easing: "ease",
color: "rgb(255, 255, 255)", composite: "auto" },
];
for (let i = 0; i < frames.length; i++) {
assert_frames_equal(frames[i], expected[i], "ComputedKeyframe #" + i);
}
}, 'KeyframeEffect.getKeyframes() returns expected frames for a simple'
+ ' animation');
test(t => {
for (const easing of kTimingFunctionValues) {
const div = addDiv(t);
div.style.animation = 'anim-simple-three 100s ' + easing;
const frames = getKeyframes(div);
assert_equals(frames.length, 3, "number of frames");
for (let i = 0; i < frames.length; i++) {
assert_equals(frames[i].easing, easing,
"value for 'easing' on ComputedKeyframe #" + i);
}
}
}, 'KeyframeEffect.getKeyframes() returns frames with expected easing'
+ ' values, when the easing comes from animation-timing-function on the'
+ ' element');
test(t => {
const div = addDiv(t);
div.style.animation = 'anim-simple-timing 100s';
const frames = getKeyframes(div);
assert_equals(frames.length, 3, "number of frames");
assert_equals(frames[0].easing, "linear",
"value of 'easing' on ComputedKeyframe #0");
assert_equals(frames[1].easing, "ease-in-out",
"value of 'easing' on ComputedKeyframe #1");
assert_equals(frames[2].easing, "steps(1)",
"value of 'easing' on ComputedKeyframe #2");
}, 'KeyframeEffect.getKeyframes() returns frames with expected easing'
+ ' values, when the easing is specified on each keyframe');
test(t => {
const div = addDiv(t);
div.style.animation = 'anim-simple-timing-some 100s step-start';
const frames = getKeyframes(div);
assert_equals(frames.length, 3, "number of frames");
assert_equals(frames[0].easing, "linear",
"value of 'easing' on ComputedKeyframe #0");
assert_equals(frames[1].easing, "steps(1, start)",
"value of 'easing' on ComputedKeyframe #1");
assert_equals(frames[2].easing, "steps(1, start)",
"value of 'easing' on ComputedKeyframe #2");
}, 'KeyframeEffect.getKeyframes() returns frames with expected easing'
+ ' values, when the easing is specified on some keyframes');
test(t => {
const div = addDiv(t);
div.style.animation = 'anim-simple-shorthand 100s';
const frames = getKeyframes(div);
assert_equals(frames.length, 2, "number of frames");
const expected = [
{ offset: 0, computedOffset: 0, easing: "ease", composite: "auto",
marginBottom: "8px", marginLeft: "8px",
marginRight: "8px", marginTop: "8px" },
{ offset: 1, computedOffset: 1, easing: "ease", composite: "auto",
marginBottom: "16px", marginLeft: "16px",
marginRight: "16px", marginTop: "16px" },
];
for (let i = 0; i < frames.length; i++) {
assert_frames_equal(frames[i], expected[i], "ComputedKeyframe #" + i);
}
}, 'KeyframeEffect.getKeyframes() returns expected frames for a simple'
+ ' animation that specifies a single shorthand property');
test(t => {
const div = addDiv(t);
div.style.animation = 'anim-omit-to 100s';
div.style.color = 'rgb(255, 255, 255)';
const frames = getKeyframes(div);
assert_equals(frames.length, 2, "number of frames");
const expected = [
{ offset: 0, computedOffset: 0, easing: "ease", composite: "auto",
color: "rgb(0, 0, 255)" },
{ offset: 1, computedOffset: 1, easing: "ease", composite: "auto",
color: "rgb(255, 255, 255)" },
];
for (let i = 0; i < frames.length; i++) {
assert_frames_equal(frames[i], expected[i], "ComputedKeyframe #" + i);
}
}, 'KeyframeEffect.getKeyframes() returns expected frames for an ' +
'animation with a 0% keyframe and no 100% keyframe');
test(t => {
const div = addDiv(t);
div.style.animation = 'anim-omit-from 100s';
div.style.color = 'rgb(255, 255, 255)';
const frames = getKeyframes(div);
assert_equals(frames.length, 2, "number of frames");
const expected = [
{ offset: 0, computedOffset: 0, easing: "ease", composite: "auto",
color: "rgb(255, 255, 255)" },
{ offset: 1, computedOffset: 1, easing: "ease", composite: "auto",
color: "rgb(0, 0, 255)" },
];
for (let i = 0; i < frames.length; i++) {
assert_frames_equal(frames[i], expected[i], "ComputedKeyframe #" + i);
}
}, 'KeyframeEffect.getKeyframes() returns expected frames for an ' +
'animation with a 100% keyframe and no 0% keyframe');
test(t => {
const div = addDiv(t);
div.style.animation = 'anim-omit-from-to 100s';
div.style.color = 'rgb(255, 255, 255)';
const frames = getKeyframes(div);
assert_equals(frames.length, 3, "number of frames");
const expected = [
{ offset: 0, computedOffset: 0, easing: "ease", composite: "auto",
color: "rgb(255, 255, 255)" },
{ offset: 0.5, computedOffset: 0.5, easing: "ease", composite: "auto",
color: "rgb(0, 0, 255)" },
{ offset: 1, computedOffset: 1, easing: "ease", composite: "auto",
color: "rgb(255, 255, 255)" },
];
for (let i = 0; i < frames.length; i++) {
assert_frames_equal(frames[i], expected[i], "ComputedKeyframe #" + i);
}
}, 'KeyframeEffect.getKeyframes() returns expected frames for an ' +
'animation with no 0% or 100% keyframe but with a 50% keyframe');
test(t => {
const div = addDiv(t);
div.style.animation = 'anim-partially-omit-to 100s';
div.style.marginTop = '250px';
const frames = getKeyframes(div);
assert_equals(frames.length, 2, "number of frames");
const expected = [
{ offset: 0, computedOffset: 0, easing: "ease", composite: "auto",
marginTop: '50px', marginBottom: '100px' },
{ offset: 1, computedOffset: 1, easing: "ease", composite: "auto",
marginTop: '250px', marginBottom: '200px' },
];
for (let i = 0; i < frames.length; i++) {
assert_frames_equal(frames[i], expected[i], "ComputedKeyframe #" + i);
}
}, 'KeyframeEffect.getKeyframes() returns expected frames for an ' +
'animation with a partially complete 100% keyframe (because the ' +
'!important rule is ignored)');
test(t => {
const div = addDiv(t);
div.style.animation = 'anim-different-props 100s';
const frames = getKeyframes(div);
assert_equals(frames.length, 4, "number of frames");
const expected = [
{ offset: 0, computedOffset: 0, easing: "ease", composite: "auto",
color: "rgb(0, 0, 0)", marginTop: "8px" },
{ offset: 0.25, computedOffset: 0.25, easing: "ease", composite: "auto",
color: "rgb(0, 0, 255)" },
{ offset: 0.75, computedOffset: 0.75, easing: "ease", composite: "auto",
marginTop: "12px" },
{ offset: 1, computedOffset: 1, easing: "ease", composite: "auto",
color: "rgb(255, 255, 255)", marginTop: "16px" },
];
for (let i = 0; i < frames.length; i++) {
assert_frames_equal(frames[i], expected[i], "ComputedKeyframe #" + i);
}
}, 'KeyframeEffect.getKeyframes() returns expected frames for an ' +
'animation with different properties on different keyframes, all ' +
'with the same easing function');
test(t => {
const div = addDiv(t);
div.style.animation = 'anim-different-props-and-easing 100s';
const frames = getKeyframes(div);
assert_equals(frames.length, 4, "number of frames");
const expected = [
{ offset: 0, computedOffset: 0, easing: "linear", composite: "auto",
color: "rgb(0, 0, 0)", marginTop: "8px" },
{ offset: 0.25, computedOffset: 0.25, easing: "steps(1)", composite: "auto",
color: "rgb(0, 0, 255)" },
{ offset: 0.75, computedOffset: 0.75, easing: "ease-in", composite: "auto",
marginTop: "12px" },
{ offset: 1, computedOffset: 1, easing: "ease", composite: "auto",
color: "rgb(255, 255, 255)", marginTop: "16px" },
];
for (let i = 0; i < frames.length; i++) {
assert_frames_equal(frames[i], expected[i], "ComputedKeyframe #" + i);
}
}, 'KeyframeEffect.getKeyframes() returns expected frames for an ' +
'animation with different properties on different keyframes, with ' +
'a different easing function on each');
test(t => {
const div = addDiv(t);
div.style.animation = 'anim-merge-offset 100s';
const frames = getKeyframes(div);
assert_equals(frames.length, 2, "number of frames");
const expected = [
{ offset: 0, computedOffset: 0, easing: "ease", composite: "auto",
color: "rgb(0, 0, 0)", marginTop: "8px" },
{ offset: 1, computedOffset: 1, easing: "ease", composite: "auto",
color: "rgb(255, 255, 255)", marginTop: "16px" },
];
for (let i = 0; i < frames.length; i++) {
assert_frames_equal(frames[i], expected[i], "ComputedKeyframe #" + i);
}
}, 'KeyframeEffect.getKeyframes() returns expected frames for an ' +
'animation with multiple keyframes for the same time, and all with ' +
'the same easing function');
test(t => {
const div = addDiv(t);
div.style.animation = 'anim-merge-offset-and-easing 100s';
const frames = getKeyframes(div);
assert_equals(frames.length, 3, "number of frames");
const expected = [
{ offset: 0, computedOffset: 0, easing: "steps(1)", composite: "auto",
color: "rgb(0, 0, 0)", fontSize: "16px" },
{ offset: 0, computedOffset: 0, easing: "linear", composite: "auto",
marginTop: "8px", paddingLeft: "2px" },
{ offset: 1, computedOffset: 1, easing: "ease", composite: "auto",
color: "rgb(255, 255, 255)", fontSize: "32px", marginTop: "16px",
paddingLeft: "4px" },
];
for (let i = 0; i < frames.length; i++) {
assert_frames_equal(frames[i], expected[i], "ComputedKeyframe #" + i);
}
}, 'KeyframeEffect.getKeyframes() returns expected frames for an ' +
'animation with multiple keyframes for the same time and with ' +
'different easing functions');
test(t => {
const div = addDiv(t);
div.style.animation = 'anim-no-merge-equiv-easing 100s';
const frames = getKeyframes(div);
assert_equals(frames.length, 3, "number of frames");
const expected = [
{ offset: 0, computedOffset: 0, easing: "steps(1)", composite: "auto",
marginTop: "0px", marginRight: "0px", marginBottom: "0px" },
{ offset: 0.5, computedOffset: 0.5, easing: "steps(1)", composite: "auto",
marginTop: "10px", marginRight: "10px", marginBottom: "10px" },
{ offset: 1, computedOffset: 1, easing: "ease", composite: "auto",
marginTop: "20px", marginRight: "20px", marginBottom: "20px" },
];
for (let i = 0; i < frames.length; i++) {
assert_frames_equal(frames[i], expected[i], "ComputedKeyframe #" + i);
}
}, 'KeyframeEffect.getKeyframes() returns expected frames for an ' +
'animation with multiple keyframes for the same time and with ' +
'different but equivalent easing functions');
test(t => {
const div = addDiv(t);
div.style.animation = 'anim-overriding 100s';
const frames = getKeyframes(div);
assert_equals(frames.length, 6, "number of frames");
const expected = [
{ offset: 0, computedOffset: 0, easing: "ease", composite: "auto",
paddingTop: "30px" },
{ offset: 0.5, computedOffset: 0.5, easing: "ease", composite: "auto",
paddingTop: "20px" },
{ offset: 0.75, computedOffset: 0.75, easing: "ease", composite: "auto",
paddingTop: "20px" },
{ offset: 0.85, computedOffset: 0.85, easing: "ease", composite: "auto",
paddingTop: "30px" },
{ offset: 0.851, computedOffset: 0.851, easing: "ease", composite: "auto",
paddingTop: "60px" },
{ offset: 1, computedOffset: 1, easing: "ease", composite: "auto",
paddingTop: "70px" },
];
for (let i = 0; i < frames.length; i++) {
assert_frames_equal(frames[i], expected[i], "ComputedKeyframe #" + i);
}
}, 'KeyframeEffect.getKeyframes() returns expected frames for ' +
'overlapping keyframes');
// Gecko-specific test case: We are specifically concerned here that the
// computed value for filter, "none", is correctly represented.
test(t => {
const div = addDiv(t);
div.style.animation = 'anim-filter 100s';
const frames = getKeyframes(div);
assert_equals(frames.length, 2, "number of frames");
const expected = [
{ offset: 0, computedOffset: 0, easing: "ease", composite: "auto",
filter: "none" },
{ offset: 1, computedOffset: 1, easing: "ease", composite: "auto",
filter: "blur(5px) sepia(60%) saturate(30%)" },
];
for (let i = 0; i < frames.length; i++) {
assert_frames_equal(frames[i], expected[i], "ComputedKeyframe #" + i);
}
}, 'KeyframeEffect.getKeyframes() returns expected values for ' +
'animations with filter properties and missing keyframes');
test(t => {
const div = addDiv(t);
div.style.animation = 'anim-filter-drop-shadow 100s';
const frames = getKeyframes(div);
assert_equals(frames.length, 2, "number of frames");
const expected = [
{ offset: 0, computedOffset: 0, easing: "ease", composite: "auto",
filter: "drop-shadow(rgb(0, 255, 0) 10px 10px 10px)" },
{ offset: 1, computedOffset: 1, easing: "ease", composite: "auto",
filter: "drop-shadow(rgb(255, 0, 0) 50px 30px 10px)" },
];
for (let i = 0; i < frames.length; i++) {
assert_frames_equal(frames[i], expected[i], "ComputedKeyframe #" + i);
}
}, 'KeyframeEffect.getKeyframes() returns expected values for ' +
'animation with drop-shadow of filter property');
// Gecko-specific test case: We are specifically concerned here that the
// computed value for text-shadow and a "none" specified on a keyframe
// are correctly represented.
test(t => {
const div = addDiv(t);
div.style.textShadow = '1px 1px 2px rgb(0, 0, 0), ' +
'0 0 16px rgb(0, 0, 255), ' +
'0 0 3.2px rgb(0, 0, 255)';
div.style.animation = 'anim-text-shadow 100s';
const frames = getKeyframes(div);
assert_equals(frames.length, 2, "number of frames");
const expected = [
{ offset: 0, computedOffset: 0, easing: "ease", composite: "auto",
textShadow: "rgb(0, 0, 0) 1px 1px 2px,"
+ " rgb(0, 0, 255) 0px 0px 16px,"
+ " rgb(0, 0, 255) 0px 0px 3.2px" },
{ offset: 1, computedOffset: 1, easing: "ease", composite: "auto",
textShadow: "none" },
];
for (let i = 0; i < frames.length; i++) {
assert_frames_equal(frames[i], expected[i], "ComputedKeyframe #" + i);
}
}, 'KeyframeEffect.getKeyframes() returns expected values for ' +
'animations with text-shadow properties and missing keyframes');
// Gecko-specific test case: We are specifically concerned here that the
// initial value for background-size and the specified list are correctly
// represented.
test(t => {
const div = addDiv(t);
div.style.animation = 'anim-background-size 100s';
let frames = getKeyframes(div);
assert_equals(frames.length, 2, "number of frames");
const expected = [
{ offset: 0, computedOffset: 0, easing: "ease", composite: "auto",
backgroundSize: "auto" },
{ offset: 1, computedOffset: 1, easing: "ease", composite: "auto",
backgroundSize: "50% auto, 6px auto, contain" },
];
for (let i = 0; i < frames.length; i++) {
assert_frames_equal(frames[i], expected[i], "ComputedKeyframe #" + i);
}
// Test inheriting a background-size value
expected[0].backgroundSize = div.style.backgroundSize =
"30px auto, 40% auto, auto";
frames = getKeyframes(div);
for (let i = 0; i < frames.length; i++) {
assert_frames_equal(frames[i], expected[i], "ComputedKeyframe #" + i
+ " after updating current style");
}
}, 'KeyframeEffect.getKeyframes() returns expected values for ' +
'animations with background-size properties and missing keyframes');
test(t => {
const div = addDiv(t);
div.style.animation = 'anim-variables 100s';
const frames = getKeyframes(div);
assert_equals(frames.length, 2, "number of frames");
const expected = [
{ offset: 0, computedOffset: 0, easing: "ease", composite: "auto",
transform: "none" },
{ offset: 1, computedOffset: 1, easing: "ease", composite: "auto",
transform: "translate(100px)" },
];
for (let i = 0; i < frames.length; i++) {
assert_frames_equal(frames[i], expected[i], "ComputedKeyframe #" + i);
}
}, 'KeyframeEffect.getKeyframes() returns expected values for ' +
'animations with CSS variables as keyframe values');
test(t => {
const div = addDiv(t);
div.style.animation = 'anim-variables-shorthand 100s';
const frames = getKeyframes(div);
assert_equals(frames.length, 2, "number of frames");
const expected = [
{ offset: 0, computedOffset: 0, easing: "ease", composite: "auto",
marginBottom: "0px",
marginLeft: "0px",
marginRight: "0px",
marginTop: "0px" },
{ offset: 1, computedOffset: 1, easing: "ease", composite: "auto",
marginBottom: "100px",
marginLeft: "100px",
marginRight: "100px",
marginTop: "100px" },
];
for (let i = 0; i < frames.length; i++) {
assert_frames_equal(frames[i], expected[i], "ComputedKeyframe #" + i);
}
}, 'KeyframeEffect.getKeyframes() returns expected values for ' +
'animations with CSS variables as keyframe values in a shorthand property');
test(t => {
const div = addDiv(t);
div.style.animation = 'anim-custom-property-in-keyframe 100s';
const frames = getKeyframes(div);
assert_equals(frames.length, 2, "number of frames");
const expected = [
{ offset: 0, computedOffset: 0, easing: "ease", composite: "auto",
color: "rgb(0, 0, 0)" },
{ offset: 1, computedOffset: 1, easing: "ease", composite: "auto",
color: "rgb(0, 255, 0)" },
];
for (let i = 0; i < frames.length; i++) {
assert_frames_equal(frames[i], expected[i], "ComputedKeyframe #" + i);
}
}, 'KeyframeEffect.getKeyframes() returns expected values for ' +
'animations with a CSS variable which is overriden by the value in keyframe');
test(t => {
const div = addDiv(t);
div.style.animation = 'anim-only-custom-property-in-keyframe 100s';
const frames = getKeyframes(div);
assert_equals(frames.length, 2, "number of frames");
const expected = [
{ offset: 0, computedOffset: 0, easing: "ease", composite: "auto",
transform: "translate(100px)" },
{ offset: 1, computedOffset: 1, easing: "ease", composite: "auto",
transform: "none" },
];
for (let i = 0; i < frames.length; i++) {
assert_frames_equal(frames[i], expected[i], "ComputedKeyframe #" + i);
}
}, 'KeyframeEffect.getKeyframes() returns expected values for ' +
'animations with only custom property in a keyframe');
</script>
</body>