browser_inspector-shadow.js (7411B)
1 "use strict"; 2 3 const URL = MAIN_DOMAIN + "inspector-shadow.html"; 4 5 add_task(async function () { 6 info("Test that a shadow host has a shadow root"); 7 const { walker } = await initInspectorFront(URL); 8 9 const el = await walker.querySelector(walker.rootNode, "#empty"); 10 const children = await walker.children(el); 11 12 is(el.displayName, "test-empty", "#empty exists"); 13 ok(el.isShadowHost, "#empty is a shadow host"); 14 15 const shadowRoot = children.nodes[0]; 16 ok(shadowRoot.isShadowRoot, "#empty has a shadow-root child"); 17 is(children.nodes.length, 1, "#empty has no other children"); 18 }); 19 20 add_task(async function () { 21 info("Test that a shadow host has its children too"); 22 const { walker } = await initInspectorFront(URL); 23 24 const el = await walker.querySelector(walker.rootNode, "#one-child"); 25 const children = await walker.children(el); 26 27 is( 28 children.nodes.length, 29 2, 30 "#one-child has two children " + "(shadow root + another child)" 31 ); 32 ok(children.nodes[0].isShadowRoot, "First child is a shadow-root"); 33 is(children.nodes[1].displayName, "h1", "Second child is <h1>"); 34 }); 35 36 add_task(async function () { 37 info("Test that shadow-root has its children"); 38 const { walker } = await initInspectorFront(URL); 39 40 const el = await walker.querySelector(walker.rootNode, "#shadow-children"); 41 ok(el.isShadowHost, "#shadow-children is a shadow host"); 42 43 const children = await walker.children(el); 44 ok( 45 children.nodes.length === 1 && children.nodes[0].isShadowRoot, 46 "#shadow-children has only one child and it's a shadow-root" 47 ); 48 49 const shadowRoot = children.nodes[0]; 50 const shadowChildren = await walker.children(shadowRoot); 51 is(shadowChildren.nodes.length, 2, "shadow-root has two children"); 52 is(shadowChildren.nodes[0].displayName, "h1", "First child is <h1>"); 53 is(shadowChildren.nodes[1].displayName, "p", "Second child is <p>"); 54 }); 55 56 add_task(async function () { 57 info("Test that shadow root has its children and slotted nodes"); 58 const { walker } = await initInspectorFront(URL); 59 60 const el = await walker.querySelector(walker.rootNode, "#named-slot"); 61 ok(el.isShadowHost, "#named-slot is a shadow host"); 62 63 const children = await walker.children(el); 64 is(children.nodes.length, 2, "#named-slot has two children"); 65 const shadowRoot = children.nodes[0]; 66 ok(shadowRoot.isShadowRoot, "#named-slot has a shadow-root child"); 67 68 const slotted = children.nodes[1]; 69 is( 70 slotted.getAttribute("slot"), 71 "slot1", 72 "#named-slot as a child that is slotted" 73 ); 74 75 const shadowChildren = await walker.children(shadowRoot); 76 is( 77 shadowChildren.nodes[0].displayName, 78 "h1", 79 "shadow-root first child is a regular <h1> tag" 80 ); 81 is( 82 shadowChildren.nodes[1].displayName, 83 "slot", 84 "shadow-root second child is a slot" 85 ); 86 87 const slottedChildren = await walker.children(shadowChildren.nodes[1]); 88 is( 89 slottedChildren.nodes[0], 90 slotted, 91 "The slot has the slotted node as a child" 92 ); 93 }); 94 95 add_task(async function () { 96 info("Test pseudoelements in shadow host"); 97 const { walker } = await initInspectorFront(URL); 98 99 const el = await walker.querySelector(walker.rootNode, "#host-pseudo"); 100 const children = await walker.children(el); 101 102 ok(children.nodes[0].isShadowRoot, "#host-pseudo 1st child is a shadow root"); 103 is( 104 children.nodes[1].displayName, 105 "::before", 106 "#host-pseudo 2nd child is ::before" 107 ); 108 is( 109 children.nodes[2].displayName, 110 "::after", 111 "#host-pseudo 3rd child is ::after" 112 ); 113 }); 114 115 add_task(async function () { 116 info("Test pseudoelements in slotted nodes"); 117 const { walker } = await initInspectorFront(URL); 118 119 const el = await walker.querySelector(walker.rootNode, "#slot-pseudo"); 120 const shadowRoot = (await walker.children(el)).nodes[0]; 121 ok(shadowRoot.isShadowRoot, "#slot-pseudo has a shadow-root child"); 122 123 const shadowChildren = await walker.children(shadowRoot); 124 is(shadowChildren.nodes[1].displayName, "slot", "shadow-root has a slot"); 125 126 const slottedChildren = await walker.children(shadowChildren.nodes[1]); 127 is(slottedChildren.nodes[0].displayName, "::before", "slot has ::before"); 128 is(slottedChildren.nodes.at(-1).displayName, "::after", "slot has ::after"); 129 }); 130 131 add_task(async function () { 132 info("Test open/closed modes in shadow roots"); 133 const { walker } = await initInspectorFront(URL); 134 135 const openEl = await walker.querySelector(walker.rootNode, "#mode-open"); 136 const openShadowRoot = (await walker.children(openEl)).nodes[0]; 137 const closedEl = await walker.querySelector(walker.rootNode, "#mode-closed"); 138 const closedShadowRoot = (await walker.children(closedEl)).nodes[0]; 139 140 is( 141 openShadowRoot.shadowRootMode, 142 "open", 143 "#mode-open has a shadow root with open mode" 144 ); 145 is( 146 closedShadowRoot.shadowRootMode, 147 "closed", 148 "#mode-closed has a shadow root with closed mode" 149 ); 150 }); 151 152 add_task(async function () { 153 info("Test that slotted inline text nodes appear in the Shadow DOM tree"); 154 const { walker } = await initInspectorFront(URL); 155 156 const el = await walker.querySelector(walker.rootNode, "#slot-inline-text"); 157 const hostChildren = await walker.children(el); 158 const originalSlot = hostChildren.nodes[1]; 159 is( 160 originalSlot.displayName, 161 "#text", 162 "Shadow host as a text node to be slotted" 163 ); 164 165 const shadowRoot = hostChildren.nodes[0]; 166 const shadowChildren = await walker.children(shadowRoot); 167 const slot = shadowChildren.nodes[0]; 168 is(slot.displayName, "slot", "shadow-root has a slot child"); 169 ok(!slot._form.inlineTextChild, "Slotted node is not an inline text"); 170 171 const slotChildren = await walker.children(slot); 172 const slotted = slotChildren.nodes[0]; 173 is(slotted.displayName, "#text", "Slotted node is a text node"); 174 is( 175 slotted._form.nodeValue, 176 originalSlot._form.nodeValue, 177 "Slotted content is the same as original's" 178 ); 179 }); 180 181 add_task(async function () { 182 info("Test UA widgets when showAllAnonymousContent is true"); 183 await SpecialPowers.pushPrefEnv({ 184 set: [["devtools.inspector.showAllAnonymousContent", true]], 185 }); 186 187 const { walker } = await initInspectorFront(URL); 188 189 let el = await walker.querySelector(walker.rootNode, "#video-controls"); 190 let hostChildren = await walker.children(el); 191 is(hostChildren.nodes.length, 3, "#video-controls tag has 3 children"); 192 const shadowRoot = hostChildren.nodes[0]; 193 ok(shadowRoot.isShadowRoot, "#video-controls has a shadow-root child"); 194 195 el = await walker.querySelector( 196 walker.rootNode, 197 "#video-controls-with-children" 198 ); 199 hostChildren = await walker.children(el); 200 is( 201 hostChildren.nodes.length, 202 4, 203 "#video-controls-with-children has 4 children" 204 ); 205 }); 206 207 add_task(async function () { 208 info("Test UA widgets when showAllAnonymousContent is false"); 209 await SpecialPowers.pushPrefEnv({ 210 set: [["devtools.inspector.showAllAnonymousContent", false]], 211 }); 212 213 const { walker } = await initInspectorFront(URL); 214 215 let el = await walker.querySelector(walker.rootNode, "#video-controls"); 216 let hostChildren = await walker.children(el); 217 is(hostChildren.nodes.length, 0, "#video-controls tag has no children"); 218 219 el = await walker.querySelector( 220 walker.rootNode, 221 "#video-controls-with-children" 222 ); 223 hostChildren = await walker.children(el); 224 is( 225 hostChildren.nodes.length, 226 1, 227 "#video-controls-with-children has one child" 228 ); 229 });