"use strict"; const URL = MAIN_DOMAIN + "inspector-shadow.html"; add_task(async function () { info("Test that a shadow host has a shadow root"); const { walker } = await initInspectorFront(URL); const el = await walker.querySelector(walker.rootNode, "#empty"); const children = await walker.children(el); is(el.displayName, "test-empty", "#empty exists"); ok(el.isShadowHost, "#empty is a shadow host"); const shadowRoot = children.nodes[0]; ok(shadowRoot.isShadowRoot, "#empty has a shadow-root child"); is(children.nodes.length, 1, "#empty has no other children"); }); add_task(async function () { info("Test that a shadow host has its children too"); const { walker } = await initInspectorFront(URL); const el = await walker.querySelector(walker.rootNode, "#one-child"); const children = await walker.children(el); is( children.nodes.length, 2, "#one-child has two children " + "(shadow root + another child)" ); ok(children.nodes[0].isShadowRoot, "First child is a shadow-root"); is(children.nodes[1].displayName, "h1", "Second child is

"); }); add_task(async function () { info("Test that shadow-root has its children"); const { walker } = await initInspectorFront(URL); const el = await walker.querySelector(walker.rootNode, "#shadow-children"); ok(el.isShadowHost, "#shadow-children is a shadow host"); const children = await walker.children(el); ok( children.nodes.length === 1 && children.nodes[0].isShadowRoot, "#shadow-children has only one child and it's a shadow-root" ); const shadowRoot = children.nodes[0]; const shadowChildren = await walker.children(shadowRoot); is(shadowChildren.nodes.length, 2, "shadow-root has two children"); is(shadowChildren.nodes[0].displayName, "h1", "First child is

"); is(shadowChildren.nodes[1].displayName, "p", "Second child is

"); }); add_task(async function () { info("Test that shadow root has its children and slotted nodes"); const { walker } = await initInspectorFront(URL); const el = await walker.querySelector(walker.rootNode, "#named-slot"); ok(el.isShadowHost, "#named-slot is a shadow host"); const children = await walker.children(el); is(children.nodes.length, 2, "#named-slot has two children"); const shadowRoot = children.nodes[0]; ok(shadowRoot.isShadowRoot, "#named-slot has a shadow-root child"); const slotted = children.nodes[1]; is( slotted.getAttribute("slot"), "slot1", "#named-slot as a child that is slotted" ); const shadowChildren = await walker.children(shadowRoot); is( shadowChildren.nodes[0].displayName, "h1", "shadow-root first child is a regular

tag" ); is( shadowChildren.nodes[1].displayName, "slot", "shadow-root second child is a slot" ); const slottedChildren = await walker.children(shadowChildren.nodes[1]); is( slottedChildren.nodes[0], slotted, "The slot has the slotted node as a child" ); }); add_task(async function () { info("Test pseudoelements in shadow host"); const { walker } = await initInspectorFront(URL); const el = await walker.querySelector(walker.rootNode, "#host-pseudo"); const children = await walker.children(el); ok(children.nodes[0].isShadowRoot, "#host-pseudo 1st child is a shadow root"); ok( children.nodes[1].isBeforePseudoElement, "#host-pseudo 2nd child is ::before" ); ok( children.nodes[2].isAfterPseudoElement, "#host-pseudo 3rd child is ::after" ); }); add_task(async function () { info("Test pseudoelements in slotted nodes"); const { walker } = await initInspectorFront(URL); const el = await walker.querySelector(walker.rootNode, "#slot-pseudo"); const shadowRoot = (await walker.children(el)).nodes[0]; ok(shadowRoot.isShadowRoot, "#slot-pseudo has a shadow-root child"); const shadowChildren = await walker.children(shadowRoot); is(shadowChildren.nodes[1].displayName, "slot", "shadow-root has a slot"); const slottedChildren = await walker.children(shadowChildren.nodes[1]); ok(slottedChildren.nodes[0].isBeforePseudoElement, "slot has ::before"); ok( slottedChildren.nodes[slottedChildren.nodes.length - 1] .isAfterPseudoElement, "slot has ::after" ); }); add_task(async function () { info("Test open/closed modes in shadow roots"); const { walker } = await initInspectorFront(URL); const openEl = await walker.querySelector(walker.rootNode, "#mode-open"); const openShadowRoot = (await walker.children(openEl)).nodes[0]; const closedEl = await walker.querySelector(walker.rootNode, "#mode-closed"); const closedShadowRoot = (await walker.children(closedEl)).nodes[0]; is( openShadowRoot.shadowRootMode, "open", "#mode-open has a shadow root with open mode" ); is( closedShadowRoot.shadowRootMode, "closed", "#mode-closed has a shadow root with closed mode" ); }); add_task(async function () { info("Test that slotted inline text nodes appear in the Shadow DOM tree"); const { walker } = await initInspectorFront(URL); const el = await walker.querySelector(walker.rootNode, "#slot-inline-text"); const hostChildren = await walker.children(el); const originalSlot = hostChildren.nodes[1]; is( originalSlot.displayName, "#text", "Shadow host as a text node to be slotted" ); const shadowRoot = hostChildren.nodes[0]; const shadowChildren = await walker.children(shadowRoot); const slot = shadowChildren.nodes[0]; is(slot.displayName, "slot", "shadow-root has a slot child"); ok(!slot._form.inlineTextChild, "Slotted node is not an inline text"); const slotChildren = await walker.children(slot); const slotted = slotChildren.nodes[0]; is(slotted.displayName, "#text", "Slotted node is a text node"); is( slotted._form.nodeValue, originalSlot._form.nodeValue, "Slotted content is the same as original's" ); }); add_task(async function () { info("Test UA widgets when showAllAnonymousContent is true"); await SpecialPowers.pushPrefEnv({ set: [["devtools.inspector.showAllAnonymousContent", true]], }); const { walker } = await initInspectorFront(URL); let el = await walker.querySelector(walker.rootNode, "#video-controls"); let hostChildren = await walker.children(el); is(hostChildren.nodes.length, 3, "#video-controls tag has 3 children"); const shadowRoot = hostChildren.nodes[0]; ok(shadowRoot.isShadowRoot, "#video-controls has a shadow-root child"); el = await walker.querySelector( walker.rootNode, "#video-controls-with-children" ); hostChildren = await walker.children(el); is( hostChildren.nodes.length, 4, "#video-controls-with-children has 4 children" ); }); add_task(async function () { info("Test UA widgets when showAllAnonymousContent is false"); await SpecialPowers.pushPrefEnv({ set: [["devtools.inspector.showAllAnonymousContent", false]], }); const { walker } = await initInspectorFront(URL); let el = await walker.querySelector(walker.rootNode, "#video-controls"); let hostChildren = await walker.children(el); is(hostChildren.nodes.length, 0, "#video-controls tag has no children"); el = await walker.querySelector( walker.rootNode, "#video-controls-with-children" ); hostChildren = await walker.children(el); is( hostChildren.nodes.length, 1, "#video-controls-with-children has one child" ); });