blob: e3bc5aaae5b7ac4d00cfdb7beb1fb4cfa3f21719 [file] [edit]
<!DOCTYPE html>
<html>
<head>
<script src="../../http/tests/inspector/resources/inspector-test.js"></script>
<script>
function test()
{
let suite = InspectorTest.createAsyncSuite("DOMNodeStyles.usedCSSVariables");
function addTestCase({name, description, selector, checkUsedCSSVariables})
{
suite.addTestCase({
name,
description,
async test() {
let documentNode = await WI.domManager.requestDocument();
let nodeId = await documentNode.querySelector(selector);
let domNode = await WI.domManager.nodeForId(nodeId);
InspectorTest.assert(domNode, `Should find DOM Node for selector '${selector}'.`);
let cssStyles = WI.cssManager.stylesForNode(domNode);
InspectorTest.assert(cssStyles, `Should find CSS Styles for DOM Node.`);
await cssStyles.refreshIfNeeded();
await checkUsedCSSVariables(cssStyles.usedCSSVariables, cssStyles.allCSSVariables);
},
});
}
addTestCase({
name: "DOMNodeStyles.usedCSSVariables.InheritedUsed",
description: "A used inherited variable is found in the set of used variables",
selector: "#used-inherited-variable",
checkUsedCSSVariables(usedCSSVariables) {
InspectorTest.expectEqual(usedCSSVariables.size, 1, "Set should contain one used variable");
InspectorTest.expectTrue(usedCSSVariables.has("--inherited-color"), "--inherited-color should be used");
},
});
addTestCase({
name: "DOMNodeStyles.usedCSSVariables.InheritedUsedReferenced",
description: "An inherited variable referenced by another used variable is found in the set of used variables",
selector: "#used-referenced-inherited-variable",
checkUsedCSSVariables(usedCSSVariables) {
InspectorTest.expectEqual(usedCSSVariables.size, 2, "Set should contain two used variables");
InspectorTest.expectTrue(usedCSSVariables.has("--inherited-color"), "--inherited-color should be used");
InspectorTest.expectTrue(usedCSSVariables.has("--color"), "--color should be used");
},
});
addTestCase({
name: "DOMNodeStyles.usedCSSVariables.InheritedNotUsed",
description: "Unused inherited variables are not found in the set of used variables",
selector: "#unused-inherited-variable",
checkUsedCSSVariables(usedCSSVariables) {
InspectorTest.expectEqual(usedCSSVariables.size, 1, "Set should contain one used variable");
InspectorTest.expectTrue(usedCSSVariables.has("--color"), "--color should be used");
InspectorTest.expectFalse(usedCSSVariables.has("--inherited-color"), "--inherited-color should not be used");
},
});
for (let [name, selector] of [["InheritedReverseOrder", "#used-reversed-inherited-variable-chain"], ["InheritedDifferentRules", "#used-inherited-variable-chain-across-rules"]]) {
addTestCase({
name: `DOMNodeStyles.usedCSSVariables.${name}`,
description: "Inherited variable dependencies are independent of declaration order",
selector,
checkUsedCSSVariables(usedCSSVariables) {
InspectorTest.expectEqual(usedCSSVariables.size, 3, "The full inherited dependency chain should be used");
for (let variableName of ["--theme-button-color", "--theme-accent-color", "--theme-base-color"])
InspectorTest.expectTrue(usedCSSVariables.has(variableName), `${variableName} should be used`);
InspectorTest.expectFalse(usedCSSVariables.has("--theme-unused-color"), "The unrelated inherited variable should remain unused");
},
});
}
addTestCase({
name: "DOMNodeStyles.usedCSSVariables.InheritedUnusedChain",
selector: "#unused-reversed-inherited-variable-chain",
checkUsedCSSVariables(usedCSSVariables) {
InspectorTest.expectEqual(usedCSSVariables.size, 0, "The unused inherited dependency chain should remain unused");
},
});
addTestCase({
name: "DOMNodeStyles.usedCSSVariables.InheritedCyclicChain",
selector: "#used-cyclic-inherited-variable-chain",
checkUsedCSSVariables(usedCSSVariables) {
InspectorTest.expectShallowEqual([...usedCSSVariables].sort(), ["--theme-cycle-a", "--theme-cycle-b"], "The inherited dependency cycle should include each variable once");
},
});
addTestCase({
name: "DOMNodeStyles.usedCSSVariables.InheritedUsedFunction",
description: "An inherited variable used in a function value is found in the set of used variables",
selector: "#used-inherited-variable-function",
checkUsedCSSVariables(usedCSSVariables) {
InspectorTest.expectEqual(usedCSSVariables.size, 1, "Set should contain one used variable");
InspectorTest.expectTrue(usedCSSVariables.has("--inherited-color"), "--inherited-color should be used");
},
});
addTestCase({
name: "DOMNodeStyles.usedCSSVariables.HighSpecificityUsed",
description: "A variable declared in a higher specificity rule but used in a lower specificity rule is found in the set of used variables",
selector: "#used-higher-specificity",
checkUsedCSSVariables(usedCSSVariables) {
InspectorTest.expectTrue(usedCSSVariables.has("--color"), "--color should be used");
},
});
addTestCase({
name: "DOMNodeStyles.usedCSSVariables.InheritedHighSpecificityUsed",
description: "An inherited variable declared in a higher specificity rule but used in a lower specificity rule on an inheritable property (`color`) is found in the set of used variables",
selector: "#used-higher-specificity-inheritable > p",
checkUsedCSSVariables(usedCSSVariables) {
InspectorTest.expectEqual(usedCSSVariables.size, 1, "Set should contain one used variable");
InspectorTest.expectTrue(usedCSSVariables.has("--color"), "--color should be used");
},
});
addTestCase({
name: "DOMNodeStyles.usedCSSVariables.InheritedHighSpecificityNotUsed",
description: "An inherited variable declared in a higher specificity rule but used in a lower specificity rule on a non-inheritable property (`background-color`) is not found in the set of used variables",
selector: "#unused-higher-specificity-non-inheritable > p",
checkUsedCSSVariables(usedCSSVariables) {
InspectorTest.expectFalse(usedCSSVariables.has("--color"), "--color should not be used");
},
});
for (let [name, selector] of [["PseudoElement", "#used-with-pseudo-element"], ["Keyframes", "#used-with-keyframes"]]) {
addTestCase({
name: `DOMNodeStyles.usedCSSVariables.${name}`,
description: "Processing pseudo elements or keyframes preserves the element's CSS variables",
selector,
checkUsedCSSVariables(usedCSSVariables, allCSSVariables) {
InspectorTest.expectEqual(usedCSSVariables.size, 1, "Set should contain one used variable");
InspectorTest.expectTrue(usedCSSVariables.has("--color"), "--color should be used");
InspectorTest.expectTrue(allCSSVariables.has("--color"), "--color should be available");
InspectorTest.expectTrue(allCSSVariables.has("--inherited-color"), "--inherited-color should be available");
InspectorTest.expectFalse(allCSSVariables.has("--pseudo-color"), "Pseudo element variables should not replace the element's variables");
},
});
}
addTestCase({
name: "DOMNodeStyles.usedCSSVariables.KeyframesInheritedReference",
description: "Variables referenced only by an element's keyframes remain used",
selector: "#used-only-in-keyframes",
async checkUsedCSSVariables(usedCSSVariables, allCSSVariables) {
InspectorTest.expectEqual(usedCSSVariables.size, 2, "Set should include the animation variable and its inherited dependency");
InspectorTest.expectTrue(usedCSSVariables.has("--animation-color"), "--animation-color should be used");
InspectorTest.expectTrue(usedCSSVariables.has("--inherited-color"), "--inherited-color should be used");
InspectorTest.expectTrue(allCSSVariables.has("--animation-color"), "--animation-color should be available");
let color = await InspectorTest.evaluateInPage('getComputedStyle(document.getElementById("used-only-in-keyframes")).color');
InspectorTest.expectEqual(color, "rgb(0, 128, 0)", "The animation should render the inherited variable value");
},
});
addTestCase({
name: "DOMNodeStyles.usedCSSVariables.KeyframeDeclaration",
description: "A variable declared by an element's keyframes remains available",
selector: "#defined-only-in-keyframes",
async checkUsedCSSVariables(usedCSSVariables, allCSSVariables) {
InspectorTest.expectTrue(usedCSSVariables.has("--keyframe-color"), "--keyframe-color should be used");
InspectorTest.expectTrue(allCSSVariables.has("--keyframe-color"), "--keyframe-color should be available");
let color = await InspectorTest.evaluateInPage('getComputedStyle(document.getElementById("defined-only-in-keyframes")).color');
InspectorTest.expectEqual(color, "rgb(0, 128, 0)", "The element should render the variable declared in keyframes");
},
});
suite.runTestCasesAndFinish();
}
</script>
<style>
html {
--inherited-color: green;
--animation-color: var(--inherited-color);
}
div#used-inherited-variable {
color: var(--inherited-color, red);
}
div#used-referenced-inherited-variable {
--color: var(--inherited-color);
color: var(--color, red);
}
#reversed-inherited-variable-chain {
--theme-base-color: green;
--theme-accent-color: var(--theme-base-color);
--theme-button-color: var(--theme-accent-color);
--theme-unused-color: red;
}
#used-reversed-inherited-variable-chain,
#used-inherited-variable-chain-across-rules {
background-color: var(--theme-button-color);
}
#inherited-variable-chain-across-rules {
--theme-base-color: green;
--theme-unused-color: red;
}
div.inherited-chain-middle {
--theme-accent-color: var(--theme-base-color);
}
.inherited-chain-lowest {
--theme-button-color: var(--theme-accent-color);
}
#cyclic-inherited-variable-chain {
--theme-cycle-a: var(--theme-cycle-b);
--theme-cycle-b: var(--theme-cycle-a);
}
#used-cyclic-inherited-variable-chain {
background-color: var(--theme-cycle-a, green);
}
div#unused-inherited-variable {
--color: green;
color: var(--color, red);
}
div#used-inherited-variable-function {
background: linear-gradient(90deg, var(--inherited-color, red), white);
}
div.used-lower-specificity {
background-color: var(--color, red);
}
div#used-higher-specificity {
--color: green;
}
div.used-lower-specificity-inheritable {
color: var(--color, red);
}
div#used-higher-specificity-inheritable {
--color: green;
}
div.unused-lower-specificity-non-inheritable {
background-color: var(--color, red);
}
div#unused-higher-specificity-non-inheritable {
--color: green;
}
div#used-with-pseudo-element,
div#used-with-keyframes {
--color: green;
color: var(--color);
}
div#used-with-pseudo-element::before {
content: "";
--pseudo-color: blue;
color: var(--pseudo-color);
}
div#used-with-keyframes {
animation: fade 1s infinite;
}
@keyframes fade {
from { opacity: 0; }
to { opacity: 1; }
}
#used-only-in-keyframes {
animation: inherited-variables 1s linear paused;
}
@keyframes inherited-variables {
from { color: var(--animation-color); }
to { color: var(--animation-color); }
}
#defined-only-in-keyframes {
animation: keyframe-variable 1s linear paused;
color: var(--keyframe-color);
}
@keyframes keyframe-variable {
from { --keyframe-color: green; }
to { --keyframe-color: green; }
}
</style>
</head>
<body onload="runTest();">
<p>Test for DOMNodeStyles.usedCSSVariables</p>
<div>
<div id="used-inherited-variable"></div>
<div id="used-referenced-inherited-variable"></div>
<div id="unused-inherited-variable"></div>
<div id="used-inherited-variable-function"></div>
<div id="used-with-pseudo-element"></div>
<div id="used-with-keyframes"></div>
<div id="used-only-in-keyframes"></div>
<div id="defined-only-in-keyframes"></div>
<div id="used-higher-specificity" class="used-lower-specificity"></div>
<div id="used-higher-specificity-inheritable" class="used-lower-specificity-inheritable">
<p></p>
</div>
<div id="unused-higher-specificity-non-inheritable" class="unused-lower-specificity-non-inheritable">
<p></p>
</div>
</div>
<div id="reversed-inherited-variable-chain">
<div id="used-reversed-inherited-variable-chain"></div>
<div id="unused-reversed-inherited-variable-chain"></div>
</div>
<div id="inherited-variable-chain-across-rules" class="inherited-chain-middle inherited-chain-lowest">
<div id="used-inherited-variable-chain-across-rules"></div>
</div>
<div id="cyclic-inherited-variable-chain">
<div id="used-cyclic-inherited-variable-chain"></div>
</div>
</body>
</html>