browser_rules_selector-highlighter_02.js (3542B)
1 /* Any copyright is dedicated to the Public Domain. 2 http://creativecommons.org/publicdomain/zero/1.0/ */ 3 4 "use strict"; 5 6 // Test that the selector highlighter is shown when clicking on a selector icon 7 // in the rule-view 8 9 const TEST_URI = ` 10 <style type="text/css"> 11 body { 12 background: red; 13 } 14 p { 15 color: white; 16 } 17 18 @scope (.scope-root) to (.scope-limit) { 19 .b { 20 background-color: hotpink; 21 } 22 } 23 24 :where(.b) { 25 background-color: gold; 26 } 27 </style> 28 <p>Testing the selector highlighter</p> 29 <aside class="for-scope"> 30 <div class="scope-root"> 31 <article class="b in-scope">article in scope</article> 32 <h2 class="b in-scope">h2 in scope</h2> 33 <div class="scope-limit"> 34 <code class="b outside-scope">code after scope limit</code> 35 </div> 36 </div> 37 <section class="b outside-scope">section outside scope</section> 38 </aside> 39 `; 40 41 add_task(async function () { 42 await pushPref("layout.css.at-scope.enabled", true); 43 44 await addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI)); 45 const { inspector, view } = await openRuleView(); 46 let data; 47 48 info("Clicking once on the body selector highlighter icon"); 49 data = await clickSelectorIcon(view, "body"); 50 ok(data.isShown, "The highlighter is shown"); 51 52 info("Clicking once again on the body selector highlighter icon"); 53 data = await clickSelectorIcon(view, "body"); 54 ok(!data.isShown, "The highlighter is hidden"); 55 56 info("Checking that the right NodeFront reference and options are passed"); 57 await selectNode("p", inspector); 58 data = await clickSelectorIcon(view, "p"); 59 60 is( 61 data.nodeFront.tagName, 62 "P", 63 "The right NodeFront is passed to the highlighter" 64 ); 65 is( 66 data.options.selector, 67 "p", 68 "The right selector option is passed to the highlighter" 69 ); 70 info("Hide the highlighter for the `p` selector"); 71 await clickSelectorIcon(view, "p"); 72 73 info("Check that the highlighter works for rules in @scope"); 74 await selectNode("article.in-scope", inspector); 75 76 await clickSelectorIcon(view, ".b"); 77 78 // Here we want to check that the selector highlighter is shown for article.b.in-scope and 79 // h2.b.in-scope, but not code.b.outside-scope, nor section.b.outside-scope. 80 // The event we get from the highlighter doesn't really indicate which elements the highlighter 81 // is shown for, so we need to check the highlighter markup directly 82 await SpecialPowers.spawn(gBrowser.selectedBrowser, [], () => { 83 const doc = content.document; 84 85 // Highlighters are rendered in the shadow DOM, let's get the shadow roots first 86 const roots = doc.getConnectedShadowRoots(); 87 const highlightedInfobarContent = roots 88 .map( 89 root => 90 root.querySelector( 91 ".highlighter-container.box-model #box-model-infobar-container" 92 )?.textContent 93 ) 94 .filter(text => !!text) 95 // The order of highlighter elements in the DOM tree isn't guaranteed, 96 // let's sort the selector texts. 97 .sort(); 98 99 is( 100 highlightedInfobarContent.length, 101 2, 102 "2 selector highlighters are displayed" 103 ); 104 if (highlightedInfobarContent.length != 2) { 105 return; 106 } 107 108 is( 109 highlightedInfobarContent[0], 110 "article.b.in-scope", 111 "The first highlighter is displayed for the first node in scope" 112 ); 113 114 is( 115 highlightedInfobarContent[1], 116 "h2.b.in-scope", 117 "The second highlighter is displayed for the second node in scope" 118 ); 119 }); 120 });