Commit faa1edfe authored by George Steel's avatar George Steel Committed by Commit Bot

update WPT tests to eliminate CSSPseudoElement from animations

Goes with spec CL https://github.com/w3c/csswg-drafts/pull/4437 (merged)
Eliminated the use of CSSPseudoElement from WebAnimations to coincide with
recent spec changes. JeyframeEffect targets now use an Element reference
and pseudo-element selector like getComputedStyle and css-animations events.

Change-Id: Ib6957a7b764eac3b4372ad35c1b79b139c356a19
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1894477Reviewed-by: default avatarStephen McGruer <smcgruer@chromium.org>
Reviewed-by: default avatarKevin Ellis <kevers@chromium.org>
Commit-Queue: George Steel <gtsteel@chromium.org>
Cr-Commit-Position: refs/heads/master@{#714541}
parent 2e0a019f
This is a testharness.js-based test.
PASS getAnimations returns CSSAnimation objects
FAIL getAnimations returns CSS transitions/animations, and script-generated animations in the expected order assert_equals: 1st animation is the 1st transition sorted by name expected (string) "height" but got (undefined) undefined
Harness: the test ran to completion.
<!doctype html>
<meta charset=utf-8>
<title>CSSPseudoElement.getAnimations() 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 anim1 { }
@keyframes anim2 { }
.before::before {
animation: anim1 10s;
content: '';
}
.after-with-mix-anims-trans::after {
content: '';
animation: anim1 10s, anim2 10s;
width: 0px;
height: 0px;
transition: all 100s;
}
.after-change::after {
width: 100px;
height: 100px;
content: '';
}
</style>
<div id="log"></div>
<script>
'use strict';
test(t => {
const div = addDiv(t, { class: 'before' });
const pseudoTarget = document.getAnimations()[0].effect.target;
assert_equals(pseudoTarget.getAnimations().length, 1,
'Expected number of animations are returned');
assert_equals(pseudoTarget.getAnimations()[0].animationName, 'anim1',
'CSS animation name matches');
}, 'getAnimations returns CSSAnimation objects');
test(t => {
const div = addDiv(t, { class: 'after-with-mix-anims-trans' });
// Trigger transitions
flushComputedStyle(div);
div.classList.add('after-change');
// Create additional animation on the pseudo-element from script
const pseudoTarget = document.getAnimations()[0].effect.target;
const effect = new KeyframeEffect(pseudoTarget,
{ background: ["blue", "red"] },
3 * MS_PER_SEC);
const newAnimation = new Animation(effect, document.timeline);
newAnimation.id = 'scripted-anim';
newAnimation.play();
// Check order - the script-generated animation should appear later
const anims = pseudoTarget.getAnimations();
assert_equals(anims.length, 5,
'Got expected number of animations/trnasitions running on ' +
'::after pseudo element');
assert_equals(anims[0].transitionProperty, 'height',
'1st animation is the 1st transition sorted by name');
assert_equals(anims[1].transitionProperty, 'width',
'2nd animation is the 2nd transition sorted by name ');
assert_equals(anims[2].animationName, 'anim1',
'3rd animation is the 1st animation in animation-name list');
assert_equals(anims[3].animationName, 'anim2',
'4rd animation is the 2nd animation in animation-name list');
assert_equals(anims[4].id, 'scripted-anim',
'Animation added by script appears last');
}, 'getAnimations returns CSS transitions/animations, and script-generated ' +
'animations in the expected order');
</script>
...@@ -12,6 +12,6 @@ PASS Finished but not filling CSS Animations are not returned ...@@ -12,6 +12,6 @@ PASS Finished but not filling CSS Animations are not returned
PASS Yet-to-start CSS Animations are returned PASS Yet-to-start CSS Animations are returned
PASS CSS Animations canceled via the API are not returned PASS CSS Animations canceled via the API are not returned
PASS CSS Animations canceled and restarted via the API are returned PASS CSS Animations canceled and restarted via the API are returned
FAIL CSS Animations targetting (pseudo-)elements should have correct order after sorting assert_equals: Animation #2 has expected target expected (object) Element node <div id="parent" style="animation: animBottom 100s"><div ... but got (undefined) undefined FAIL CSS Animations targetting (pseudo-)elements should have correct order after sorting assert_equals: Animation #1 has null pseudo type expected (object) null but got (undefined) undefined
Harness: the test ran to completion. Harness: the test ran to completion.
...@@ -298,12 +298,12 @@ test(t => { ...@@ -298,12 +298,12 @@ test(t => {
if (pseudo) { if (pseudo) {
assert_equals( assert_equals(
actual.effect.target.element, actual.effect.target,
element, element,
`Animation #${index + 1} has expected target` `Animation #${index + 1} has expected target`
); );
assert_equals( assert_equals(
actual.effect.target.type, actual.effect.pseudoElement,
pseudo, pseudo,
`Animation #${index + 1} has expected pseudo type` `Animation #${index + 1} has expected pseudo type`
); );
...@@ -313,6 +313,11 @@ test(t => { ...@@ -313,6 +313,11 @@ test(t => {
element, element,
`Animation #${index + 1} has expected target` `Animation #${index + 1} has expected target`
); );
assert_equals(
actual.effect.pseudoElement,
null,
`Animation #${index + 1} has null pseudo type`
);
} }
} }
}, 'CSS Animations targetting (pseudo-)elements should have correct order ' }, 'CSS Animations targetting (pseudo-)elements should have correct order '
......
...@@ -17,9 +17,9 @@ PASS getAnimations returns objects with the same identity ...@@ -17,9 +17,9 @@ PASS getAnimations returns objects with the same identity
PASS getAnimations for CSS Animations that are canceled PASS getAnimations for CSS Animations that are canceled
FAIL getAnimations for CSS Animations follows animation-name order assert_equals: animation order after prepending to list expected "anim1" but got "anim2" FAIL getAnimations for CSS Animations follows animation-name order assert_equals: animation order after prepending to list expected "anim1" but got "anim2"
PASS { subtree: false } on a leaf element returns the element's animations and ignore pseudo-elements PASS { subtree: false } on a leaf element returns the element's animations and ignore pseudo-elements
FAIL { subtree: true } on a leaf element returns the element's animations and its pseudo-elements' animations assert_equals: The animation targeting the ::before pseudo-element should be returned second expected (string) "::before" but got (undefined) undefined FAIL { subtree: true } on a leaf element returns the element's animations and its pseudo-elements' animations assert_equals: The animation targeting the parent element should be returned first expected (object) null but got (undefined) undefined
PASS { subtree: false } on an element with a child returns only the element's animations PASS { subtree: false } on an element with a child returns only the element's animations
FAIL { subtree: true } on an element with a child returns animations from the element, its pseudo-elements, its child and its child pseudo-elements assert_equals: The animation targeting the ::before pseudo-element should be returned second expected (string) "::before" but got (undefined) undefined FAIL { subtree: true } on an element with a child returns animations from the element, its pseudo-elements, its child and its child pseudo-elements assert_equals: The animation targeting the parent element should be returned first expected (object) null but got (undefined) undefined
PASS { subtree: true } on an element with many descendants returns animations from all the descendants PASS { subtree: true } on an element with many descendants returns animations from all the descendants
Harness: the test ran to completion. Harness: the test ran to completion.
...@@ -325,10 +325,13 @@ test(t => { ...@@ -325,10 +325,13 @@ test(t => {
assert_equals(animations[0].effect.target, target, assert_equals(animations[0].effect.target, target,
'The animation targeting the parent element ' + 'The animation targeting the parent element ' +
'should be returned first'); 'should be returned first');
assert_equals(animations[1].effect.target.type, '::before', assert_equals(animations[0].effect.pseudoElement, null,
'The animation targeting the parent element ' +
'should be returned first')
assert_equals(animations[1].effect.pseudoElement, '::before',
'The animation targeting the ::before pseudo-element ' + 'The animation targeting the ::before pseudo-element ' +
'should be returned second'); 'should be returned second');
assert_equals(animations[2].effect.target.type, '::after', assert_equals(animations[2].effect.pseudoElement, '::after',
'The animation targeting the ::after pesudo-element ' + 'The animation targeting the ::after pesudo-element ' +
'should be returned last'); 'should be returned last');
}, '{ subtree: true } on a leaf element returns the element\'s animations' }, '{ subtree: true } on a leaf element returns the element\'s animations'
...@@ -366,34 +369,37 @@ test(t => { ...@@ -366,34 +369,37 @@ test(t => {
const animations = parent.getAnimations({ subtree: true }); const animations = parent.getAnimations({ subtree: true });
assert_equals(animations.length, 6, assert_equals(animations.length, 6,
'Should find all elements, pesudo-elements that parent has'); 'Should find all elements, pseudo-elements that parent has');
assert_equals(animations[0].effect.target, parent, assert_equals(animations[0].effect.target, parent,
'The animation targeting the parent element ' + 'The animation targeting the parent element ' +
'should be returned first'); 'should be returned first');
assert_equals(animations[1].effect.target.type, '::before', assert_equals(animations[0].effect.pseudoElement, null,
'The animation targeting the parent element ' +
'should be returned first');
assert_equals(animations[1].effect.pseudoElement, '::before',
'The animation targeting the ::before pseudo-element ' + 'The animation targeting the ::before pseudo-element ' +
'should be returned second'); 'should be returned second');
assert_equals(animations[1].effect.target.element, parent, assert_equals(animations[1].effect.target, parent,
'This ::before element should be child of parent element'); 'This ::before element should be child of parent element');
assert_equals(animations[2].effect.target.type, '::after', assert_equals(animations[2].effect.pseudoElement, '::after',
'The animation targeting the ::after pesudo-element ' + 'The animation targeting the ::after pesudo-element ' +
'should be returned third'); 'should be returned third');
assert_equals(animations[2].effect.target.element, parent, assert_equals(animations[2].effect.target, parent,
'This ::after element should be child of parent element'); 'This ::after element should be child of parent element');
assert_equals(animations[3].effect.target, child, assert_equals(animations[3].effect.target, child,
'The animation targeting the child element ' + 'The animation targeting the child element ' +
'should be returned fourth'); 'should be returned fourth');
assert_equals(animations[4].effect.target.type, '::before', assert_equals(animations[4].effect.pseudoElement, '::before',
'The animation targeting the ::before pseudo-element ' + 'The animation targeting the ::before pseudo-element ' +
'should be returned fifth'); 'should be returned fifth');
assert_equals(animations[4].effect.target.element, child, assert_equals(animations[4].effect.target, child,
'This ::before element should be child of child element'); 'This ::before element should be child of child element');
assert_equals(animations[5].effect.target.type, '::after', assert_equals(animations[5].effect.pseudoElement, '::after',
'The animation targeting the ::after pesudo-element ' + 'The animation targeting the ::after pesudo-element ' +
'should be returned last'); 'should be returned last');
assert_equals(animations[5].effect.target.element, child, assert_equals(animations[5].effect.target, child,
'This ::after element should be child of child element'); 'This ::after element should be child of child element');
}, '{ subtree: true } on an element with a child returns animations from the' }, '{ subtree: true } on an element with a child returns animations from the'
+ ' element, its pseudo-elements, its child and its child pseudo-elements'); + ' element, its pseudo-elements, its child and its child pseudo-elements');
......
This is a testharness.js-based test.
FAIL getAnimations sorts simultaneous transitions by name assert_class_string: Got pseudo-element target expected "[object CSSPseudoElement]" but got "[object Element]"
Harness: the test ran to completion.
<!doctype html>
<meta charset=utf-8>
<title>CSSPseudoElement.getAnimations() for CSS transitions</title>
<link rel="help" href="https://drafts.csswg.org/css-transitions-2/#animation-composite-order">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="support/helper.js"></script>
<style>
.init::before {
content: '';
height: 0px;
width: 0px;
opacity: 0;
transition: all 100s;
}
.change::before {
height: 100px;
width: 100px;
opacity: 1;
}
</style>
<div id="log"></div>
<script>
'use strict';
test(t => {
const div = addDiv(t, { class: 'init' });
getComputedStyle(div).width;
div.classList.add('change');
// Sanity checks
assert_equals(document.getAnimations().length, 3,
'Got expected number of animations on document');
const pseudoTarget = document.getAnimations()[0].effect.target;
assert_class_string(pseudoTarget, 'CSSPseudoElement',
'Got pseudo-element target');
// Check animations returned from the pseudo element are in correct order
const anims = pseudoTarget.getAnimations();
assert_equals(anims.length, 3,
'Got expected number of animations on pseudo-element');
assert_equals(anims[0].transitionProperty, 'height');
assert_equals(anims[1].transitionProperty, 'opacity');
assert_equals(anims[2].transitionProperty, 'width');
}, 'getAnimations sorts simultaneous transitions by name');
</script>
This is a testharness.js-based test. This is a testharness.js-based test.
PASS getAnimations for non-animated content PASS getAnimations for non-animated content
PASS getAnimations for CSS Transitions PASS getAnimations for CSS Transitions
FAIL CSS Transitions targetting (pseudo-)elements should have correct order after sorting assert_equals: Transition #2 has expected target expected (object) Element node <div style="display: list-item; left: 100px; transition: ... but got (undefined) undefined FAIL CSS Transitions targetting (pseudo-)elements should have correct order after sorting assert_equals: Transition #1 has null pseudo type expected (object) null but got (undefined) undefined
PASS Transitions are not returned after they have finished PASS Transitions are not returned after they have finished
Harness: the test ran to completion. Harness: the test ran to completion.
...@@ -99,12 +99,12 @@ test(t => { ...@@ -99,12 +99,12 @@ test(t => {
if (pseudo) { if (pseudo) {
assert_equals( assert_equals(
actual.effect.target.element, actual.effect.target,
element, element,
`Transition #${index + 1} has expected target` `Transition #${index + 1} has expected target`
); );
assert_equals( assert_equals(
actual.effect.target.type, actual.effect.pseudoElement,
pseudo, pseudo,
`Transition #${index + 1} has expected pseudo type` `Transition #${index + 1} has expected pseudo type`
); );
...@@ -114,6 +114,11 @@ test(t => { ...@@ -114,6 +114,11 @@ test(t => {
element, element,
`Transition #${index + 1} has expected target` `Transition #${index + 1} has expected target`
); );
assert_equals(
actual.effect.pseudoElement,
null,
`Transition #${index + 1} has null pseudo type`
);
} }
} }
}, 'CSS Transitions targetting (pseudo-)elements should have correct order ' }, 'CSS Transitions targetting (pseudo-)elements should have correct order '
......
This is a testharness.js-based test. This is a testharness.js-based test.
Found 563 tests; 544 PASS, 19 FAIL, 0 TIMEOUT, 0 NOTRUN. Found 560 tests; 541 PASS, 19 FAIL, 0 TIMEOUT, 0 NOTRUN.
PASS Setup PASS Setup
PASS align-content (type: discrete) has testAccumulation function PASS align-content (type: discrete) has testAccumulation function
PASS align-content: "flex-end" onto "flex-start" PASS align-content: "flex-end" onto "flex-start"
...@@ -176,9 +176,6 @@ PASS column-width: length of rem ...@@ -176,9 +176,6 @@ PASS column-width: length of rem
PASS column-width (type: discrete) has testAccumulation function PASS column-width (type: discrete) has testAccumulation function
PASS column-width: "1px" onto "auto" PASS column-width: "1px" onto "auto"
PASS column-width: "auto" onto "1px" PASS column-width: "auto" onto "1px"
PASS content (type: discrete) has testAccumulation function
PASS content: ""b"" onto ""a""
PASS content: ""a"" onto ""b""
PASS counter-increment (type: discrete) has testAccumulation function PASS counter-increment (type: discrete) has testAccumulation function
PASS counter-increment: "ident-2 2" onto "ident-1 1" PASS counter-increment: "ident-2 2" onto "ident-1 1"
PASS counter-increment: "ident-1 1" onto "ident-2 2" PASS counter-increment: "ident-1 1" onto "ident-2 2"
......
This is a testharness.js-based test. This is a testharness.js-based test.
Found 559 tests; 541 PASS, 18 FAIL, 0 TIMEOUT, 0 NOTRUN. Found 556 tests; 538 PASS, 18 FAIL, 0 TIMEOUT, 0 NOTRUN.
PASS Setup PASS Setup
PASS align-content (type: discrete) has testAddition function PASS align-content (type: discrete) has testAddition function
PASS align-content: "flex-end" onto "flex-start" PASS align-content: "flex-end" onto "flex-start"
...@@ -176,9 +176,6 @@ PASS column-width: length of rem ...@@ -176,9 +176,6 @@ PASS column-width: length of rem
PASS column-width (type: discrete) has testAddition function PASS column-width (type: discrete) has testAddition function
PASS column-width: "1px" onto "auto" PASS column-width: "1px" onto "auto"
PASS column-width: "auto" onto "1px" PASS column-width: "auto" onto "1px"
PASS content (type: discrete) has testAddition function
PASS content: ""b"" onto ""a""
PASS content: ""a"" onto ""b""
PASS counter-increment (type: discrete) has testAddition function PASS counter-increment (type: discrete) has testAddition function
PASS counter-increment: "ident-2 2" onto "ident-1 1" PASS counter-increment: "ident-2 2" onto "ident-1 1"
PASS counter-increment: "ident-1 1" onto "ident-2 2" PASS counter-increment: "ident-1 1" onto "ident-2 2"
......
This is a testharness.js-based test. This is a testharness.js-based test.
Found 690 tests; 657 PASS, 33 FAIL, 0 TIMEOUT, 0 NOTRUN. Found 686 tests; 653 PASS, 33 FAIL, 0 TIMEOUT, 0 NOTRUN.
PASS Setup PASS Setup
PASS align-content (type: discrete) has testInterpolation function PASS align-content (type: discrete) has testInterpolation function
PASS align-content uses discrete animation when animating between "flex-start" and "flex-end" with linear easing PASS align-content uses discrete animation when animating between "flex-start" and "flex-end" with linear easing
...@@ -212,10 +212,6 @@ PASS column-width (type: discrete) has testInterpolation function ...@@ -212,10 +212,6 @@ PASS column-width (type: discrete) has testInterpolation function
PASS column-width uses discrete animation when animating between "auto" and "1px" with linear easing PASS column-width uses discrete animation when animating between "auto" and "1px" with linear easing
PASS column-width uses discrete animation when animating between "auto" and "1px" with effect easing PASS column-width uses discrete animation when animating between "auto" and "1px" with effect easing
PASS column-width uses discrete animation when animating between "auto" and "1px" with keyframe easing PASS column-width uses discrete animation when animating between "auto" and "1px" with keyframe easing
PASS content (type: discrete) has testInterpolation function
PASS content uses discrete animation when animating between ""a"" and ""b"" with linear easing
PASS content uses discrete animation when animating between ""a"" and ""b"" with effect easing
PASS content uses discrete animation when animating between ""a"" and ""b"" with keyframe easing
PASS counter-increment (type: discrete) has testInterpolation function PASS counter-increment (type: discrete) has testInterpolation function
PASS counter-increment uses discrete animation when animating between "ident-1 1" and "ident-2 2" with linear easing PASS counter-increment uses discrete animation when animating between "ident-1 1" and "ident-2 2" with linear easing
PASS counter-increment uses discrete animation when animating between "ident-1 1" and "ident-2 2" with effect easing PASS counter-increment uses discrete animation when animating between "ident-1 1" and "ident-2 2" with effect easing
......
...@@ -410,15 +410,6 @@ const gCSSProperties = { ...@@ -410,15 +410,6 @@ const gCSSProperties = {
{ type: 'discrete', options: [ [ 'auto', '1px' ] ] } { type: 'discrete', options: [ [ 'auto', '1px' ] ] }
] ]
}, },
'content': {
// https://drafts.csswg.org/css-content-3/#propdef-content
types: [
{ type: 'discrete', options: [ [ '"a"', '"b"' ] ] }
],
setup: t => {
return getPseudoElement(t, 'before');
}
},
'counter-increment': { 'counter-increment': {
// https://drafts.csswg.org/css-lists-3/#propdef-counter-increment // https://drafts.csswg.org/css-lists-3/#propdef-counter-increment
types: [ types: [
...@@ -1432,13 +1423,11 @@ const gCSSProperties = { ...@@ -1432,13 +1423,11 @@ const gCSSProperties = {
}; };
function testAnimationSamples(animation, idlName, testSamples) { function testAnimationSamples(animation, idlName, testSamples) {
const type = animation.effect.target.type; const pseudoType = animation.effect.pseudoElement;
const target = animation.effect.target.constructor.name === 'CSSPseudoElement' const target = animation.effect.target;
? animation.effect.target.element
: animation.effect.target;
for (const testSample of testSamples) { for (const testSample of testSamples) {
animation.currentTime = testSample.time; animation.currentTime = testSample.time;
assert_equals(getComputedStyle(target, type)[idlName], assert_equals(getComputedStyle(target, pseudoType)[idlName],
testSample.expected, testSample.expected,
`The value should be ${testSample.expected}` + `The value should be ${testSample.expected}` +
` at ${testSample.time}ms`); ` at ${testSample.time}ms`);
...@@ -1453,10 +1442,8 @@ function toOrderedArray(string) { ...@@ -1453,10 +1442,8 @@ function toOrderedArray(string) {
// don't specify an order for serializing computed values. // don't specify an order for serializing computed values.
// This test is for such the property. // This test is for such the property.
function testAnimationSamplesWithAnyOrder(animation, idlName, testSamples) { function testAnimationSamplesWithAnyOrder(animation, idlName, testSamples) {
const type = animation.effect.target.type; const type = animation.effect.pseudoElement;
const target = animation.effect.target.constructor.name === 'CSSPseudoElement' const target = animation.effect.target;
? animation.effect.target.element
: animation.effect.target;
for (const testSample of testSamples) { for (const testSample of testSamples) {
animation.currentTime = testSample.time; animation.currentTime = testSample.time;
......
This is a testharness.js-based test. This is a testharness.js-based test.
Found 138 tests; 136 PASS, 2 FAIL, 0 TIMEOUT, 0 NOTRUN. Found 140 tests; 137 PASS, 3 FAIL, 0 TIMEOUT, 0 NOTRUN.
PASS Element.animate() creates an Animation object PASS Element.animate() creates an Animation object
PASS Element.animate() creates an Animation object in the relevant realm of the target element PASS Element.animate() creates an Animation object in the relevant realm of the target element
PASS Element.animate() creates an Animation object with a KeyframeEffect PASS Element.animate() creates an Animation object with a KeyframeEffect
...@@ -134,9 +134,11 @@ PASS Element.animate() correctly sets the Animation's timeline ...@@ -134,9 +134,11 @@ PASS Element.animate() correctly sets the Animation's timeline
PASS Element.animate() correctly sets the Animation's timeline when triggered on an element in a different document PASS Element.animate() correctly sets the Animation's timeline when triggered on an element in a different document
PASS Element.animate() calls play on the Animation PASS Element.animate() calls play on the Animation
PASS Element.animate() does NOT trigger a style change event PASS Element.animate() does NOT trigger a style change event
PASS CSSPseudoElement.animate() creates an Animation object PASS animate() with pseudoElement parameter creates an Animation object
FAIL CSSPseudoElement.animate() creates an Animation object for ::marker assert_true: expected true got false PASS animate() with pseudoElement parameter creates an Animation object for ::marker
PASS CSSPseudoElement.animate() creates an Animation object targeting to the correct CSSPseudoElement object PASS animate() with pseudoElement parameter creates an Animation object for ::first-line
FAIL CSSPseudoElement.animate() creates an Animation object targeting to the correct CSSPseudoElement object for ::marker assert_true: expected true got false FAIL animate() with pseudoElement an Animation object targeting to the correct pseudo-element assert_equals: The returned Animation targets to the correct selector expected (string) "::before" but got (undefined) undefined
FAIL animate() with pseudoElement an Animation object targeting to the correct pseudo-element for ::marker assert_equals: The returned Animation targets to the correct selector expected (string) "::marker" but got (undefined) undefined
FAIL animate() with pseudoElement an Animation object targeting to the correct pseudo-element for ::first-line assert_equals: The returned Animation targets to the correct selector expected (string) "::first-line" but got (undefined) undefined
Harness: the test ran to completion. Harness: the test ran to completion.
...@@ -10,6 +10,11 @@ ...@@ -10,6 +10,11 @@
<script src="../../resources/keyframe-tests.js"></script> <script src="../../resources/keyframe-tests.js"></script>
<script src="../../resources/timing-utils.js"></script> <script src="../../resources/timing-utils.js"></script>
<script src="../../resources/timing-tests.js"></script> <script src="../../resources/timing-tests.js"></script>
<style>
.pseudo::before {content: '';}
.pseudo::after {content: '';}
.pseudo::marker {content: '';}
</style>
<body> <body>
<div id="log"></div> <div id="log"></div>
<iframe width="10" height="10" id="iframe"></iframe> <iframe width="10" height="10" id="iframe"></iframe>
...@@ -235,34 +240,59 @@ promise_test(async t => { ...@@ -235,34 +240,59 @@ promise_test(async t => {
assert_false(gotTransition, 'A transition should NOT have been triggered'); assert_false(gotTransition, 'A transition should NOT have been triggered');
}, 'Element.animate() does NOT trigger a style change event'); }, 'Element.animate() does NOT trigger a style change event');
// Tests on CSSPseudoElement // Tests on pseudo-elements
test(t => { test(t => {
const pseudoTarget = getPseudoElement(t, 'before'); const div = createDiv(t);
const anim = pseudoTarget.animate(null); div.classList.add('pseudo');
const anim = div.animate(null, {pseudoElement: '::before'});
assert_class_string(anim, 'Animation', 'The returned object is an Animation'); assert_class_string(anim, 'Animation', 'The returned object is an Animation');
}, 'CSSPseudoElement.animate() creates an Animation object'); }, 'animate() with pseudoElement parameter creates an Animation object');
test(t => { test(t => {
const pseudoTarget = getPseudoElement(t, 'marker'); const div = createDiv(t);
const anim = pseudoTarget.animate(null); div.classList.add('pseudo');
div.style.display = 'list-item';
const anim = div.animate(null, {pseudoElement: '::marker'});
assert_class_string(anim, 'Animation', 'The returned object is an Animation for ::marker'); assert_class_string(anim, 'Animation', 'The returned object is an Animation for ::marker');
}, 'CSSPseudoElement.animate() creates an Animation object for ::marker'); }, 'animate() with pseudoElement parameter creates an Animation object for ::marker');
test(t => {
const div = createDiv(t);
div.classList.add('pseudo');
div.textContent = 'foo';
const anim = div.animate(null, {pseudoElement: '::first-line'});
assert_class_string(anim, 'Animation', 'The returned object is an Animation for ::first-line');
}, 'animate() with pseudoElement parameter creates an Animation object for ::first-line');
test(t => { test(t => {
const pseudoTarget = getPseudoElement(t, 'before'); const div = createDiv(t);
const anim = pseudoTarget.animate(null); div.classList.add('pseudo');
assert_equals(anim.effect.target, pseudoTarget, const anim = div.animate(null, {pseudoElement: '::before'});
'The returned Animation targets to the correct object'); assert_equals(anim.effect.pseudoElement, '::before',
}, 'CSSPseudoElement.animate() creates an Animation object targeting ' + 'The returned Animation targets to the correct selector');
'to the correct CSSPseudoElement object'); }, 'animate() with pseudoElement an Animation object targeting ' +
'to the correct pseudo-element');
test(t => { test(t => {
const pseudoTarget = getPseudoElement(t, 'marker'); const div = createDiv(t);
const anim = pseudoTarget.animate(null); div.classList.add('pseudo');
assert_equals(anim.effect.target, pseudoTarget, div.style.display = 'list-item';
'The returned Animation targets to the correct object for ::marker'); const anim = div.animate(null, {pseudoElement: '::marker'});
}, 'CSSPseudoElement.animate() creates an Animation object targeting ' + assert_equals(anim.effect.pseudoElement, '::marker',
'to the correct CSSPseudoElement object for ::marker'); 'The returned Animation targets to the correct selector');
}, 'animate() with pseudoElement an Animation object targeting ' +
'to the correct pseudo-element for ::marker');
test(t => {
const div = createDiv(t);
div.classList.add('pseudo');
div.textContent = 'foo';
const anim = div.animate(null, {pseudoElement: '::first-line'});
assert_equals(anim.effect.pseudoElement, '::first-line',
'The returned Animation targets to the correct selector');
}, 'animate() with pseudoElement an Animation object targeting ' +
'to the correct pseudo-element for ::first-line');
</script> </script>
</body> </body>
...@@ -28,6 +28,8 @@ FAIL Treats display:contents in a display:none subtree as not rendered assert_th ...@@ -28,6 +28,8 @@ FAIL Treats display:contents in a display:none subtree as not rendered assert_th
FAIL Throws if the target effect is disconnected assert_throws: function "() => { FAIL Throws if the target effect is disconnected assert_throws: function "() => {
animation.commitStyles(); animation.commitStyles();
}" threw object "TypeError: animation.commitStyles is not a function" that is not a DOMException InvalidStateError: property "code" is equal to undefined, expected 11 }" threw object "TypeError: animation.commitStyles is not a function" that is not a DOMException InvalidStateError: property "code" is equal to undefined, expected 11
FAIL Checks the pseudo element condition before the not rendered condition Cannot read property 'remove' of undefined FAIL Checks the pseudo element condition before the not rendered condition assert_throws: function "() => {
animation.commitStyles();
}" threw object "TypeError: animation.commitStyles is not a function" that is not a DOMException NoModificationAllowedError: property "code" is equal to undefined, expected 7
Harness: the test ran to completion. Harness: the test ran to completion.
...@@ -5,6 +5,11 @@ ...@@ -5,6 +5,11 @@
<script src="/resources/testharness.js"></script> <script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script> <script src="/resources/testharnessreport.js"></script>
<script src="../../testcommon.js"></script> <script src="../../testcommon.js"></script>
<style>
.pseudo::before {content: '';}
.pseudo::after {content: '';}
.pseudo::marker {content: '';}
</style>
<body> <body>
<div id="log"></div> <div id="log"></div>
<script> <script>
...@@ -263,10 +268,12 @@ promise_test(async t => { ...@@ -263,10 +268,12 @@ promise_test(async t => {
}, 'Does NOT trigger mutation observers when the change to style is redundant'); }, 'Does NOT trigger mutation observers when the change to style is redundant');
test(t => { test(t => {
const pseudo = getPseudoElement(t, 'before');
const animation = pseudo.animate( const div = createDiv(t);
div.classList.add('pseudo');
const animation = div.animate(
{ opacity: 0 }, { opacity: 0 },
{ duration: 1, fill: 'forwards' } { duration: 1, fill: 'forwards', pseudoElement: '::before' }
); );
assert_throws('NoModificationAllowedError', () => { assert_throws('NoModificationAllowedError', () => {
...@@ -372,13 +379,14 @@ test(t => { ...@@ -372,13 +379,14 @@ test(t => {
}, 'Throws if the target effect is disconnected'); }, 'Throws if the target effect is disconnected');
test(t => { test(t => {
const pseudo = getPseudoElement(t, 'before'); const div = createDiv(t);
const animation = pseudo.animate( div.classList.add('pseudo');
const animation = div.animate(
{ opacity: 0 }, { opacity: 0 },
{ duration: 1, fill: 'forwards' } { duration: 1, fill: 'forwards', pseudoElement: '::before' }
); );
pseudo.element.remove(); div.remove();
assert_throws('NoModificationAllowedError', () => { assert_throws('NoModificationAllowedError', () => {
animation.commitStyles(); animation.commitStyles();
......
...@@ -87,23 +87,6 @@ function createStyle(test, rules, doc) { ...@@ -87,23 +87,6 @@ function createStyle(test, rules, doc) {
}); });
} }
// Create a pseudo element
function getPseudoElement(test, type) {
createStyle(test, { '@keyframes anim': '',
[`.pseudo::${type}`]: 'animation: anim 10s; ' +
'content: \'\';' });
const div = createDiv(test);
if (type == 'marker') {
div.style.display = 'list-item';
}
div.classList.add('pseudo');
const anims = document.getAnimations();
assert_true(anims.length >= 1);
const anim = anims[anims.length - 1];
anim.cancel();
return anim.effect.target;
}
// Cubic bezier with control points (0, 0), (x1, y1), (x2, y2), and (1, 1). // Cubic bezier with control points (0, 0), (x1, y1), (x2, y2), and (1, 1).
function cubicBezier(x1, y1, x2, y2) { function cubicBezier(x1, y1, x2, y2) {
const xForT = t => { const xForT = t => {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment