summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/css/css-transitions/animations
diff options
context:
space:
mode:
Diffstat (limited to 'testing/web-platform/tests/css/css-transitions/animations')
-rw-r--r--testing/web-platform/tests/css/css-transitions/animations/animate-with-color-mix.html146
-rw-r--r--testing/web-platform/tests/css/css-transitions/animations/change-duration-during-transition.html61
-rw-r--r--testing/web-platform/tests/css/css-transitions/animations/color-transition-premultiplied.html69
-rw-r--r--testing/web-platform/tests/css/css-transitions/animations/move-after-transition.html62
-rw-r--r--testing/web-platform/tests/css/css-transitions/animations/text-shadow-composition.html101
-rw-r--r--testing/web-platform/tests/css/css-transitions/animations/text-shadow-interpolation.html123
-rw-r--r--testing/web-platform/tests/css/css-transitions/animations/transition-end-event-shorthands.html65
-rw-r--r--testing/web-platform/tests/css/css-transitions/animations/transition-timing-function.html87
-rw-r--r--testing/web-platform/tests/css/css-transitions/animations/vertical-align-composition.html65
-rw-r--r--testing/web-platform/tests/css/css-transitions/animations/vertical-align-interpolation.html98
-rw-r--r--testing/web-platform/tests/css/css-transitions/animations/z-index-interpolation.html130
11 files changed, 1007 insertions, 0 deletions
diff --git a/testing/web-platform/tests/css/css-transitions/animations/animate-with-color-mix.html b/testing/web-platform/tests/css/css-transitions/animations/animate-with-color-mix.html
new file mode 100644
index 0000000000..3e630a7a2b
--- /dev/null
+++ b/testing/web-platform/tests/css/css-transitions/animations/animate-with-color-mix.html
@@ -0,0 +1,146 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <link rel="help" href="https://www.w3.org/TR/css-color-4/#interpolation">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <title>CSS transitions with color-mix</title>
+</head>
+<style>
+ #target-1, #target-2, #target-3, #target-4, #target-5, #target-6 {
+ color: black;
+ height: 100px;
+ width: 100px;
+ display: inline-block;
+ transition: background-color 1s linear;
+ }
+ #target-1,
+ #target-2.update-2,
+ #target-3,
+ #target-4.update-4 {
+ background-color: color-mix(in srgb, white 50%,
+ currentcolor);
+ }
+ #target-1.update-1,
+ #target-2 {
+ background-color: rgb(0, 255, 0);
+ }
+
+ #target-3.update-3,
+ #target-4 {
+ background-color: color(srgb 0.0 1.0 0.0);
+ }
+
+ #target-5, #target-6.update-6 {
+ background-color: color-mix(in srgb, transparent 50%,
+ currentcolor);
+ }
+
+ #target-6, #target-5.update-5 {
+ background-color: rgba(255, 255, 255, 0.75);
+ }
+
+</style>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/web-animations/testcommon.js"></script>
+<script src="/css/support/color-testcommon.js"></script>
+<body>
+ <div id="target-1"></div>
+ <div id="target-2"></div>
+ <div id="target-3"></div>
+ <div id="target-4"></div>
+ <div id="target-5"></div>
+ <div id="target-6"></div>
+</body>
+<script>
+ 'use strict';
+
+ async function runAnimationTest(t, elementId, update,
+ expected_colors) {
+ const elem = document.getElementById(elementId);
+ t.add_cleanup(() => {
+ elem.classList.remove(update);
+ });
+ await waitForNextFrame();
+ await waitForNextFrame();
+ elem.classList.add(update);
+ const anim = elem.getAnimations()[0];
+ await anim.ready;
+ // Keep the animation in effect when it reaches the end.
+ anim.effect.updateTiming({ fill: 'forwards' });
+ expected_colors.forEach(data => {
+ anim.currentTime = 1000 * data.at;
+ const actual = getComputedStyle(elem).backgroundColor;
+ const expected = data.value;
+ assert_oklab_color(
+ actual, expected,
+ `Background color at ${100*data.at}% animation progress`);
+ });
+ }
+
+ const gray_to_green = [
+ { at: 0, value: 'oklab(0.5981 0.0000 0.0000)' },
+ { at: 0.25, value: 'oklab(0.6652 -0.0584 0.0449)' },
+ { at: 0.5, value: 'oklab(0.7323 -0.1169 0.0898)' },
+ { at: 0.75, value: 'oklab(0.7994 -0.1754 0.1346)' },
+ { at: 1, value: 'oklab(0.8664 -0.2338 0.1795)' }
+ ];
+
+ const green_to_gray = [
+ { at: 0, value: 'oklab(0.8664 -0.2338 0.1795)' },
+ { at: 0.25, value: 'oklab(0.7994 -0.1754 0.1346)' },
+ { at: 0.5, value: 'oklab(0.7323 -0.1169 0.0898)' },
+ { at: 0.75, value: 'oklab(0.6652 -0.0584 0.0449)' },
+ { at: 1, value: 'oklab(0.5981 0.0000 0.0000)' }
+ ];
+
+ const translucent_black_to_white = [
+ { at: 0, value: 'oklab(0 0 0 / 0.5)' },
+ { at: 0.25, value: 'oklab(0.3330 0 0 / 0.5623)' },
+ { at: 0.5, value: 'oklab(0.5997 0 0 / 0.6245)' },
+ { at: 0.75, value: 'oklab(0.8180 0 0 / 0.6868)' },
+ { at: 1, value: 'oklab(1 0 0 / 0.75)' }
+ ];
+
+ const translucent_white_to_black = [
+ { at: 0, value: 'oklab(1 0 0 / 0.75)' },
+ { at: 0.25, value: 'oklab(0.8180 0 0. / 0.6868)' },
+ { at: 0.5, value: 'oklab(0.5997 0 0 / 0.6245)' },
+ { at: 0.75, value: 'oklab(0.3330 0 0 / 0.5623)' },
+ { at: 1, value: 'oklab(0 0 0 / 0.5)' }
+ ];
+
+ window.onload = async () => {
+ promise_test(t => {
+ return runAnimationTest(t, 'target-1', 'update-1',
+ gray_to_green);
+ }, 'Transition from color-mix to legacy rgb');
+
+ promise_test(t => {
+ return runAnimationTest(t, 'target-2', 'update-2',
+ green_to_gray);
+ }, 'Transition from legacy rgb to color-mix');
+
+ promise_test(t => {
+ return runAnimationTest(t, 'target-3', 'update-3',
+ gray_to_green);
+ }, 'Transition from color-mix to srgb');
+
+ promise_test(t => {
+ return runAnimationTest(t, 'target-4', 'update-4',
+ green_to_gray);
+ }, 'Transition from srgb to color-mix');
+
+ promise_test(t => {
+ return runAnimationTest(t, 'target-5', 'update-5',
+ translucent_black_to_white);
+ }, 'Transition from color-mix with transparency to legacy rgba');
+
+ promise_test(t => {
+ return runAnimationTest(t, 'target-6', 'update-6',
+ translucent_white_to_black);
+ }, 'Transition from legacy rgba to color-mix with transparency');
+ };
+</script>
+</html>
diff --git a/testing/web-platform/tests/css/css-transitions/animations/change-duration-during-transition.html b/testing/web-platform/tests/css/css-transitions/animations/change-duration-during-transition.html
new file mode 100644
index 0000000000..cf03f2e120
--- /dev/null
+++ b/testing/web-platform/tests/css/css-transitions/animations/change-duration-during-transition.html
@@ -0,0 +1,61 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>transition duration change</title>
+ <link rel="help" href="https://drafts.csswg.org/css-transitions-1/#starting">
+ <style>
+ #box {
+ position: absolute;
+ height: 100px;
+ width: 100px;
+ left: 0px;
+ background-color: blue;
+ transition-duration: 1s;
+ transition-delay: -0.75s;
+ transition-timing-function: linear;
+ transition-property: left;
+ }
+ </style>
+</head>
+<body>
+ <div id="box"></div>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/css/css-transitions/support/helper.js"></script>
+ <script>
+ 'use strict';
+
+ window.onload = () => {
+ promise_test(async t => {
+ // Make sure we have rendered the page before making the style change
+ // to ensure we get transitions.
+ await waitForAnimationFrames(2);
+
+ box.style.left = '400px';
+ assert_equals(
+ getComputedStyle(box).left, '300px',
+ 'The transition progresses 75% immediately due to negative ' +
+ 'transition-delay');
+
+ box.style.transitionDuration = '7.5s';
+ assert_equals(
+ getComputedStyle(box).left, '300px',
+ 'Changing the duration does not affect the current transition');
+
+ const anim = document.getAnimations()[0];
+ anim.finish();
+
+ assert_equals(
+ getComputedStyle(box).left, '400px',
+ 'The final value has been reached when finished');
+ box.style.left = '1400px';
+ assert_equals(
+ getComputedStyle(box).left, '500px',
+ 'With the new duration taking effect, the transition progresses ' +
+ '10% immediately');
+ }, 'Transition duration change should not affect transition in progress');
+ };
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-transitions/animations/color-transition-premultiplied.html b/testing/web-platform/tests/css/css-transitions/animations/color-transition-premultiplied.html
new file mode 100644
index 0000000000..745e6c0c73
--- /dev/null
+++ b/testing/web-platform/tests/css/css-transitions/animations/color-transition-premultiplied.html
@@ -0,0 +1,69 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>transition from transparent background</title>
+ <link rel="help" href="https://www.w3.org/TR/css-color-4/#interpolation-alpha">
+ <style>
+ .box {
+ width: 100px;
+ height: 100px;
+ margin: 10px;
+ border: 1px solid black;
+ transition: background-color 1s linear;
+ }
+
+ #one {
+ background-color: transparent;
+ }
+
+ #one.changed {
+ background-color: green;
+ }
+
+ #two {
+ background-color: rgba(0, 255, 0, 0);
+ }
+
+ #two.changed {
+ background-color: rgba(0, 0, 255, 1);
+ }
+ </style>
+</head>
+<body>
+ <div class="box" id="one"></div>
+ <div class="box" id="two"></div>
+</body>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/css-transitions/support/helper.js"></script>
+<script type="text/javascript">
+
+promise_test(async t => {
+ // Make sure we have rendered the page before making the style change
+ // to ensure we get transitions.
+ await waitForAnimationFrames(2);
+ promises = [];
+
+ const elem1 = document.getElementById('one');
+ const elem2 = document.getElementById('two');
+ elem1.classList.add('changed');
+ elem2.classList.add('changed');
+
+ document.getAnimations().forEach(anim => {
+ anim.pause();
+ anim.currentTime = 500;
+ promises.push(anim.ready);
+ });
+
+ Promise.all(promises).then(() => {
+ assert_equals(promises.length, 2, 'Unexpected animation count');
+ assert_equals(getComputedStyle(elem1).backgroundColor,
+ 'rgba(0, 128, 0, 0.5)');
+ assert_equals(getComputedStyle(elem2).backgroundColor,
+ 'rgba(0, 0, 255, 0.5)');
+ });
+}, 'Transition from transparent background');
+
+</script>
+</html>
diff --git a/testing/web-platform/tests/css/css-transitions/animations/move-after-transition.html b/testing/web-platform/tests/css/css-transitions/animations/move-after-transition.html
new file mode 100644
index 0000000000..28180452f7
--- /dev/null
+++ b/testing/web-platform/tests/css/css-transitions/animations/move-after-transition.html
@@ -0,0 +1,62 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="UTF-8">
+ <title>move after transition</title>
+ <link rel="help" href="https://drafts.csswg.org/css-transitions/#transition-property-property">
+ <style>
+ #container {
+ position: relative;
+ width: 400px;
+ height: 100px;
+ border: 1px solid black;
+ }
+ #box {
+ position: absolute;
+ width: 100px;
+ height: 100px;
+ background-color: green;
+ transform-style: preserve-3d;
+ transition: transform 300ms linear;
+ transform: translateX(0);
+ }
+ #container.moved #box {
+ transform: translateX(300px);
+ }
+ </style>
+</head>
+<body>
+ <div id="container">
+ <div id="box"></div>
+ </div>
+</body>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/css-transitions/support/helper.js"></script>
+<script type="text/javascript">
+ promise_test(async t => {
+ const container = document.getElementById('container');
+ const box = document.getElementById('box');
+
+ await waitForAnimationFrames(2);
+
+ container.classList.add('moved');
+ const animations = document.getAnimations();
+ assert_equals(animations.length, 1);
+ assert_equals(getComputedStyle(box).transform,
+ "matrix(1, 0, 0, 1, 0, 0)");
+
+ animations[0].finish();
+ assert_equals(getComputedStyle(box).transform,
+ "matrix(1, 0, 0, 1, 300, 0)");
+
+ // Verify that we do not create a second transform transition.
+ box.style.transitionProperty = 'none';
+ box.style.transform = 'translateX(150px)';
+
+ assert_equals(box.getAnimations().length, 0);
+ assert_equals(getComputedStyle(box).transform,
+ "matrix(1, 0, 0, 1, 150, 0)");
+ }, 'Move after transition.');
+</script>
+</html>
diff --git a/testing/web-platform/tests/css/css-transitions/animations/text-shadow-composition.html b/testing/web-platform/tests/css/css-transitions/animations/text-shadow-composition.html
new file mode 100644
index 0000000000..d7d29c416a
--- /dev/null
+++ b/testing/web-platform/tests/css/css-transitions/animations/text-shadow-composition.html
@@ -0,0 +1,101 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>text-shadow composition</title>
+<link rel="help" href="https://drafts.csswg.org/css-text-decor-3/#text-shadow-property">
+<meta name="assert" content="text-shadow supports animation">
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/interpolation-testcommon.js"></script>
+
+<style>
+.target {
+ width: 40px;
+ height: 40px;
+ background-color: black;
+}
+.expected {
+ background-color: green;
+}
+</style>
+
+<body>
+<script>
+test_composition({
+ property: 'text-shadow',
+ replaceFrom: 'rgb(100, 100, 100) 10px 20px 30px',
+ addTo: 'rgb(200, 200, 200) 20px 40px 60px',
+}, [
+ {at: -0.3, expect: 'rgb(70, 70, 70 ) 7px 14px 21px'},
+ {at: 0, expect: 'rgb(100, 100, 100) 10px 20px 30px'},
+ {at: 0.5, expect: 'rgb(150, 150, 150) 15px 30px 45px'},
+ {at: 1, expect: 'rgb(200, 200, 200) 20px 40px 60px'},
+ {at: 1.5, expect: 'rgb(250, 250, 250) 25px 50px 75px'},
+]);
+
+test_composition({
+ property: 'text-shadow',
+ underlying: 'rgb(10, 20, 30) 1px 2px 3px',
+ addFrom: 'rgb(100, 100, 100) 10px 20px 30px',
+ addTo: 'rgb(200, 200, 200) 20px 40px 60px',
+}, [
+ {at: -0.3, expect: 'rgb(10, 20, 30) 1px 2px 3px, rgb(70, 70, 70) 7px 14px 21px'},
+ {at: 0, expect: 'rgb(10, 20, 30) 1px 2px 3px, rgb(100, 100, 100) 10px 20px 30px'},
+ {at: 0.5, expect: 'rgb(10, 20, 30) 1px 2px 3px, rgb(150, 150, 150) 15px 30px 45px'},
+ {at: 1, expect: 'rgb(10, 20, 30) 1px 2px 3px, rgb(200, 200, 200) 20px 40px 60px'},
+ {at: 1.5, expect: 'rgb(10, 20, 30) 1px 2px 3px, rgb(250, 250, 250) 25px 50px 75px'},
+]);
+
+test_composition({
+ property: 'text-shadow',
+ underlying: 'rgb(10, 20, 30) 1px 2px 3px, rgb(20, 40, 60) 2px 4px 6px',
+ addFrom: 'rgb(100, 100, 100) 10px 20px 30px',
+ addTo: 'rgb(200, 200, 200) 20px 40px 60px',
+}, [
+ {at: -0.3, expect: 'rgb(10, 20, 30) 1px 2px 3px, rgb(20, 40, 60) 2px 4px 6px, rgb(70, 70, 70) 7px 14px 21px'},
+ {at: 0, expect: 'rgb(10, 20, 30) 1px 2px 3px, rgb(20, 40, 60) 2px 4px 6px, rgb(100, 100, 100) 10px 20px 30px'},
+ {at: 0.5, expect: 'rgb(10, 20, 30) 1px 2px 3px, rgb(20, 40, 60) 2px 4px 6px, rgb(150, 150, 150) 15px 30px 45px'},
+ {at: 1, expect: 'rgb(10, 20, 30) 1px 2px 3px, rgb(20, 40, 60) 2px 4px 6px, rgb(200, 200, 200) 20px 40px 60px'},
+ {at: 1.5, expect: 'rgb(10, 20, 30) 1px 2px 3px, rgb(20, 40, 60) 2px 4px 6px, rgb(250, 250, 250) 25px 50px 75px'},
+]);
+
+test_composition({
+ property: 'text-shadow',
+ underlying: 'rgb(10, 20, 30) 1px 2px 3px, rgb(20, 40, 60) 2px 4px 6px',
+ addFrom: 'rgb(100, 100, 100) 10px 20px 30px',
+ replaceTo: 'rgb(200, 200, 200) 20px 40px 60px',
+}, [
+ {at: -0.3, expect: 'rgb(0, 0, 0) -4.7px -9.4px 0px, rgb(26, 52, 78) 2.6px 5.2px 7.8px, rgb(130, 130, 130) 13px 26px 39px'},
+ {at: 0, expect: 'rgb(10, 20, 30) 1px 2px 3px, rgb(20, 40, 60) 2px 4px 6px, rgb(100, 100, 100) 10px 20px 30px'},
+ {at: 0.5, expect: 'rgb(105, 110, 115) 10.5px 21px 31.5px, rgba(20, 40, 60, 0.5) 1px 2px 3px, rgba(100, 100, 100, 0.5) 5px 10px 15px'},
+ {at: 1, expect: 'rgb(200, 200, 200) 20px 40px 60px, rgba(0, 0, 0, 0) 0px 0px 0px, rgba(0, 0, 0, 0) 0px 0px 0px'},
+ {at: 1.5, expect: 'rgb(255, 255, 255) 29.5px 59px 88.5px, rgba(0, 0, 0, 0) -1px -2px 0px, rgba(0, 0, 0, 0) -5px -10px 0px'},
+]);
+
+test_composition({
+ property: 'text-shadow',
+ underlying: 'rgb(10, 20, 30) 1px 2px 3px, rgb(20, 40, 60) 2px 4px 6px',
+ replaceFrom: 'rgb(100, 100, 100) 10px 20px 30px',
+ addTo: 'rgb(200, 200, 200) 20px 40px 60px',
+}, [
+ {at: -0.3, expect: 'rgb(127, 124, 121) 12.7px 25.4px 38.1px, rgba(0, 0, 0, 0) -0.6px -1.2px 0px, rgba(0, 0, 0, 0) -6px -12px 0px'},
+ {at: 0, expect: 'rgb(100, 100, 100) 10px 20px 30px, rgba(0, 0, 0, 0) 0px 0px 0px, rgba(0, 0, 0, 0) 0px 0px 0px'},
+ {at: 0.5, expect: 'rgb(55, 60, 65) 5.5px 11px 16.5px, rgba(20, 40, 60, 0.5) 1px 2px 3px, rgba(200, 200, 200, 0.5) 10px 20px 30px'},
+ {at: 1, expect: 'rgb(10, 20, 30) 1px 2px 3px, rgb(20, 40, 60) 2px 4px 6px, rgb(200, 200, 200) 20px 40px 60px'},
+ {at: 1.5, expect: 'rgb(0, 0, 0) -3.5px -7px 0px, rgb(30, 60, 90) 3px 6px 9px, rgb(255, 255, 255) 30px 60px 90px'},
+]);
+
+test_composition({
+ property: 'text-shadow',
+ underlying: 'rgb(10, 20, 30) 1px 2px 3px, rgb(20, 40, 60) 2px 4px 6px, rgb(40, 80, 120) 4px 8px 12px',
+ addFrom: 'rgb(100, 100, 100) 10px 20px 30px, rgb(200, 200, 200) 20px 40px 60px',
+ replaceTo: 'rgb(200, 200, 200) 20px 40px 60px',
+}, [
+ {at: -0.3, expect: 'rgb(0, 0, 0) -4.7px -9.4px 0px, rgb(26, 52, 78) 2.6px 5.2px 7.8px, rgb(52, 104, 156) 5.2px 10.4px 15.6px, rgb(130, 130, 130) 13px 26px 39px, rgb(255, 255, 255) 26px 52px 78px'},
+ {at: 0, expect: 'rgb(10, 20, 30) 1px 2px 3px, rgb(20, 40, 60) 2px 4px 6px, rgb(40, 80, 120) 4px 8px 12px, rgb(100, 100, 100) 10px 20px 30px, rgb(200, 200, 200) 20px 40px 60px'},
+ {at: 0.5, expect: 'rgb(105, 110, 115) 10.5px 21px 31.5px, rgba(20, 40, 60, 0.5) 1px 2px 3px, rgba(40, 80, 120, 0.5) 2px 4px 6px, rgba(100, 100, 100, 0.5) 5px 10px 15px, rgba(200, 200, 200, 0.5) 10px 20px 30px'},
+ {at: 1, expect: 'rgb(200, 200, 200) 20px 40px 60px, rgba(0, 0, 0, 0) 0px 0px 0px, rgba(0, 0, 0, 0) 0px 0px 0px, rgba(0, 0, 0, 0) 0px 0px 0px, rgba(0, 0, 0, 0) 0px 0px 0px'},
+ {at: 1.5, expect: 'rgb(255, 255, 255) 29.5px 59px 88.5px, rgba(0, 0, 0, 0) -1px -2px 0px, rgba(0, 0, 0, 0) -2px -4px 0px, rgba(0, 0, 0, 0) -5px -10px 0px, rgba(0, 0, 0, 0) -10px -20px 0px'},
+]);
+</script>
+</body>
diff --git a/testing/web-platform/tests/css/css-transitions/animations/text-shadow-interpolation.html b/testing/web-platform/tests/css/css-transitions/animations/text-shadow-interpolation.html
new file mode 100644
index 0000000000..d4a75654a9
--- /dev/null
+++ b/testing/web-platform/tests/css/css-transitions/animations/text-shadow-interpolation.html
@@ -0,0 +1,123 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>text-shadow interpolation</title>
+<link rel="help" href="https://drafts.csswg.org/css-text-decor-3/#text-shadow-property">
+<meta name="assert" content="text-shadow supports animation">
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/interpolation-testcommon.js"></script>
+
+<style>
+.parent {
+ text-shadow: 30px 10px 30px orange;
+}
+
+.target {
+ display: inline-block;
+ font-size: 60pt;
+ margin-right: 20px;
+ margin-bottom: 30px;
+ color: green;
+ text-shadow: 10px 30px 10px orange;
+}
+
+.expected {
+ margin-right: 40px;
+}
+</style>
+<body>
+<template id="target-template">T</template>
+<script>
+test_interpolation({
+ property: 'text-shadow',
+ from: neutralKeyframe,
+ to: 'green 20px 20px 20px',
+}, [
+ {at: -0.3, expect: 'rgb(255, 176, 0) 7px 33px 7px'},
+ {at: 0, expect: 'rgb(255, 165, 0) 10px 30px 10px'},
+ {at: 0.3, expect: 'rgb(179, 154, 0) 13px 27px 13px'},
+ {at: 0.6, expect: 'rgb(102, 143, 0) 16px 24px 16px'},
+ {at: 1, expect: 'rgb(0, 128, 0) 20px 20px 20px'},
+ {at: 1.5, expect: 'rgb(0, 110, 0) 25px 15px 25px'},
+]);
+
+test_interpolation({
+ property: 'text-shadow',
+ from: 'initial',
+ to: 'green 20px 20px 20px',
+}, [
+ {at: -0.3, expect: 'rgba(0, 0, 0, 0) -6px -6px 0px'},
+ {at: 0, expect: 'rgba(0, 0, 0, 0) 0px 0px 0px'},
+ {at: 0.3, expect: 'rgba(0, 128, 0, 0.3) 6px 6px 6px'},
+ {at: 0.6, expect: 'rgba(0, 128, 0, 0.6) 12px 12px 12px'},
+ {at: 1, expect: 'rgb(0, 128, 0) 20px 20px 20px'},
+ {at: 1.5, expect: 'rgb(0, 192, 0) 30px 30px 30px'},
+]);
+
+test_interpolation({
+ property: 'text-shadow',
+ from: 'inherit',
+ to: 'green 20px 20px 20px',
+}, [
+ {at: -0.3, expect: 'rgb(255, 176, 0) 33px 7px 33px'},
+ {at: 0, expect: 'rgb(255, 165, 0) 30px 10px 30px'},
+ {at: 0.3, expect: 'rgb(179, 154, 0) 27px 13px 27px'},
+ {at: 0.6, expect: 'rgb(102, 143, 0) 24px 16px 24px'},
+ {at: 1, expect: 'rgb(0, 128, 0) 20px 20px 20px'},
+ {at: 1.5, expect: 'rgb(0, 110, 0) 15px 25px 15px'},
+]);
+
+test_interpolation({
+ property: 'text-shadow',
+ from: 'unset',
+ to: 'green 20px 20px 20px',
+}, [
+ {at: -0.3, expect: 'rgb(255, 176, 0) 33px 7px 33px'},
+ {at: 0, expect: 'rgb(255, 165, 0) 30px 10px 30px'},
+ {at: 0.3, expect: 'rgb(179, 154, 0) 27px 13px 27px'},
+ {at: 0.6, expect: 'rgb(102, 143, 0) 24px 16px 24px'},
+ {at: 1, expect: 'rgb(0, 128, 0) 20px 20px 20px'},
+ {at: 1.5, expect: 'rgb(0, 110, 0) 15px 25px 15px'},
+]);
+
+test_interpolation({
+ property: 'text-shadow',
+ from: 'black 15px 10px 5px',
+ to: 'orange -15px -10px 25px',
+}, [
+ {at: -0.3, expect: 'rgb(0, 0, 0) 24px 16px 0px'},
+ {at: 0, expect: 'rgb(0, 0, 0) 15px 10px 5px'},
+ {at: 0.3, expect: 'rgb(77, 50, 0) 6px 4px 11px'},
+ {at: 0.6, expect: 'rgb(153, 99, 0) -3px -2px 17px'},
+ {at: 1, expect: 'rgb(255, 165, 0) -15px -10px 25px'},
+ {at: 1.5, expect: 'rgb(255, 248, 0) -30px -20px 35px'},
+]);
+
+test_interpolation({
+ property: 'text-shadow',
+ from: 'black 10px 10px 10px',
+ to: 'currentColor 10px 10px 10px',
+}, [
+ {at: -0.3, expect: 'rgb(0, 0, 0) 10px 10px 10px'},
+ {at: 0, expect: 'rgb(0, 0, 0) 10px 10px 10px'},
+ {at: 0.3, expect: 'rgb(0, 38, 0) 10px 10px 10px'},
+ {at: 0.6, expect: 'rgb(0, 77, 0) 10px 10px 10px'},
+ {at: 1, expect: 'rgb(0, 128, 0) 10px 10px 10px'},
+ {at: 1.5, expect: 'rgb(0, 192, 0) 10px 10px 10px'},
+]);
+
+test_interpolation({
+ property: 'text-shadow',
+ from: 'black 0px 0px 0px',
+ to: 'black 1px 1px 1px',
+}, [
+ {at: -0.3, expect: 'rgb(0, 0, 0) -0.3px -0.3px 0px'},
+ {at: 0, expect: 'rgb(0, 0, 0) 0px 0px 0px'},
+ {at: 0.3, expect: 'rgb(0, 0, 0) 0.3px 0.3px 0.3px'},
+ {at: 0.6, expect: 'rgb(0, 0, 0) 0.6px 0.6px 0.6px'},
+ {at: 1, expect: 'rgb(0, 0, 0) 1px 1px 1px'},
+ {at: 1.5, expect: 'rgb(0, 0, 0) 1.5px 1.5px 1.5px'},
+]);
+</script>
+</body>
diff --git a/testing/web-platform/tests/css/css-transitions/animations/transition-end-event-shorthands.html b/testing/web-platform/tests/css/css-transitions/animations/transition-end-event-shorthands.html
new file mode 100644
index 0000000000..3816821972
--- /dev/null
+++ b/testing/web-platform/tests/css/css-transitions/animations/transition-end-event-shorthands.html
@@ -0,0 +1,65 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="UTF-8">
+ <title>transition end event with shorthand property</title>
+ <link rel="help" href="https://drafts.csswg.org/css-transitions/#transition-property-property">
+ <style>
+ #box {
+ transition: padding 1s;
+ padding: 0px 1px 2px 3px; // top right bottom left
+ }
+ </style>
+</head>
+<body>
+ <div id="container">
+ <div id="box"></div>
+ </div>
+</body>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/css-transitions/support/helper.js"></script>
+<script>
+ window.onload = () => {
+ function timeoutPromise() {
+ return waitForAnimationFrames(5);
+ }
+
+ promise_test(async t => {
+ // Make sure we have rendered the page before making the style change
+ // to ensure we get transitions.
+ await waitForAnimationFrames(2);
+
+ // Change three padding properties, but preserve padding-bottom.
+ // This should trigger 3 transitions.
+ box.style.padding = "8px 7px 2px 5px";
+
+ const animations = document.getAnimations();
+ const properties =
+ animations.map(anim => anim.transitionProperty).sort();
+ assert_array_equals(properties,
+ ['padding-left', 'padding-right', 'padding-top']);
+
+ // Expect a transitionend event for each of the CSSTransitions.
+ const eventWatcher =
+ new EventWatcher(t, box, 'transitionend', timeoutPromise);
+
+ const eventsPromise =
+ eventWatcher.wait_for(
+ ['transitionend', 'transitionend', 'transitionend'],
+ { record: 'all' }).then(events => {
+ events.forEach(event => {
+ assert_times_equal(event.elapsedTime, 1);
+ })
+ });
+ animations.forEach(anim => {
+ anim.finish();
+ });
+ await eventsPromise;
+
+ // Ensure no unexpected events are received.
+ await waitForAnimationFrames(2);
+ }, 'Transition end events generated for transition on shorthand property');
+ };
+</script>
+</html>
diff --git a/testing/web-platform/tests/css/css-transitions/animations/transition-timing-function.html b/testing/web-platform/tests/css/css-transitions/animations/transition-timing-function.html
new file mode 100644
index 0000000000..6dc42f5529
--- /dev/null
+++ b/testing/web-platform/tests/css/css-transitions/animations/transition-timing-function.html
@@ -0,0 +1,87 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="UTF-8">
+ <title>transition timing function</title>
+ <link rel="help" href="https://drafts.csswg.org/css-transitions-1/#transition-timing-function-property">
+ <style>
+ .box {
+ position: relative;
+ left: 0;
+ height: 100px;
+ width: 100px;
+ margin: 10px;
+ background-color: blue;
+ transition: left 1s linear;
+ }
+ .animating > .box {
+ left: 400px;
+ }
+ </style>
+</head>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/css-transitions/support/helper.js"></script>
+<script src="/css/css-easing/testcommon.js"></script>
+<script>
+ window.onload = () => {
+ function verifyPosition(element_id, expected) {
+ const element = document.getElementById(element_id);
+ const actual = Math.round(parseFloat(getComputedStyle(element).left));
+ assert_equals(actual, expected, `verify ${element_id} left`);
+ }
+
+ function easing(x1, y1, x2, y2) {
+ return Math.round(400 * cubicBezier(x1, y1, x2, y2)(0.5));
+ }
+
+ function ease() {
+ return easing(0.25, 0.1, 0.25, 1); // 321
+ }
+
+ function easeIn() {
+ return easing(0.42, 0, 1, 1); // 126
+ }
+
+ function easeOut() {
+ return easing(0.0, 0.0, 0.58, 1.0); // 274
+ }
+
+ function easeInOut() {
+ return easing(0.42, 0.0, 0.58, 1.0); // 200
+ }
+
+ promise_test(async t => {
+ // Make sure we have rendered the page before making the style change
+ // to ensure we get transitions.
+ await waitForAnimationFrames(2);
+ promises = [];
+ document.getElementById('container').className = 'animating';
+ document.getAnimations().forEach(anim => {
+ anim.pause();
+ anim.currentTime = 500;
+ promises.push(anim.ready);
+ });
+ await Promise.all(promises).then(() => {
+ assert_equals(promises.length, 6, 'Unexpected animation count');
+ verifyPosition('box1', 200); // linear easing
+ verifyPosition('box2', ease());
+ verifyPosition('box3', easeIn());
+ verifyPosition('box4', easeOut());
+ verifyPosition('box5', easeInOut());
+ verifyPosition('box6', 400);
+ });
+ }, 'Ensure that transition easing functions are properly applied.');
+ };
+</script>
+<body>
+<div id="container">
+ <div id="box1" class="box" style="transition-timing-function: linear;"></div>
+ <div id="box2" class="box" style="transition-timing-function: ease;"></div>
+ <div id="box3" class="box" style="transition-timing-function: ease-in;"></div>
+ <div id="box4" class="box" style="transition-timing-function: ease-out;"></div>
+ <div id="box5" class="box" style="transition-timing-function: ease-in-out;"></div>
+ <div id="box6" class="box" style="transition-timing-function: linear(0, 1, 0);"></div>
+</div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-transitions/animations/vertical-align-composition.html b/testing/web-platform/tests/css/css-transitions/animations/vertical-align-composition.html
new file mode 100644
index 0000000000..222a511679
--- /dev/null
+++ b/testing/web-platform/tests/css/css-transitions/animations/vertical-align-composition.html
@@ -0,0 +1,65 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>vertical-align composition</title>
+<link rel="help" href="https://www.w3.org/TR/CSS2/visudet.html#propdef-vertical-align">
+<meta name="assert" content="vertical-align supports animation">
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/interpolation-testcommon.js"></script>
+
+<body>
+<script>
+test_composition({
+ property: 'vertical-align',
+ underlying: '50px',
+ addFrom: '100px',
+ addTo: '200px',
+}, [
+ {at: -0.3, expect: '120px'},
+ {at: 0, expect: '150px'},
+ {at: 0.5, expect: '200px'},
+ {at: 1, expect: '250px'},
+ {at: 1.5, expect: '300px'},
+]);
+
+test_composition({
+ property: 'vertical-align',
+ underlying: '100px',
+ addFrom: '10px',
+ addTo: '2px',
+}, [
+ {at: -0.5, expect: '114px'},
+ {at: 0, expect: '110px'},
+ {at: 0.5, expect: '106px'},
+ {at: 1, expect: '102px'},
+ {at: 1.5, expect: '98px'},
+]);
+
+test_composition({
+ property: 'vertical-align',
+ underlying: '10%',
+ addFrom: '100px',
+ addTo: '20%',
+}, [
+ {at: -0.3, expect: 'calc(130px + 4%)'},
+ {at: 0, expect: 'calc(100px + 10%)'},
+ {at: 0.5, expect: 'calc(50px + 20%)'},
+ {at: 1, expect: '30%'},
+ {at: 1.5, expect: 'calc(-50px + 40%)'},
+]);
+
+test_composition({
+ property: 'vertical-align',
+ underlying: '50px',
+ addFrom: '100px',
+ replaceTo: '200px',
+}, [
+ {at: -0.3, expect: '135px'},
+ {at: 0, expect: '150px'},
+ {at: 0.5, expect: '175px'},
+ {at: 1, expect: '200px'},
+ {at: 1.5, expect: '225px'},
+]);
+</script>
+</body>
diff --git a/testing/web-platform/tests/css/css-transitions/animations/vertical-align-interpolation.html b/testing/web-platform/tests/css/css-transitions/animations/vertical-align-interpolation.html
new file mode 100644
index 0000000000..194f9fc9f6
--- /dev/null
+++ b/testing/web-platform/tests/css/css-transitions/animations/vertical-align-interpolation.html
@@ -0,0 +1,98 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>vertical-align interpolation</title>
+<link rel="help" href="https://www.w3.org/TR/CSS2/visudet.html#propdef-vertical-align">
+<meta name="assert" content="vertical-align supports animation">
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/interpolation-testcommon.js"></script>
+
+<style>
+.parent {
+ vertical-align: 100px;
+}
+.target {
+ width: 100px;
+ height: 100px;
+ background-color: black;
+ display: inline-block;
+ vertical-align: 10px;
+}
+.expected {
+ background-color: green;
+}
+</style>
+
+<body>
+<script>
+test_interpolation({
+ property: 'vertical-align',
+ from: neutralKeyframe,
+ to: '40px',
+}, [
+ {at: -0.5, expect: '-5px'},
+ {at: 0, expect: '10px'},
+ {at: 0.3, expect: '19px'},
+ {at: 0.6, expect: '28px'},
+ {at: 1, expect: '40px'},
+ {at: 1.5, expect: '55px'},
+]);
+
+test_no_interpolation({
+ property: 'vertical-align',
+ from: 'initial',
+ to: '40px',
+});
+
+test_interpolation({
+ property: 'vertical-align',
+ from: 'inherit',
+ to: '40px',
+}, [
+ {at: -0.5, expect: '130px'},
+ {at: 0, expect: '100px'},
+ {at: 0.3, expect: '82px'},
+ {at: 0.6, expect: '64px'},
+ {at: 1, expect: '40px'},
+ {at: 1.5, expect: '10px'},
+]);
+
+test_no_interpolation({
+ property: 'vertical-align',
+ from: 'unset',
+ to: '40px',
+});
+
+test_interpolation({
+ property: 'vertical-align',
+ from: '0px',
+ to: '100px'
+}, [
+ {at: -0.5, expect: '-50px'},
+ {at: 0, expect: '0px'},
+ {at: 0.3, expect: '30px'},
+ {at: 0.6, expect: '60px'},
+ {at: 1, expect: '100px'},
+ {at: 1.5, expect: '150px'}
+]);
+
+test_interpolation({
+ property: 'vertical-align',
+ from: '40px',
+ to: '40%'
+}, [
+ {at: -0.5, expect: 'calc(60px - 20%)'},
+ {at: 0, expect: 'calc(40px + 0%)'},
+ {at: 0.3, expect: 'calc(28px + 12%)'},
+ {at: 1, expect: '40%'},
+ {at: 1.5, expect: 'calc(-20px + 60%)'}
+]);
+
+test_no_interpolation({
+ property: 'vertical-align',
+ from: 'super',
+ to: '40%'
+});
+</script>
+</body>
diff --git a/testing/web-platform/tests/css/css-transitions/animations/z-index-interpolation.html b/testing/web-platform/tests/css/css-transitions/animations/z-index-interpolation.html
new file mode 100644
index 0000000000..9673cc4d8c
--- /dev/null
+++ b/testing/web-platform/tests/css/css-transitions/animations/z-index-interpolation.html
@@ -0,0 +1,130 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>z-index interpolation</title>
+<link rel="help" href="https://www.w3.org/TR/CSS2/visuren.html#z-index">
+<meta name="assert" content="z-index supports animation">
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/interpolation-testcommon.js"></script>
+
+<style>
+body {
+ margin-top: 20px;
+}
+.layer-reference {
+ position: fixed;
+ top: 0px;
+ height: 100vh;
+ width: 50px;
+ background-color: rgba(255, 255, 255, 0.75);
+ font-family: sans-serif;
+ text-align: center;
+ padding-top: 5px;
+ border: 1px solid;
+}
+.parent {
+ z-index: 15;
+}
+.target {
+ position: relative;
+ width: 350px;
+ height: 10px;
+ z-index: -2;
+}
+.actual {
+ background-color: black;
+}
+.expected {
+ background-color: green;
+}
+</style>
+
+<body></body>
+
+<script>
+test_interpolation({
+ property: 'z-index',
+ from: neutralKeyframe,
+ to: '5',
+}, [
+ {at: -0.3, expect: '-4'},
+ {at: 0, expect: '-2'},
+ {at: 0.3, expect: '0'},
+ {at: 0.6, expect: '2'},
+ {at: 1, expect: '5'},
+ {at: 1.5, expect: '9'},
+]);
+
+test_no_interpolation({
+ property: 'z-index',
+ from: 'initial',
+ to: '5',
+});
+
+// We fail to inherit correctly due to style overadjustment: crbug.com/375982
+test_interpolation({
+ property: 'z-index',
+ from: 'inherit',
+ to: '5',
+}, [
+ {at: -0.3, expect: '18'},
+ {at: 0, expect: '15'},
+ {at: 0.3, expect: '12'},
+ {at: 0.6, expect: '9'},
+ {at: 1, expect: '5'},
+ {at: 1.5, expect: '0'},
+]);
+
+test_no_interpolation({
+ property: 'z-index',
+ from: 'unset',
+ to: '5',
+});
+
+test_interpolation({
+ property: 'z-index',
+ from: '-5',
+ to: '5'
+}, [
+ {at: -0.3, expect: '-8'},
+ {at: 0, expect: '-5'},
+ {at: 0.3, expect: '-2'},
+ {at: 0.6, expect: '1'},
+ {at: 1, expect: '5'},
+ {at: 1.5, expect: '10'},
+]);
+
+test_interpolation({
+ property: 'z-index',
+ from: '2',
+ to: '4'
+}, [
+ {at: -0.3, expect: '1'},
+ {at: 0, expect: '2'},
+ {at: 0.3, expect: '3'},
+ {at: 0.6, expect: '3'},
+ {at: 1, expect: '4'},
+ {at: 1.5, expect: '5'},
+]);
+
+test_interpolation({
+ property: 'z-index',
+ from: '-2',
+ to: '-4'
+}, [
+ {at: -0.3, expect: '-1'},
+ {at: 0, expect: '-2'},
+ {at: 0.1, expect: '-2'},
+ {at: 0.3, expect: '-3'},
+ {at: 0.6, expect: '-3'},
+ {at: 1, expect: '-4'},
+ {at: 1.5, expect: '-5'},
+]);
+
+test_no_interpolation({
+ property: 'z-index',
+ from: 'auto',
+ to: '10',
+});
+</script>