| <!DOCTYPE html> |
| <html> |
| <head> |
| <script src="../../http/tests/inspector/resources/inspector-test.js"></script> |
| <script> |
| function test() |
| { |
| let documentNode; |
| |
| async function nodeForSelector(selector) { |
| let nodeId = await WI.domManager.querySelector(documentNode.id, selector); |
| return WI.domManager.nodeForId(nodeId); |
| } |
| |
| function testNodeMatchesPath(node, message, {regular, full}) { |
| InspectorTest.expectEqual(WI.cssPath(node), regular, message); |
| if (full) { |
| let actual = WI.cssPath(node, {full: true}); |
| InspectorTest.assert(actual === full, `Full path ${actual} doesn't match expected ${full}.`); |
| } |
| } |
| |
| let suite = InspectorTest.createAsyncSuite("WI.cssPath"); |
| |
| suite.addTestCase({ |
| name: "WI.cssPath.TopLevelNode", |
| description: "Top level nodes like html, body, and head are unique.", |
| async test() { |
| let html = await nodeForSelector("html"); |
| testNodeMatchesPath(html, "HTML element should have simple selector 'html'.", { |
| regular: `html`, |
| full: `html`, |
| }); |
| |
| let body = await nodeForSelector("html > body"); |
| testNodeMatchesPath(body, "BODY element should have simple selector 'body'.", { |
| regular: `body`, |
| full: `html > body[onload="runTest()"]`, |
| }); |
| |
| let head = await nodeForSelector("html > head"); |
| testNodeMatchesPath(head, "HEAD element should have simple selector 'head'.", { |
| regular: `head`, |
| full: `html > head`, |
| }); |
| } |
| }); |
| |
| suite.addTestCase({ |
| name: "WI.cssPath.ElementWithID", |
| description: "Element with ID is unique (#id). Path does not need to go past it.", |
| async test() { |
| let test = await nodeForSelector("#id-test"); |
| testNodeMatchesPath(test, "Element with id should have simple selector '#id-test'.", { |
| regular: `#id-test`, |
| full: `html > body[onload="runTest()"] > div[style="visibility:hidden"] > div#id-test`, |
| }); |
| |
| let div = await nodeForSelector("#id-test > div"); |
| testNodeMatchesPath(div, "Element inside element with id should have path from id.", { |
| regular: `#id-test > div`, |
| full: `html > body[onload="runTest()"] > div[style="visibility:hidden"] > div#id-test > div`, |
| }); |
| } |
| }); |
| |
| suite.addTestCase({ |
| name: "WI.cssPath.InputElementFlair", |
| description: "Input elements include their type.", |
| async test() { |
| let input = await nodeForSelector("#input-test input"); |
| testNodeMatchesPath(input, "Input element should include type.", { |
| regular: `#input-test > input[type="password"]`, |
| full: `html > body[onload="runTest()"] > div[style="visibility:hidden"] > div#input-test > input[type="password"]`, |
| }); |
| } |
| }); |
| |
| suite.addTestCase({ |
| name: "WI.cssPath.UniqueTagName", |
| description: "Elements with unique tag name do not need nth-child.", |
| async test() { |
| let span = await nodeForSelector("#unique-tag-test > span"); |
| testNodeMatchesPath(span, "Elements with unique tag name should not need nth-child().", { |
| regular: `#unique-tag-test > span`, |
| full: `html > body[onload="runTest()"] > div[style="visibility:hidden"] > div#unique-tag-test > span`, |
| }); |
| } |
| }); |
| |
| suite.addTestCase({ |
| name: "WI.cssPath.NonUniqueTagName", |
| description: "Elements with non-unique tag name need nth-child.", |
| async test() { |
| let span = await nodeForSelector("#non-unique-tag-test > span ~ span"); |
| testNodeMatchesPath(span, "Elements with non-unique tag name should need nth-child().", { |
| regular: `#non-unique-tag-test > span:nth-child(3)`, |
| full: `html > body[onload="runTest()"] > div[style="visibility:hidden"] > div#non-unique-tag-test > span:nth-child(3)`, |
| }); |
| } |
| }); |
| |
| suite.addTestCase({ |
| name: "WI.cssPath.UniqueClassName", |
| description: "Elements with unique class names should include their class names.", |
| async test() { |
| let beta = await nodeForSelector("#unique-class-test > .beta"); |
| testNodeMatchesPath(beta, "Elements with unique class names should include their class names.", { |
| regular: `#unique-class-test > div.alpha.beta`, |
| full: `html > body[onload="runTest()"] > div[style="visibility:hidden"] > div#unique-class-test > div.alpha.beta`, |
| }); |
| } |
| }); |
| |
| suite.addTestCase({ |
| name: "WI.cssPath.NonUniqueClassName", |
| description: "Elements with non-unique class names should not include their class names.", |
| async test() { |
| let div = await nodeForSelector("#non-unique-class-test > div ~ div"); |
| testNodeMatchesPath(div, "Elements with non-unique class names should not include their class names.", { |
| regular: `#non-unique-class-test > div:nth-child(2)`, |
| full: `html > body[onload="runTest()"] > div[style="visibility:hidden"] > div#non-unique-class-test > div.alpha:nth-child(2)`, |
| }); |
| } |
| }); |
| |
| suite.addTestCase({ |
| name: "WI.cssPath.UniqueTagAndClassName", |
| description: "Elements with unique tag and class name just use tag for simplicity.", |
| async test() { |
| let alpha = await nodeForSelector("#unique-tag-and-class-test > .alpha"); |
| testNodeMatchesPath(alpha, "Elements with unique tag and class names should just have simple tag.", { |
| regular: `#unique-tag-and-class-test > div`, |
| full: `html > body[onload="runTest()"] > div[style="visibility:hidden"] > div#unique-tag-and-class-test > div.alpha`, |
| }); |
| } |
| }); |
| |
| suite.addTestCase({ |
| name: "WI.cssPath.DeepPath", |
| description: "Tests for element with complex path.", |
| async test() { |
| let small = await nodeForSelector("small"); |
| testNodeMatchesPath(small, "Should be able to create path for deep elements.", { |
| regular: `body > div > div.deep-path-test > ul > li > div:nth-child(4) > ul > li.active > a > small`, |
| full: `html > body[onload="runTest()"] > div[style="visibility:hidden"] > div.deep-path-test > ul > li > div:nth-child(4) > ul.list > li.active > a[href="#"] > small`, |
| }); |
| } |
| }); |
| |
| suite.addTestCase({ |
| name: "WI.cssPath.PseudoElement", |
| description: "For a pseudo element we should get the path of the parent and append the pseudo element selector.", |
| async test() { |
| let div = await nodeForSelector("#pseudo-element-test > div ~ div"); |
| |
| let pseudoElementBefore = div.beforePseudoElement(); |
| InspectorTest.assert(pseudoElementBefore); |
| testNodeMatchesPath(pseudoElementBefore, "Should be able to create path for ::before pseudo elements.", { |
| regular: `#pseudo-element-test > div:nth-child(3)::before`, |
| full: `html > body[onload="runTest()"] > div[style="visibility:hidden"] > div#pseudo-element-test > div:nth-child(3)::before`, |
| }); |
| |
| let pseudoElementAfter = div.afterPseudoElement(); |
| InspectorTest.assert(pseudoElementAfter); |
| testNodeMatchesPath(pseudoElementAfter, "Should be able to create path for ::after pseudo elements.", { |
| regular: `#pseudo-element-test > div:nth-child(3)::after`, |
| full: `html > body[onload="runTest()"] > div[style="visibility:hidden"] > div#pseudo-element-test > div:nth-child(3)::after`, |
| }); |
| } |
| }); |
| |
| // FIXME: Write tests for nodes inside a Shadow DOM Tree. |
| |
| WI.domManager.requestDocument((node) => { |
| documentNode = node; |
| suite.runTestCasesAndFinish(); |
| }); |
| } |
| </script> |
| </head> |
| <body onload="runTest()"> |
| <p>Test for WI.cssPath.</p> |
| <!-- If display:none pseudo elements are not created. --> |
| <div style="visibility:hidden"> |
| <div id="id-test"> |
| <div></div> |
| </div> |
| <div id="input-test"> |
| <input type="password"> |
| </div> |
| <div id="unique-tag-test"> |
| <div></div> |
| <span></span> |
| <div></div> |
| </div> |
| <div id="non-unique-tag-test"> |
| <div></div> |
| <span></span> |
| <span></span> |
| <div></div> |
| </div> |
| <div id="unique-class-test"> |
| <div class="alpha"></div> |
| <div class="alpha beta"></div> |
| <div class="alpha"></div> |
| </div> |
| <div id="non-unique-class-test"> |
| <div class="alpha"></div> |
| <div class="alpha"></div> |
| <div class="alpha"></div> |
| </div> |
| <div id="unique-tag-and-class-test"> |
| <div class="alpha"></div> |
| </div> |
| <div class="deep-path-test"> |
| <ul> |
| <li> |
| <h1></h1> |
| <div></div> |
| <div></div> |
| <div> |
| <ul class="list"> |
| <li></li> |
| <li class="active"><a href="#"><small></small></a></li> |
| <li></li> |
| </ul> |
| </div> |
| </li> |
| </ul> |
| </div> |
| <div id="pseudo-element-test"> |
| <style> |
| #pseudo-element-test > div~div::before { content: "before"; } |
| #pseudo-element-test > div~div::after { content: "after"; } |
| </style> |
| <div></div> |
| <div></div> |
| </div> |
| </div> |
| </body> |
| </html> |