diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
commit | 26a029d407be480d791972afb5975cf62c9360a6 (patch) | |
tree | f435a8308119effd964b339f76abb83a57c29483 /devtools/client/inspector/rules/test/browser_rules_container-queries.js | |
parent | Initial commit. (diff) | |
download | firefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz firefox-26a029d407be480d791972afb5975cf62c9360a6.zip |
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'devtools/client/inspector/rules/test/browser_rules_container-queries.js')
-rw-r--r-- | devtools/client/inspector/rules/test/browser_rules_container-queries.js | 321 |
1 files changed, 321 insertions, 0 deletions
diff --git a/devtools/client/inspector/rules/test/browser_rules_container-queries.js b/devtools/client/inspector/rules/test/browser_rules_container-queries.js new file mode 100644 index 0000000000..1a1857be05 --- /dev/null +++ b/devtools/client/inspector/rules/test/browser_rules_container-queries.js @@ -0,0 +1,321 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +// Test that the rule-view content is correct when the page defines container queries. +const TEST_URI = ` + <!DOCTYPE html> + <style type="text/css"> + body { + container: mycontainer / size; + } + + section { + container: mycontainer / inline-size; + } + + @container (width > 0px) { + h1, [test-hint="nocontainername"]{ + outline-color: chartreuse; + } + } + + @container unknowncontainer (min-width: 2vw) { + h1, [test-hint="unknowncontainer"] { + border-color: salmon; + } + } + + @container mycontainer (1px < width < 10000px) { + h1, [test-hint="container"] { + color: tomato; + } + + section, [test-hint="container-duplicate-name--body"] { + color: gold; + } + + div, [test-hint="container-duplicate-name--section"] { + color: salmon; + } + } + </style> + <body id=myBody class="a-container test"> + <h1>Hello @container!</h1> + <section> + <div> + <h2>You rock</h2> + </div> + </section> + </body> +`; + +add_task(async function () { + await pushPref("layout.css.container-queries.enabled", true); + + await addTab( + "https://example.com/document-builder.sjs?html=" + + encodeURIComponent(TEST_URI) + ); + const { inspector, view } = await openRuleView(); + + await selectNode("h1", inspector); + assertContainerQueryData(view, [ + { selector: "element", ancestorRulesData: null }, + { + selector: `h1, [test-hint="container"]`, + ancestorRulesData: ["@container mycontainer (1px < width < 10000px) {"], + }, + { + selector: `h1, [test-hint="nocontainername"]`, + ancestorRulesData: ["@container (width > 0px) {"], + }, + ]); + + info("Check that the query container tooltip works as expected"); + // Retrieve query containers sizes + const { bodyInlineSize, bodyBlockSize, sectionInlineSize } = + await SpecialPowers.spawn(gBrowser.selectedBrowser, [], () => { + const body = content.document.body; + const section = content.document.querySelector("section"); + return { + bodyInlineSize: content.getComputedStyle(body).inlineSize, + bodyBlockSize: content.getComputedStyle(body).blockSize, + sectionInlineSize: content.getComputedStyle(section).inlineSize, + }; + }); + + await assertQueryContainerTooltip({ + inspector, + view, + ruleIndex: 1, + expectedHeaderText: "<body#myBody.a-container.test>", + expectedBodyText: [ + "container-type: size", + `inline-size: ${bodyInlineSize}`, + `block-size: ${bodyBlockSize}`, + ], + }); + + info("Check that the 'jump to container' button works as expected"); + await assertJumpToContainerButton(inspector, view, 1, "body"); + + info("Check that inherited rules display container query data as expected"); + await selectNode("h2", inspector); + + assertContainerQueryData(view, [ + { selector: "element", ancestorRulesData: null }, + { + selector: `div, [test-hint="container-duplicate-name--section"]`, + ancestorRulesData: ["@container mycontainer (1px < width < 10000px) {"], + }, + { + selector: `section, [test-hint="container-duplicate-name--body"]`, + ancestorRulesData: ["@container mycontainer (1px < width < 10000px) {"], + }, + ]); + + info( + "Check that the query container tooltip works as expected for inherited rules as well" + ); + await assertQueryContainerTooltip({ + inspector, + view, + ruleIndex: 1, + expectedHeaderText: "<section>", + expectedBodyText: [ + "container-type: inline-size", + `inline-size: ${sectionInlineSize}`, + ], + }); + await assertQueryContainerTooltip({ + inspector, + view, + ruleIndex: 2, + expectedHeaderText: "<body#myBody.a-container.test>", + expectedBodyText: [ + "container-type: size", + `inline-size: ${bodyInlineSize}`, + `block-size: ${bodyBlockSize}`, + ], + }); + + info( + "Check that the 'jump to container' button works as expected for inherited rules" + ); + await assertJumpToContainerButton(inspector, view, 1, "section"); + + await selectNode("h2", inspector); + await assertJumpToContainerButton(inspector, view, 2, "body"); +}); + +function assertContainerQueryData(view, expectedRules) { + const rulesInView = Array.from( + view.element.querySelectorAll(".ruleview-rule") + ); + + is( + rulesInView.length, + expectedRules.length, + "All expected rules are displayed" + ); + + for (let i = 0; i < expectedRules.length; i++) { + const expectedRule = expectedRules[i]; + info(`Checking rule #${i}: ${expectedRule.selector}`); + + const selector = rulesInView[i].querySelector( + ".ruleview-selectors-container" + ).innerText; + is(selector, expectedRule.selector, `Expected selector for ${selector}`); + + const ancestorDataEl = getRuleViewAncestorRulesDataElementByIndex(view, i); + + if (expectedRule.ancestorRulesData == null) { + is( + ancestorDataEl, + null, + `No ancestor rules data displayed for ${selector}` + ); + } else { + is( + ancestorDataEl?.innerText, + expectedRule.ancestorRulesData.join("\n"), + `Expected ancestor rules data displayed for ${selector}` + ); + Assert.notStrictEqual( + ancestorDataEl.querySelector(".container-query .open-inspector"), + null, + "An icon is displayed to select the container in the markup view" + ); + } + } +} + +async function assertJumpToContainerButton( + inspector, + view, + ruleIndex, + expectedSelectedNodeAfterClick +) { + const selectContainerButton = getRuleViewAncestorRulesDataElementByIndex( + view, + ruleIndex + ).querySelector(".open-inspector"); + + // Ensure that the button can be targetted from EventUtils. + selectContainerButton.scrollIntoView(); + + const { waitForHighlighterTypeShown, waitForHighlighterTypeHidden } = + getHighlighterTestHelpers(inspector); + + const onNodeHighlight = waitForHighlighterTypeShown( + inspector.highlighters.TYPES.BOXMODEL + ); + EventUtils.synthesizeMouseAtCenter( + selectContainerButton, + { type: "mouseover" }, + selectContainerButton.ownerDocument.defaultView + ); + const { nodeFront: highlightedNodeFront } = await onNodeHighlight; + is( + highlightedNodeFront.displayName, + expectedSelectedNodeAfterClick, + "The correct node was highlighted" + ); + + const onceNewNodeFront = inspector.selection.once("new-node-front"); + const onNodeUnhighlight = waitForHighlighterTypeHidden( + inspector.highlighters.TYPES.BOXMODEL + ); + + EventUtils.synthesizeMouseAtCenter( + selectContainerButton, + {}, + selectContainerButton.ownerDocument.defaultView + ); + + const nodeFront = await onceNewNodeFront; + is( + nodeFront.displayName, + expectedSelectedNodeAfterClick, + "The correct node has been selected" + ); + + await onNodeUnhighlight; + ok(true, "Highlighter was hidden when clicking on icon"); + + // Move mouse so it does stay in a position where it could hover something impacting + // the test. + EventUtils.synthesizeMouse( + selectContainerButton.closest("body"), + 0, + 0, + { type: "mouseover" }, + selectContainerButton.ownerDocument.defaultView + ); +} + +async function assertQueryContainerTooltip({ + inspector, + view, + ruleIndex, + expectedHeaderText, + expectedBodyText, +}) { + const tooltipTriggerEl = getRuleViewAncestorRulesDataElementByIndex( + view, + ruleIndex + ).querySelector(".container-query-declaration"); + + // Ensure that the element can be targetted from EventUtils. + tooltipTriggerEl.scrollIntoView(); + + const { waitForHighlighterTypeShown, waitForHighlighterTypeHidden } = + getHighlighterTestHelpers(inspector); + + const onNodeHighlight = waitForHighlighterTypeShown( + inspector.highlighters.TYPES.BOXMODEL + ); + + const tooltip = view.tooltips.getTooltip("interactiveTooltip"); + const onTooltipReady = tooltip.once("shown"); + info("synthesizing mousemove: " + tooltip.isVisible()); + EventUtils.synthesizeMouseAtCenter( + tooltipTriggerEl, + { type: "mousemove" }, + tooltipTriggerEl.ownerDocument.defaultView + ); + await onTooltipReady; + info("tooltip was shown"); + await onNodeHighlight; + info("node was highlighted"); + + is( + tooltip.panel.querySelector("header").textContent, + expectedHeaderText, + "Tooltip has expected header content" + ); + + const lis = Array.from(tooltip.panel.querySelectorAll("li")).map( + li => li.textContent + ); + Assert.deepEqual(lis, expectedBodyText, "Tooltip has expected body items"); + + info("Hide the tooltip"); + const onHidden = tooltip.once("hidden"); + const onNodeUnhighlight = waitForHighlighterTypeHidden( + inspector.highlighters.TYPES.BOXMODEL + ); + // Move the mouse elsewhere to hide the tooltip + EventUtils.synthesizeMouse( + tooltipTriggerEl.ownerDocument.body, + 1, + 1, + { type: "mousemove" }, + tooltipTriggerEl.ownerDocument.defaultView + ); + await onHidden; + await onNodeUnhighlight; +} |