| <!DOCTYPE html> |
| <html> |
| <head> |
| <script src="../../http/tests/inspector/resources/inspector-test.js"></script> |
| <script> |
| function test() { |
| let nodeStyles = null; |
| |
| let suite = InspectorTest.createAsyncSuite("CSSProperty"); |
| |
| suite.addTestCase({ |
| name: "CSSProperty.NameCount", |
| description: "Ensure that the name counts are being tracked.", |
| async test() { |
| InspectorTest.expectGreaterThanOrEqual(WI.CSSProperty._cachedNameCounts["display"], 2, `"display" should have at least 2 counts.`); |
| InspectorTest.expectGreaterThanOrEqual(WI.CSSProperty._cachedNameCounts["background-repeat"], 1, `"background-repeat" should have at least 1 count.`); |
| InspectorTest.expectThat(!("background-repeat-x" in WI.CSSProperty._cachedNameCounts), `"background-repeat-x" should not be counted.`); |
| InspectorTest.expectThat(!("background-repeat-y" in WI.CSSProperty._cachedNameCounts), `"background-repeat-y" should not be counted.`); |
| InspectorTest.expectThat(!("background-repeat-invalid" in WI.CSSProperty._cachedNameCounts), `"background-repeat-invalid" should not be counted.`); |
| |
| const counts = [99, 1, 100, 0, 101, 150, 50, 200]; |
| let seenProperty = (count) => `Fake Property ${count} Seen`; |
| let unseenProperty = (count) => `Fake Property ${count} Unseen`; |
| for (const count of counts) |
| WI.CSSProperty._cachedNameCounts[seenProperty(count)] = count; |
| InspectorTest.json(counts.flatMap((count) => [unseenProperty(count), seenProperty(count)]).sort(WI.CSSProperty.sortByPropertyNameUsageCount)) |
| for (const count of counts) |
| delete WI.CSSProperty._cachedNameCounts[seenProperty(count)]; |
| } |
| }); |
| |
| suite.addTestCase({ |
| name: "CSSProperty.prototype.get valid", |
| description: "Ensure valid, invalid, and internal-only have correct valid state.", |
| test(resolve, reject) { |
| for (let rule of nodeStyles.matchedRules) { |
| if (rule.selectorText !== "div#x") |
| continue; |
| |
| for (let property of rule.style.enabledProperties) { |
| switch (property.name) { |
| case "background-repeat": |
| InspectorTest.expectThat(property.valid, `"${property.name}" is a valid property.`); |
| break; |
| case "background-repeat-x": |
| case "background-repeat-y": |
| case "background-repeat-invalid": |
| InspectorTest.expectFalse(property.valid, `"${property.name}" is an invalid property.`); |
| break; |
| } |
| } |
| } |
| |
| resolve(); |
| } |
| }); |
| |
| suite.addTestCase({ |
| name: "CSSProperty.prototype.get anonymous", |
| description: "Ensure valid, invalid, and internal-only have correct anonymous state.", |
| test(resolve, reject) { |
| for (let rule of nodeStyles.matchedRules) { |
| if (rule.selectorText !== "div#x") |
| continue; |
| |
| for (let property of rule.style.enabledProperties) { |
| switch (property.name) { |
| case "background-repeat": |
| case "background-repeat-x": |
| case "background-repeat-invalid": |
| InspectorTest.expectFalse(property.anonymous, `"${property.name}" is not an anonymous CSS property.`); |
| break; |
| case "background-repeat-y": |
| InspectorTest.expectThat(property.anonymous, `"${property.name}" is an anonymous CSS property.`); |
| break; |
| } |
| } |
| } |
| |
| resolve(); |
| } |
| }); |
| |
| suite.addTestCase({ |
| name: "CSSProperty.prototype.get implicit", |
| description: "Ensure valid, invalid, and internal-only have correct implicit state.", |
| test(resolve, reject) { |
| for (let rule of nodeStyles.matchedRules) { |
| if (rule.selectorText !== "div#x") |
| continue; |
| |
| for (let property of rule.style.enabledProperties) { |
| switch (property.name) { |
| case "background-repeat": |
| case "background-repeat-x": |
| case "background-repeat-invalid": |
| InspectorTest.expectFalse(property.implicit, `"${property.name}" is not an implicit CSS property.`); |
| break; |
| case "background-repeat-y": |
| InspectorTest.expectThat(property.implicit, `"${property.name}" is an implicit CSS property.`); |
| break; |
| } |
| } |
| } |
| |
| resolve(); |
| } |
| }); |
| |
| suite.addTestCase({ |
| name: "CSSProperty.prototype.get value", |
| description: "Ensure valid, invalid, and internal-only have correct value.", |
| test(resolve, reject) { |
| for (let rule of nodeStyles.matchedRules) { |
| if (rule.selectorText !== "div#x") |
| continue; |
| |
| for (let property of rule.style.enabledProperties) { |
| switch (property.name) { |
| case "background-repeat": |
| case "background-repeat-x": |
| case "background-repeat-y": |
| case "background-repeat-invalid": |
| InspectorTest.expectEqual(property.value, "repeat", `"${property.name}" has the value "repeat".`); |
| break; |
| } |
| } |
| } |
| |
| resolve(); |
| } |
| }); |
| |
| suite.addTestCase({ |
| name: "CSSProperty.prototype.get enabled", |
| description: "Ensure valid, invalid, and internal-only have correct enabled state.", |
| test(resolve, reject) { |
| for (let rule of nodeStyles.matchedRules) { |
| if (rule.selectorText !== "div#x") |
| continue; |
| |
| for (let property of rule.style.properties) { |
| switch (property.name) { |
| case "background-repeat": |
| case "background-repeat-x": |
| case "background-repeat-y": |
| case "background-repeat-invalid": |
| InspectorTest.expectThat(property.enabled, `"${property.name}" is enabled.`); |
| break; |
| case "background-color": |
| InspectorTest.expectThat(!property.enabled, `"${property.name}" is disabled.`); |
| break; |
| } |
| } |
| } |
| |
| resolve(); |
| } |
| }); |
| |
| suite.addTestCase({ |
| name: "CSSProperty.prototype.get attached", |
| description: "Ensure valid, invalid, and internal-only have correct attached state.", |
| test(resolve, reject) { |
| for (let rule of nodeStyles.matchedRules) { |
| if (rule.selectorText !== "div#x") |
| continue; |
| |
| for (let property of rule.style.properties) { |
| switch (property.name) { |
| case "background-repeat": |
| case "background-repeat-x": |
| case "background-repeat-y": |
| case "background-repeat-invalid": |
| InspectorTest.expectThat(property.attached, `"${property.name}" is attached.`); |
| break; |
| case "background-color": |
| InspectorTest.expectThat(!property.attached, `"${property.name}" is detached.`); |
| break; |
| } |
| } |
| } |
| |
| resolve(); |
| } |
| }); |
| |
| suite.addTestCase({ |
| name: "CSSProperty.prototype.get text", |
| description: "Ensure valid, invalid, and internal-only have correct text.", |
| test(resolve, reject) { |
| for (let rule of nodeStyles.matchedRules) { |
| if (rule.selectorText !== "div#x") |
| continue; |
| |
| // It is necessary to use "_text" because the public "text" getter will attempt to |
| // synthesize a value for the CSSProperty if it is falsy. This is used for cases |
| // where a shorthand property is written in the style, since the longhand properties |
| // (with corresponding values) are still sent to the frontend. |
| for (let property of rule.style.enabledProperties) { |
| switch (property.name) { |
| case "background-repeat": |
| InspectorTest.expectEqual(property.text, "background-repeat: repeat;", `"${property.name}" has the text "background-repeat: repeat;".`); |
| InspectorTest.expectEqual(property._text, "background-repeat: repeat;", `"${property.name}" has the _text (private) "background-repeat: repeat;".`); |
| break; |
| case "background-repeat-x": |
| InspectorTest.expectEqual(property.text, "background-repeat-x: repeat;", `"${property.name}" has the text "background-repeat-x: repeat;".`); |
| InspectorTest.expectEqual(property._text, "background-repeat-x: repeat;", `"${property.name}" has the _text (private) "background-repeat-x: repeat;".`); |
| break; |
| case "background-repeat-y": |
| InspectorTest.expectEqual(property.text, "", `"${property.name}" has the text "".`); |
| InspectorTest.expectEqual(property._text, "", `"${property.name}" has the _text (private) "".`); |
| break; |
| case "background-repeat-invalid": |
| InspectorTest.expectEqual(property.text, "background-repeat-invalid: repeat;", `"${property.name}" has the text "background-repeat-invalid: repeat;".`); |
| InspectorTest.expectEqual(property._text, "background-repeat-invalid: repeat;", `"${property.name}" has the _text (private) "background-repeat-invalid: repeat;".`); |
| break; |
| } |
| } |
| } |
| |
| resolve(); |
| } |
| }); |
| |
| suite.addTestCase({ |
| name: "CSSProperty.prototype.remove", |
| description: "Ensure remove method removes a property from an array of properties.", |
| test(resolve, reject) { |
| for (let rule of nodeStyles.matchedRules) { |
| if (rule.selectorText !== "div#x") |
| continue; |
| |
| let propertiesLength = rule.style.properties.length; |
| let firstProperty = rule.style.properties[0]; |
| let secondProperty = rule.style.properties[1]; |
| |
| rule.style.properties[0].remove(); |
| |
| InspectorTest.expectEqual(rule.style.properties.length, propertiesLength - 1, "The removed property should no longer be in properties array."); |
| InspectorTest.expectEqual(rule.style.properties[0], secondProperty, "The second property should shift and become the first."); |
| } |
| |
| resolve(); |
| } |
| }); |
| |
| WI.domManager.requestDocument((documentNode) => { |
| documentNode.querySelector("div#x", (contentNodeId) => { |
| if (contentNodeId) { |
| let domNode = WI.domManager.nodeForId(contentNodeId); |
| nodeStyles = WI.cssManager.stylesForNode(domNode); |
| |
| if (nodeStyles.needsRefresh) { |
| nodeStyles.singleFireEventListener(WI.DOMNodeStyles.Event.Refreshed, (event) => { |
| suite.runTestCasesAndFinish() |
| }); |
| } else |
| suite.runTestCasesAndFinish(); |
| } else { |
| InspectorTest.fail("DOM node not found."); |
| InspectorTest.completeTest(); |
| } |
| }); |
| }); |
| } |
| </script> |
| </head> |
| <body onload="runTest()"> |
| <p>Testing methods of CSSProperty.</p> |
| |
| <style> |
| div#x { |
| display: initial; |
| display: initial; |
| background-repeat: repeat; |
| background-repeat-x: repeat; |
| background-repeat-invalid: repeat; |
| /* background-color: black; */ |
| /* Not a CSS property */ |
| /* foo:bar; foo:baz; */ |
| } |
| </style> |
| <div id="x"></div> |
| </body> |
| </html> |