diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
commit | 36d22d82aa202bb199967e9512281e9a53db42c9 (patch) | |
tree | 105e8c98ddea1c1e4784a60a5a6410fa416be2de /devtools/client/inspector/flexbox/test | |
parent | Initial commit. (diff) | |
download | firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip |
Adding upstream version 115.7.0esr.upstream/115.7.0esrupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'devtools/client/inspector/flexbox/test')
45 files changed, 2312 insertions, 0 deletions
diff --git a/devtools/client/inspector/flexbox/test/Ahem.ttf b/devtools/client/inspector/flexbox/test/Ahem.ttf Binary files differnew file mode 100644 index 0000000000..ac81cb0316 --- /dev/null +++ b/devtools/client/inspector/flexbox/test/Ahem.ttf diff --git a/devtools/client/inspector/flexbox/test/browser.ini b/devtools/client/inspector/flexbox/test/browser.ini new file mode 100644 index 0000000000..ba7dd0b46b --- /dev/null +++ b/devtools/client/inspector/flexbox/test/browser.ini @@ -0,0 +1,54 @@ +[DEFAULT] +tags = devtools +subsuite = devtools +support-files = + Ahem.ttf + doc_flexbox_CSS_property_with_!important.html + doc_flexbox_pseudos.html + doc_flexbox_specific_cases.html + doc_flexbox_text_nodes.html + doc_flexbox_unauthored_min_dimension.html + doc_flexbox_writing_modes.html + head.js + !/devtools/client/inspector/test/head.js + !/devtools/client/inspector/test/shared-head.js + !/devtools/client/shared/test/shared-head.js + !/devtools/client/shared/test/telemetry-test-helpers.js + !/devtools/client/shared/test/highlighter-test-actor.js + +[browser_flexbox_accordion_state.js] +[browser_flexbox_container_and_item.js] +[browser_flexbox_container_and_item_accordion_state.js] +[browser_flexbox_container_and_item_updates_on_change.js] +[browser_flexbox_container_element_rep.js] +[browser_flexbox_container_properties.js] +[browser_flexbox_empty_state.js] +[browser_flexbox_grand_parent_flex.js] +[browser_flexbox_highlighter_color_picker_on_ESC.js] +[browser_flexbox_highlighter_color_picker_on_RETURN.js] +[browser_flexbox_highlighter_opened_telemetry.js] +[browser_flexbox_item_list_01.js] +[browser_flexbox_item_list_02.js] +[browser_flexbox_item_list_updates_on_change.js] +[browser_flexbox_item_outline_exists.js] +[browser_flexbox_item_outline_has_correct_layout.js] +[browser_flexbox_item_outline_hidden_when_useless.js] +[browser_flexbox_item_outline_renders_basisfinal_points_correctly.js] +[browser_flexbox_item_outline_rotates_for_column.js] +[browser_flexbox_item_outline_rotates_for_different_writing_modes.js] +[browser_flexbox_non_flex_item_is_not_shown.js] +[browser_flexbox_pseudo_elements_are_listed.js] +[browser_flexbox_sizing_flexibility_not_displayed_when_useless.js] +[browser_flexbox_sizing_info_do_not_show_unspecified_min_dimension.js] +[browser_flexbox_sizing_info_exists.js] +[browser_flexbox_sizing_info_for_different_writing_modes.js] +[browser_flexbox_sizing_info_for_pseudos.js] +[browser_flexbox_sizing_info_for_text_nodes.js] +[browser_flexbox_sizing_info_has_correct_sections.js] +[browser_flexbox_sizing_info_matches_properties_with_!important.js] +[browser_flexbox_sizing_info_updates_on_change.js] +[browser_flexbox_sizing_wanted_to_grow_but_was_clamped.js] +[browser_flexbox_text_nodes_are_listed.js] +[browser_flexbox_text_nodes_are_not_inlined.js] +[browser_flexbox_toggle_flexbox_highlighter_01.js] +[browser_flexbox_toggle_flexbox_highlighter_02.js] diff --git a/devtools/client/inspector/flexbox/test/browser_flexbox_accordion_state.js b/devtools/client/inspector/flexbox/test/browser_flexbox_accordion_state.js new file mode 100644 index 0000000000..eb4acd8a1b --- /dev/null +++ b/devtools/client/inspector/flexbox/test/browser_flexbox_accordion_state.js @@ -0,0 +1,120 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +// Test that the flexbox accordions state is persistent through hide/show in the layout +// view. + +const TEST_URI = URL_ROOT + "doc_flexbox_specific_cases.html"; +const ACCORDION_HEADER_SELECTOR = ".accordion-header"; +const ACCORDION_CONTENT_SELECTOR = ".accordion-content"; + +add_task(async function () { + await addTab(TEST_URI); + + await testAccordionState( + ":root", + FLEXBOX_OPENED_PREF, + "#layout-section-flex" + ); + await testAccordionState( + "#container-only", + FLEX_CONTAINER_OPENED_PREF, + "#layout-section-flex-container" + ); + await testAccordionState( + "#item-only", + FLEX_ITEM_OPENED_PREF, + "#layout-section-flex-item" + ); +}); + +async function testAccordionState(target, pref, selector) { + const context = await openLayoutViewAndSelectNode(target); + + await testAccordionStateAfterClickingHeader(pref, selector, context); + await testAccordionStateAfterSwitchingSidebars(pref, selector, context); + await testAccordionStateAfterReopeningLayoutView(pref, selector, context); + + Services.prefs.clearUserPref(pref); +} + +async function testAccordionStateAfterClickingHeader(pref, selector, { doc }) { + info("Checking initial state of the flexbox panel."); + + const item = await waitFor(() => doc.querySelector(selector)); + const header = item.querySelector(ACCORDION_HEADER_SELECTOR); + const content = item.querySelector(ACCORDION_CONTENT_SELECTOR); + + ok( + !content.hidden && content.childElementCount > 0, + "The flexbox panel content is visible." + ); + ok(Services.prefs.getBoolPref(pref), `${pref} is pref on by default.`); + + info("Clicking the flexbox header to hide the flexbox panel."); + header.click(); + + info("Checking the new state of the flexbox panel."); + ok(content.hidden, "The flexbox panel content is hidden."); + ok(!Services.prefs.getBoolPref(pref), `${pref} is pref off.`); +} + +async function testAccordionStateAfterSwitchingSidebars( + pref, + selector, + { doc, inspector } +) { + info( + "Checking the flexbox accordion state is persistent after switching sidebars." + ); + + const item = await waitFor(() => doc.querySelector(selector)); + + info("Selecting the computed view."); + inspector.sidebar.select("computedview"); + + info("Selecting the layout view."); + inspector.sidebar.select("layoutview"); + + info("Checking the state of the flexbox panel."); + const content = item.querySelector(ACCORDION_CONTENT_SELECTOR); + + ok(content.hidden, "The flexbox panel content is hidden."); + ok(!Services.prefs.getBoolPref(pref), `${pref} is pref off.`); +} + +async function testAccordionStateAfterReopeningLayoutView( + pref, + selector, + { target, toolbox } +) { + info( + "Checking the flexbox accordion state is persistent after closing and re-opening the layout view." + ); + + info("Closing the toolbox."); + await toolbox.destroy(); + + info("Re-opening the layout view."); + const { doc } = await openLayoutViewAndSelectNode(target); + const item = await waitFor(() => doc.querySelector(selector)); + const content = item.querySelector(ACCORDION_CONTENT_SELECTOR); + + info("Checking the state of the flexbox panel."); + ok(content.hidden, "The flexbox panel content is hidden."); + ok(!Services.prefs.getBoolPref(pref), `${pref} is pref off.`); +} + +async function openLayoutViewAndSelectNode(target) { + const { inspector, flexboxInspector, toolbox } = await openLayoutView(); + await selectNode(target, inspector); + + return { + doc: flexboxInspector.document, + inspector, + target, + toolbox, + }; +} diff --git a/devtools/client/inspector/flexbox/test/browser_flexbox_container_and_item.js b/devtools/client/inspector/flexbox/test/browser_flexbox_container_and_item.js new file mode 100644 index 0000000000..d77ec6d9e4 --- /dev/null +++ b/devtools/client/inspector/flexbox/test/browser_flexbox_container_and_item.js @@ -0,0 +1,43 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +// Test that the flex container accordion and flex item accordion are both rendered when +// the selected element is both a flex container and item. + +const TEST_URI = ` + <style type='text/css'> + .container { + display: flex; + } + </style> + <div id="container" class="container"> + <div id="item" class="container"> + <div></div> + </div> + </div> +`; + +add_task(async function () { + await addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI)); + const { inspector, flexboxInspector } = await openLayoutView(); + const { document: doc } = flexboxInspector; + + const onAccordionsRendered = waitForDOM(doc, ".accordion-item", 4); + await selectNode("#item", inspector); + const [flexItemPane, flexContainerPane] = await onAccordionsRendered; + + ok(flexItemPane, "The flex item accordion pane is rendered."); + ok(flexContainerPane, "The flex container accordion pane is rendered."); + is( + flexItemPane.children[0].textContent, + "Flex Item of div#container.container", + "Got the correct header for the flex item pane." + ); + is( + flexContainerPane.children[0].textContent, + "Flex Container", + "Got the correct header for the flex container pane." + ); +}); diff --git a/devtools/client/inspector/flexbox/test/browser_flexbox_container_and_item_accordion_state.js b/devtools/client/inspector/flexbox/test/browser_flexbox_container_and_item_accordion_state.js new file mode 100644 index 0000000000..0339845618 --- /dev/null +++ b/devtools/client/inspector/flexbox/test/browser_flexbox_container_and_item_accordion_state.js @@ -0,0 +1,107 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +// Test the order in which accordion items are shown for container-item elements. +// For those combined types, the container accordion is shown first if the selection came +// from the markup-view, because we assume in this case that users do want to see the +// element selected as a container first. +// However when users select an item in the list of items in the container accordion (or +// in the item selector dropdown), then the item accordion should be shown first. + +const TEST_URI = URL_ROOT + "doc_flexbox_specific_cases.html"; + +add_task(async function () { + await addTab(TEST_URI); + const { inspector, flexboxInspector } = await openLayoutView(); + const { document: doc } = flexboxInspector; + + info("Select a flex container-only node"); + await selectNode("#container-only", inspector); + await waitUntil( + () => doc.querySelectorAll(".flex-header-container-properties").length + ); + + info("Check that there is only 1 accordion for displayed"); + let accordions = doc.querySelectorAll(".flex-accordion"); + is(accordions.length, 1, "There's only 1 accordion"); + is( + accordions[0].id, + "layout-section-flex-container", + "The accordion is the container type" + ); + + info("Select a flex container+item node by clicking in the markup-view"); + await clickOnNodeInMarkupView("#container-and-item", inspector); + await waitUntil(() => doc.querySelectorAll(".flex-accordion").length === 2); + + info( + "Check that the 2 accordions are displayed, with container type being first" + ); + accordions = doc.querySelectorAll(".flex-accordion"); + is(accordions.length, 2, "There are 2 accordions"); + is( + accordions[0].id, + "layout-section-flex-container", + "The first accordion is the container type" + ); + is( + accordions[1].id, + "layout-section-flex-item", + "The second accordion is the item type" + ); + + info("Select the container-only node again"); + await selectNode("#container-only", inspector); + await waitUntil(() => doc.querySelectorAll(".flex-accordion").length === 1); + + info("Wait until the accordion item list points to the correct item"); + await waitUntil(() => + doc + .querySelector(".flex-item-list button") + .textContent.includes("container-and-item") + ); + info( + "Click on the container+item node right there in the accordion item list" + ); + doc.querySelector(".flex-item-list button").click(); + await waitUntil(() => doc.querySelectorAll(".flex-accordion").length === 2); + + info( + "Check that the 2 accordions are displayed again, with item type being first" + ); + accordions = doc.querySelectorAll(".flex-accordion"); + is(accordions.length, 2, "There are 2 accordions again"); + is( + accordions[0].id, + "layout-section-flex-item", + "The first accordion is the item type" + ); + is( + accordions[1].id, + "layout-section-flex-container", + "The second accordion is the container type" + ); +}); + +async function clickOnNodeInMarkupView(selector, inspector) { + const { selection, markup } = inspector; + + await markup.expandAll(selection.nodeFront); + const nodeFront = await getNodeFront(selector, inspector); + const markupContainer = markup.getContainer(nodeFront); + + const onSelected = inspector.once("inspector-updated"); + EventUtils.synthesizeMouseAtCenter( + markupContainer.tagLine, + { type: "mousedown" }, + markup.doc.defaultView + ); + EventUtils.synthesizeMouseAtCenter( + markupContainer.tagLine, + { type: "mouseup" }, + markup.doc.defaultView + ); + await onSelected; +} diff --git a/devtools/client/inspector/flexbox/test/browser_flexbox_container_and_item_updates_on_change.js b/devtools/client/inspector/flexbox/test/browser_flexbox_container_and_item_updates_on_change.js new file mode 100644 index 0000000000..af62ac2ff0 --- /dev/null +++ b/devtools/client/inspector/flexbox/test/browser_flexbox_container_and_item_updates_on_change.js @@ -0,0 +1,54 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +// Test that the flex container accordion is rendered when a flex item is updated to +// also be a flex container. + +const TEST_URI = ` + <style> + .container { + display: flex; + } + </style> + <div id="container" class="container"> + <div id="item"> + <div></div> + </div> + </div> +`; + +add_task(async function () { + await addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI)); + const { inspector, flexboxInspector } = await openLayoutView(); + const { document: doc } = flexboxInspector; + + const onFlexItemSizingRendered = waitForDOM(doc, "ul.flex-item-sizing"); + await selectNode("#item", inspector); + const [flexSizingContainer] = await onFlexItemSizingRendered; + + ok(flexSizingContainer, "The flex sizing info is rendered."); + + info("Changing the flexbox in the page."); + const onAccordionsChanged = waitForDOM(doc, ".accordion-item", 4); + await SpecialPowers.spawn( + gBrowser.selectedBrowser, + [], + () => (content.document.getElementById("item").className = "container") + ); + const [flexItemPane, flexContainerPane] = await onAccordionsChanged; + + ok(flexItemPane, "The flex item accordion pane is rendered."); + ok(flexContainerPane, "The flex container accordion pane is rendered."); + is( + flexItemPane.children[0].textContent, + "Flex Item of div#container.container", + "Got the correct header for the flex item pane." + ); + is( + flexContainerPane.children[0].textContent, + "Flex Container", + "Got the correct header for the flex container pane." + ); +}); diff --git a/devtools/client/inspector/flexbox/test/browser_flexbox_container_element_rep.js b/devtools/client/inspector/flexbox/test/browser_flexbox_container_element_rep.js new file mode 100644 index 0000000000..d2d83527b9 --- /dev/null +++ b/devtools/client/inspector/flexbox/test/browser_flexbox_container_element_rep.js @@ -0,0 +1,51 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +// Test that the flex container's element rep will display the box model highlighter on +// hover. + +const TEST_URI = URL_ROOT + "doc_flexbox_specific_cases.html"; + +add_task(async function () { + await addTab(TEST_URI); + const { inspector, flexboxInspector } = await openLayoutView(); + const { document: doc } = flexboxInspector; + const { waitForHighlighterTypeShown } = getHighlighterTestHelpers(inspector); + + const onFlexContainerRepRendered = waitForDOM( + doc, + ".flex-header-content .objectBox" + ); + await selectNode("#container", inspector); + const [flexContainerRep] = await onFlexContainerRepRendered; + + ok(flexContainerRep, "The flex container element rep is rendered."); + + info("Listen to node-highlight event and mouse over the rep"); + const onHighlight = waitForHighlighterTypeShown( + inspector.highlighters.TYPES.BOXMODEL + ); + EventUtils.synthesizeMouse( + flexContainerRep, + 10, + 5, + { type: "mouseover" }, + doc.defaultView + ); + const { nodeFront } = await onHighlight; + + ok(nodeFront, "nodeFront was returned from highlighting the node."); + is(nodeFront.tagName, "DIV", "The highlighted node has the correct tagName."); + is( + nodeFront.attributes[0].name, + "id", + "The highlighted node has the correct attributes." + ); + is( + nodeFront.attributes[0].value, + "container", + "The highlighted node has the correct id." + ); +}); diff --git a/devtools/client/inspector/flexbox/test/browser_flexbox_container_properties.js b/devtools/client/inspector/flexbox/test/browser_flexbox_container_properties.js new file mode 100644 index 0000000000..cf75d74ffe --- /dev/null +++ b/devtools/client/inspector/flexbox/test/browser_flexbox_container_properties.js @@ -0,0 +1,59 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +// Test that the flex container properties are shown when a flex container is selected. + +const TEST_URI = ` + <style type='text/css'> + #container1 { + display: flex; + } + </style> + <div id="container1"> + <div id="item"></div> + </div> +`; + +add_task(async function () { + await addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI)); + const { inspector, flexboxInspector } = await openLayoutView(); + const { document: doc } = flexboxInspector; + + info( + "Selecting the flex container #container1 and checking the values of the flex " + + "container properties for #container1." + ); + const onFlexContainerPropertiesRendered = waitForDOM( + doc, + ".flex-header-container-properties" + ); + await selectNode("#container1", inspector); + const [flexContainerProperties] = await onFlexContainerPropertiesRendered; + + ok(flexContainerProperties, "The flex container properties is rendered."); + is( + flexContainerProperties.children[0].textContent, + "row", + "Got expected flex-direction." + ); + is( + flexContainerProperties.children[1].textContent, + "nowrap", + "Got expected flex-wrap." + ); + + info( + "Selecting a flex item and expecting the flex container properties to not be " + + "shown." + ); + const onFlexHeaderRendered = waitForDOM(doc, ".flex-header"); + await selectNode("#item", inspector); + const [flexHeader] = await onFlexHeaderRendered; + + ok( + !flexHeader.querySelector(".flex-header-container-properties"), + "The flex container properties is not shown in the header." + ); +}); diff --git a/devtools/client/inspector/flexbox/test/browser_flexbox_empty_state.js b/devtools/client/inspector/flexbox/test/browser_flexbox_empty_state.js new file mode 100644 index 0000000000..82e523ebe0 --- /dev/null +++ b/devtools/client/inspector/flexbox/test/browser_flexbox_empty_state.js @@ -0,0 +1,24 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +// Test that a message is displayed when no flex container is selected. + +const TEST_URI = ` + <div></div> +`; + +add_task(async function () { + await addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI)); + const { flexboxInspector } = await openLayoutView(); + const { document: doc } = flexboxInspector; + + info("Checking the initial state of the Flexbox Inspector."); + ok( + doc.querySelector( + ".flex-accordion .devtools-sidepanel-no-result", + "A message is shown when no flex container is selected." + ) + ); +}); diff --git a/devtools/client/inspector/flexbox/test/browser_flexbox_grand_parent_flex.js b/devtools/client/inspector/flexbox/test/browser_flexbox_grand_parent_flex.js new file mode 100644 index 0000000000..8617def08b --- /dev/null +++ b/devtools/client/inspector/flexbox/test/browser_flexbox_grand_parent_flex.js @@ -0,0 +1,55 @@ +/* Any copyright is dedicated to the Public Domain. +http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +// Test that a flex container is not shown as a flex item of its grandparent flex +// container. + +const TEST_URI = ` +<style> +.flex { + display: flex; +} +</style> +<div class="flex"> + <div> + <div id="grandchild" class="flex"> + This is a flex item of a flex container. + Its parent isn't a flex container, but its grandparent is. + </div> + </div> +</div> +`; + +add_task(async function () { + await addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI)); + const { inspector, flexboxInspector } = await openLayoutView(); + const { document: doc } = flexboxInspector; + + info("Select the flex container's grandchild."); + const onFlexContainerHeaderRendered = waitForDOM( + doc, + ".flex-header-container-label" + ); + await selectNode("#grandchild", inspector); + await onFlexContainerHeaderRendered; + + info("Check that only the Flex Container accordion item is showing."); + const flexPanes = doc.querySelectorAll(".flex-accordion"); + is( + flexPanes.length, + 1, + "There should only be one flex accordion item showing." + ); + + info("Check that the container header shows Flex Container."); + const flexAccordionHeader = flexPanes[0].querySelector( + ".accordion-header-label" + ); + is( + flexAccordionHeader.textContent, + "Flex Container", + "The flexbox pane shows a flex container accordion item." + ); +}); diff --git a/devtools/client/inspector/flexbox/test/browser_flexbox_highlighter_color_picker_on_ESC.js b/devtools/client/inspector/flexbox/test/browser_flexbox_highlighter_color_picker_on_ESC.js new file mode 100644 index 0000000000..59b24ba512 --- /dev/null +++ b/devtools/client/inspector/flexbox/test/browser_flexbox_highlighter_color_picker_on_ESC.js @@ -0,0 +1,71 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +const asyncStorage = require("resource://devtools/shared/async-storage.js"); + +// Test that the flexbox highlighter color change in the color picker is reverted when +// ESCAPE is pressed. + +const TEST_URI = URL_ROOT + "doc_flexbox_specific_cases.html"; + +add_task(async function () { + // Make sure there are no custom highlighter colors stored before starting. + await asyncStorage.removeItem("flexboxInspectorHostColors"); + + await addTab(TEST_URI); + const { inspector, flexboxInspector, layoutView } = await openLayoutView(); + const { document: doc } = flexboxInspector; + const { store } = inspector; + const cPicker = layoutView.swatchColorPickerTooltip; + const spectrum = cPicker.spectrum; + + const onColorSwatchRendered = waitForDOM( + doc, + ".layout-flexbox-wrapper .layout-color-swatch" + ); + await selectNode("#container", inspector); + const [swatch] = await onColorSwatchRendered; + + info("Checking the initial state of the Flexbox Inspector color picker."); + is( + swatch.style.backgroundColor, + "rgb(148, 0, 255)", + "The color swatch's background is correct." + ); + is( + store.getState().flexbox.color, + "#9400FF", + "The flexbox color state is correct." + ); + + info("Opening the color picker by clicking on the color swatch."); + const onColorPickerReady = cPicker.once("ready"); + swatch.click(); + await onColorPickerReady; + + await simulateColorPickerChange(cPicker, [0, 255, 0, 0.5]); + + is( + swatch.style.backgroundColor, + "rgba(0, 255, 0, 0.5)", + "The color swatch's background was updated." + ); + + info("Pressing ESCAPE to close the tooltip."); + const onColorUpdate = waitUntilState( + store, + state => state.flexbox.color === "#9400FF" + ); + const onColorPickerHidden = cPicker.tooltip.once("hidden"); + focusAndSendKey(spectrum.element.ownerDocument.defaultView, "ESCAPE"); + await onColorPickerHidden; + await onColorUpdate; + + is( + swatch.style.backgroundColor, + "rgb(148, 0, 255)", + "The color swatch's background was reverted after ESCAPE." + ); +}); diff --git a/devtools/client/inspector/flexbox/test/browser_flexbox_highlighter_color_picker_on_RETURN.js b/devtools/client/inspector/flexbox/test/browser_flexbox_highlighter_color_picker_on_RETURN.js new file mode 100644 index 0000000000..46c6a7022c --- /dev/null +++ b/devtools/client/inspector/flexbox/test/browser_flexbox_highlighter_color_picker_on_RETURN.js @@ -0,0 +1,92 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +const asyncStorage = require("resource://devtools/shared/async-storage.js"); + +// Test that the flexbox highlighter color change in the color picker is committed when +// RETURN is pressed. + +const TEST_URI = URL_ROOT + "doc_flexbox_specific_cases.html"; + +add_task(async function () { + // Make sure there are no custom highlighter colors stored before starting. + await asyncStorage.removeItem("flexboxInspectorHostColors"); + + await addTab(TEST_URI); + const { inspector, flexboxInspector, layoutView } = await openLayoutView(); + const { document: doc } = flexboxInspector; + const { store } = inspector; + const HIGHLIGHTER_TYPE = inspector.highlighters.TYPES.FLEXBOX; + const { waitForHighlighterTypeShown, waitForHighlighterTypeHidden } = + getHighlighterTestHelpers(inspector); + const cPicker = layoutView.swatchColorPickerTooltip; + const spectrum = cPicker.spectrum; + + const onColorSwatchRendered = waitForDOM( + doc, + ".layout-flexbox-wrapper .layout-color-swatch" + ); + await selectNode("#container", inspector); + const [swatch] = await onColorSwatchRendered; + + const checkbox = doc.getElementById("flexbox-checkbox-toggle"); + + info("Checking the initial state of the Flexbox Inspector color picker."); + ok(!checkbox.checked, "Flexbox highlighter toggle is unchecked."); + is( + swatch.style.backgroundColor, + "rgb(148, 0, 255)", + "The color swatch's background is correct." + ); + is( + store.getState().flexbox.color, + "#9400FF", + "The flexbox color state is correct." + ); + + info("Toggling ON the flexbox highlighter."); + const onHighlighterShown = waitForHighlighterTypeShown(HIGHLIGHTER_TYPE); + const onCheckboxChange = waitUntilState( + store, + state => state.flexbox.highlighted + ); + checkbox.click(); + await onHighlighterShown; + await onCheckboxChange; + + info("Opening the color picker by clicking on the color swatch."); + const onColorPickerReady = cPicker.once("ready"); + swatch.click(); + await onColorPickerReady; + + await simulateColorPickerChange(cPicker, [0, 255, 0, 0.5]); + + is( + swatch.style.backgroundColor, + "rgba(0, 255, 0, 0.5)", + "The color swatch's background was updated." + ); + + info("Pressing RETURN to commit the color change."); + const onColorUpdate = waitUntilState( + store, + state => state.flexbox.color === "#00FF0080" + ); + const onColorPickerHidden = cPicker.tooltip.once("hidden"); + focusAndSendKey(spectrum.element.ownerDocument.defaultView, "RETURN"); + await onColorPickerHidden; + await onColorUpdate; + + is( + swatch.style.backgroundColor, + "rgba(0, 255, 0, 0.5)", + "The color swatch's background was kept after RETURN." + ); + + info("Toggling OFF the flexbox highlighter."); + const onHighlighterHidden = waitForHighlighterTypeHidden(HIGHLIGHTER_TYPE); + checkbox.click(); + await onHighlighterHidden; +}); diff --git a/devtools/client/inspector/flexbox/test/browser_flexbox_highlighter_opened_telemetry.js b/devtools/client/inspector/flexbox/test/browser_flexbox_highlighter_opened_telemetry.js new file mode 100644 index 0000000000..62c63e8b9f --- /dev/null +++ b/devtools/client/inspector/flexbox/test/browser_flexbox_highlighter_opened_telemetry.js @@ -0,0 +1,37 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +// Test that the telemetry is correct when the flexbox highlighter is activated from +// the layout view. + +const TEST_URI = URL_ROOT + "doc_flexbox_specific_cases.html"; + +add_task(async function () { + await addTab(TEST_URI); + startTelemetry(); + const { inspector, flexboxInspector } = await openLayoutView(); + const { document: doc } = flexboxInspector; + const onFlexHighlighterToggleRendered = waitForDOM( + doc, + "#flexbox-checkbox-toggle" + ); + await selectNode("#container", inspector); + const [flexHighlighterToggle] = await onFlexHighlighterToggleRendered; + + await toggleHighlighterON(flexHighlighterToggle, inspector); + await toggleHighlighterOFF(flexHighlighterToggle, inspector); + + checkResults(); +}); + +function checkResults() { + checkTelemetry("devtools.layout.flexboxhighlighter.opened", "", 1, "scalar"); + checkTelemetry( + "DEVTOOLS_FLEXBOX_HIGHLIGHTER_TIME_ACTIVE_SECONDS", + "", + null, + "hasentries" + ); +} diff --git a/devtools/client/inspector/flexbox/test/browser_flexbox_item_list_01.js b/devtools/client/inspector/flexbox/test/browser_flexbox_item_list_01.js new file mode 100644 index 0000000000..d7a8ae184a --- /dev/null +++ b/devtools/client/inspector/flexbox/test/browser_flexbox_item_list_01.js @@ -0,0 +1,49 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +const { + getStr, +} = require("resource://devtools/client/inspector/layout/utils/l10n.js"); + +// Test the flex item list is empty when there are no flex items for the selected flex +// container. + +const TEST_URI = ` + <div id="container" style="display:flex"> + </div> +`; + +add_task(async function () { + await addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI)); + const { inspector, flexboxInspector } = await openLayoutView(); + const { document: doc } = flexboxInspector; + const HIGHLIGHTER_TYPE = inspector.highlighters.TYPES.FLEXBOX; + const { getActiveHighlighter } = getHighlighterTestHelpers(inspector); + + const onFlexHeaderRendered = waitForDOM(doc, ".flex-header"); + await selectNode("#container", inspector); + const [flexHeader] = await onFlexHeaderRendered; + const flexHighlighterToggle = flexHeader.querySelector( + "#flexbox-checkbox-toggle" + ); + const flexItemListHeader = doc.querySelector(".flex-item-list-header"); + + info("Checking the state of the Flexbox Inspector."); + ok(flexHeader, "The flex container header is rendered."); + ok(flexHighlighterToggle, "The flexbox highlighter toggle is rendered."); + is( + flexItemListHeader.textContent, + getStr("flexbox.noFlexItems"), + "The flex item list header shows 'No flex items' when there are no items." + ); + ok( + !flexHighlighterToggle.checked, + "The flexbox highlighter toggle is unchecked." + ); + ok( + !getActiveHighlighter(HIGHLIGHTER_TYPE), + "No flexbox highlighter is shown." + ); +}); diff --git a/devtools/client/inspector/flexbox/test/browser_flexbox_item_list_02.js b/devtools/client/inspector/flexbox/test/browser_flexbox_item_list_02.js new file mode 100644 index 0000000000..5433727c6a --- /dev/null +++ b/devtools/client/inspector/flexbox/test/browser_flexbox_item_list_02.js @@ -0,0 +1,35 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +// Test that the flex item list can be used to navigated to the selected flex item. + +const TEST_URI = URL_ROOT + "doc_flexbox_specific_cases.html"; + +add_task(async function () { + await addTab(TEST_URI); + const { inspector, flexboxInspector } = await openLayoutView(); + const { document: doc } = flexboxInspector; + + const onFlexItemListRendered = waitForDOM(doc, ".flex-item-list"); + await selectNode("#container", inspector); + const [flexItemList] = await onFlexItemListRendered; + + info("Checking the initial state of the flex item list."); + ok(flexItemList, "The flex item list is rendered."); + is( + flexItemList.querySelectorAll("button").length, + 1, + "Got the correct number of flex items in the list." + ); + + info("Clicking on the first flex item to navigate to the flex item."); + const onFlexItemOutlineRendered = waitForDOM(doc, ".flex-outline-container"); + flexItemList.querySelector("button").click(); + const [flexOutlineContainer] = await onFlexItemOutlineRendered; + + info("Checking the selected flex item state."); + ok(flexOutlineContainer, "The flex outline is rendered."); + ok(!doc.querySelector(".flex-item-list"), "The flex item list is not shown."); +}); diff --git a/devtools/client/inspector/flexbox/test/browser_flexbox_item_list_updates_on_change.js b/devtools/client/inspector/flexbox/test/browser_flexbox_item_list_updates_on_change.js new file mode 100644 index 0000000000..95cbb2da2d --- /dev/null +++ b/devtools/client/inspector/flexbox/test/browser_flexbox_item_list_updates_on_change.js @@ -0,0 +1,47 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +// Test that the flex item list updates on changes to the number of flex items in the +// flex container. + +const TEST_URI = ` + <style> + #container { + display: flex; + } + </style> + <div id="container"> + <div></div> + </div> +`; + +add_task(async function () { + await addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI)); + const { inspector, flexboxInspector } = await openLayoutView(); + const { document: doc } = flexboxInspector; + + const onFlexItemListRendered = waitForDOM(doc, ".flex-item-list"); + await selectNode("#container", inspector); + const [flexItemList] = await onFlexItemListRendered; + + info("Checking the initial state of the flex item list."); + ok(flexItemList, "The flex item list is rendered."); + is( + flexItemList.querySelectorAll("button").length, + 1, + "Got the correct number of flex items in the list." + ); + + info("Changing the flexbox in the page."); + const onFlexItemListChanged = waitForDOM(doc, ".flex-item-list > button", 2); + await SpecialPowers.spawn(gBrowser.selectedBrowser, [], () => { + const div = content.document.createElement("div"); + content.document.getElementById("container").appendChild(div); + }); + const elements = await onFlexItemListChanged; + + info("Checking the flex item list is correct."); + is(elements.length, 2, "Flex item list was changed."); +}); diff --git a/devtools/client/inspector/flexbox/test/browser_flexbox_item_outline_exists.js b/devtools/client/inspector/flexbox/test/browser_flexbox_item_outline_exists.js new file mode 100644 index 0000000000..eba6ec03f0 --- /dev/null +++ b/devtools/client/inspector/flexbox/test/browser_flexbox_item_outline_exists.js @@ -0,0 +1,30 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +// Test that the flex item outline exists when a flex item is selected. + +const TEST_URI = URL_ROOT + "doc_flexbox_specific_cases.html"; + +add_task(async function () { + await addTab(TEST_URI); + const { inspector, flexboxInspector } = await openLayoutView(); + const { document: doc } = flexboxInspector; + + // Select a flex item in the test document and wait for the outline to be rendered. + const onFlexItemOutlineRendered = waitForDOM(doc, ".flex-outline-container"); + await selectNode(".item", inspector); + const [flexOutlineContainer] = await onFlexItemOutlineRendered; + + ok(flexOutlineContainer, "The flex outline exists in the DOM"); + + const [basis, final] = [ + ...flexOutlineContainer.querySelectorAll( + ".flex-outline-basis, .flex-outline-final" + ), + ]; + + ok(basis, "The basis outline exists"); + ok(final, "The final outline exists"); +}); diff --git a/devtools/client/inspector/flexbox/test/browser_flexbox_item_outline_has_correct_layout.js b/devtools/client/inspector/flexbox/test/browser_flexbox_item_outline_has_correct_layout.js new file mode 100644 index 0000000000..e81d6f5677 --- /dev/null +++ b/devtools/client/inspector/flexbox/test/browser_flexbox_item_outline_has_correct_layout.js @@ -0,0 +1,67 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +// Test that the flex item outline has a correct layout. This outline is built using css +// grid under the hood to position everything. So we want to check that the template for +// this grid has been correctly generated depending on the item that is currently +// selected. + +const TEST_URI = URL_ROOT + "doc_flexbox_specific_cases.html"; + +const TEST_DATA = [ + { + selector: ".shrinking .item", + expectedGridTemplate: + "[basis-start final-start] 300fr [final-end delta-start] " + + "200fr [basis-end delta-end]", + }, + { + selector: ".shrinking.is-clamped .item", + expectedGridTemplate: + "[basis-start final-start] 300fr [delta-start] " + + "50fr [final-end min] 150fr [basis-end delta-end]", + }, + { + selector: ".growing .item", + expectedGridTemplate: + "[basis-start final-start] 200fr [basis-end delta-start] " + + "100fr [final-end delta-end]", + }, + { + selector: ".growing.is-clamped .item", + expectedGridTemplate: + "[basis-start final-start] 200fr [basis-end delta-start] " + + "50fr [final-end max] 50fr [delta-end]", + }, + { + selector: "#wanted-to-shrink-more-than-basis div:first-child", + expectedGridTemplate: + "[delta-start] 63fr [basis-start final-start] " + + "60fr [final-end min] 140fr [basis-end delta-end]", + }, +]; + +add_task(async function () { + await addTab(TEST_URI); + const { inspector, flexboxInspector } = await openLayoutView(); + const { document: doc } = flexboxInspector; + + for (const { selector, expectedGridTemplate } of TEST_DATA) { + info( + `Checking the grid template for the flex item outline for ${selector}` + ); + + await selectNode(selector, inspector); + await waitUntil(() => { + const flexOutline = doc.querySelector(".flex-outline"); + return ( + flexOutline && + flexOutline.style.gridTemplateColumns === expectedGridTemplate + ); + }); + + ok(true, "Grid template is correct"); + } +}); diff --git a/devtools/client/inspector/flexbox/test/browser_flexbox_item_outline_hidden_when_useless.js b/devtools/client/inspector/flexbox/test/browser_flexbox_item_outline_hidden_when_useless.js new file mode 100644 index 0000000000..e0c1cab942 --- /dev/null +++ b/devtools/client/inspector/flexbox/test/browser_flexbox_item_outline_hidden_when_useless.js @@ -0,0 +1,46 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +// Test that the flex item outline is not rendered when it isn't useful. +// For now, that means when the item's base, delta and final sizes are all 0. + +const TEST_URI = ` + <div style="display:flex"> + <div></div> + </div> +`; + +add_task(async function () { + await addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI)); + const { inspector, flexboxInspector } = await openLayoutView(); + const { document: doc } = flexboxInspector; + + info( + "Select the item in the document and wait for the sizing section to appear" + ); + const onFlexItemSizingRendered = waitForDOM(doc, "ul.flex-item-sizing"); + await selectNode("div > div", inspector); + const [flexSizingContainer] = await onFlexItemSizingRendered; + + const outlineEls = doc.querySelectorAll(".flex-outline-container"); + is(outlineEls.length, 0, "The outline has not been rendered for this item"); + + info("Also check that the sizing section shows the correct information"); + const allSections = [ + ...flexSizingContainer.querySelectorAll(".section .name"), + ]; + + is(allSections.length, 2, "There are 2 parts in the sizing section"); + is( + allSections[0].textContent, + "Content Size", + "The first part is the content size" + ); + is( + allSections[1].textContent, + "Final Size", + "The second part is the final size" + ); +}); diff --git a/devtools/client/inspector/flexbox/test/browser_flexbox_item_outline_renders_basisfinal_points_correctly.js b/devtools/client/inspector/flexbox/test/browser_flexbox_item_outline_renders_basisfinal_points_correctly.js new file mode 100644 index 0000000000..d2a2ce94fd --- /dev/null +++ b/devtools/client/inspector/flexbox/test/browser_flexbox_item_outline_renders_basisfinal_points_correctly.js @@ -0,0 +1,40 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +// Test that the flex item outline renders the basis and final points as a single point +// if their sizes are equal. If not, then render as separate points. + +const TEST_URI = URL_ROOT + "doc_flexbox_specific_cases.html"; + +add_task(async function () { + await addTab(TEST_URI); + const { inspector, flexboxInspector } = await openLayoutView(); + const { document: doc, store } = flexboxInspector; + + info("Select a flex item whose basis size matches its final size."); + let onUpdate = waitForDispatch(store, "UPDATE_FLEXBOX"); + await selectNode(".item", inspector); + await onUpdate; + + const [basisFinalPoint] = [ + ...doc.querySelectorAll(".flex-outline-point.basisfinal"), + ]; + + ok(basisFinalPoint, "The basis/final point exists"); + + info("Select a flex item whose basis size is different than its final size."); + onUpdate = waitForDispatch(store, "UPDATE_FLEXBOX"); + await selectNode(".shrinking .item", inspector); + await onUpdate; + + const [basis, final] = [ + ...doc.querySelectorAll( + ".flex-outline-point.basis, .flex-outline-point.final" + ), + ]; + + ok(basis, "The basis point exists"); + ok(final, "The final point exists"); +}); diff --git a/devtools/client/inspector/flexbox/test/browser_flexbox_item_outline_rotates_for_column.js b/devtools/client/inspector/flexbox/test/browser_flexbox_item_outline_rotates_for_column.js new file mode 100644 index 0000000000..05fcbdcb67 --- /dev/null +++ b/devtools/client/inspector/flexbox/test/browser_flexbox_item_outline_rotates_for_column.js @@ -0,0 +1,49 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +// Test that the flex item outline is rotated for flex items in a column flexbox layout. + +const TEST_URI = URL_ROOT + "doc_flexbox_specific_cases.html"; + +add_task(async function () { + await addTab(TEST_URI); + const { inspector, flexboxInspector } = await openLayoutView(); + const { document: doc } = flexboxInspector; + + // Select a flex item in the row flexbox layout. + let onFlexItemOutlineRendered = waitForDOM( + doc, + ".flex-outline-container .flex-outline" + ); + await selectNode(".container .item", inspector); + let [flexOutline] = await onFlexItemOutlineRendered; + + ok( + flexOutline.classList.contains("horizontal-lr"), + "The flex outline has the horizontal-lr class" + ); + + // Check that the outline is wider than it is tall in the configuration. + let bounds = flexOutline.getBoxQuads()[0].getBounds(); + ok(bounds.width > bounds.height, "The outline looks like a row"); + + // Select a flex item in the column flexbox layout. + onFlexItemOutlineRendered = waitForDOM( + doc, + ".flex-outline-container .flex-outline" + ); + await selectNode(".container.column .item", inspector); + await waitUntil(() => { + flexOutline = doc.querySelector( + ".flex-outline-container .flex-outline.vertical-tb" + ); + return flexOutline; + }); + ok(true, "The flex outline has the vertical-tb class"); + + // Check that the outline is taller than it is wide in the configuration. + bounds = flexOutline.getBoxQuads()[0].getBounds(); + ok(bounds.height > bounds.width, "The outline looks like a column"); +}); diff --git a/devtools/client/inspector/flexbox/test/browser_flexbox_item_outline_rotates_for_different_writing_modes.js b/devtools/client/inspector/flexbox/test/browser_flexbox_item_outline_rotates_for_different_writing_modes.js new file mode 100644 index 0000000000..860f2c2337 --- /dev/null +++ b/devtools/client/inspector/flexbox/test/browser_flexbox_item_outline_rotates_for_different_writing_modes.js @@ -0,0 +1,42 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +// Test that the flex item outline is rotated to match its main axis direction. + +const TEST_URI = URL_ROOT + "doc_flexbox_writing_modes.html"; + +add_task(async function () { + await addTab(TEST_URI); + const { inspector, flexboxInspector } = await openLayoutView(); + const { document: doc } = flexboxInspector; + + info("Check that the row flex item rotated to vertical-bt."); + let onFlexItemOutlineRendered = waitForDOM( + doc, + ".flex-outline-container .flex-outline" + ); + await selectNode(".row.vertical-bt.item", inspector); + let [flexOutline] = await onFlexItemOutlineRendered; + + ok( + flexOutline.classList.contains("vertical-bt"), + "Row outline has been rotated to vertical-bt." + ); + + info("Check that the column flex item rotated to horizontal-rl."); + onFlexItemOutlineRendered = waitForDOM( + doc, + ".flex-outline-container .flex-outline" + ); + await selectNode(".column.horizontal-rl.item", inspector); + await waitUntil(() => { + flexOutline = doc.querySelector( + ".flex-outline-container .flex-outline.horizontal-rl" + ); + return flexOutline; + }); + + ok(true, "Column outline has been rotated to horizontal-rl."); +}); diff --git a/devtools/client/inspector/flexbox/test/browser_flexbox_non_flex_item_is_not_shown.js b/devtools/client/inspector/flexbox/test/browser_flexbox_non_flex_item_is_not_shown.js new file mode 100644 index 0000000000..92422ea490 --- /dev/null +++ b/devtools/client/inspector/flexbox/test/browser_flexbox_non_flex_item_is_not_shown.js @@ -0,0 +1,30 @@ +/* Any copyright is dedicated to the Public Domain. +http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +// Test that an element that is the child of a flex container but is not actually a flex +// item is not shown in the sidebar when selected. + +const TEST_URI = ` +<div style="display:flex"> + <div id="item" style="position:absolute;">test</div> +</div> +`; + +add_task(async function () { + await addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI)); + const { inspector, flexboxInspector } = await openLayoutView(); + const { document: doc } = flexboxInspector; + + info("Select the container's supposed flex item."); + await selectNode("#item", inspector); + const noFlexContainerOrItemSelected = doc.querySelector( + ".flex-accordion .devtools-sidepanel-no-result" + ); + + ok( + noFlexContainerOrItemSelected, + "The flexbox pane shows a message to select a flex container or item to continue." + ); +}); diff --git a/devtools/client/inspector/flexbox/test/browser_flexbox_pseudo_elements_are_listed.js b/devtools/client/inspector/flexbox/test/browser_flexbox_pseudo_elements_are_listed.js new file mode 100644 index 0000000000..c69e4c92b6 --- /dev/null +++ b/devtools/client/inspector/flexbox/test/browser_flexbox_pseudo_elements_are_listed.js @@ -0,0 +1,28 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +// Test that pseudo-elements that are flex items do appear in the list of items. + +const TEST_URI = URL_ROOT + "doc_flexbox_pseudos.html"; + +add_task(async function () { + await addTab(TEST_URI); + const { inspector, flexboxInspector } = await openLayoutView(); + const { document: doc } = flexboxInspector; + + // Select the flex container in the inspector. + const onItemsListRendered = waitForDOM( + doc, + ".layout-flexbox-wrapper .flex-item-list" + ); + await selectNode(".container", inspector); + const [flexItemList] = await onItemsListRendered; + + const items = [...flexItemList.querySelectorAll("button .objectBox")]; + is(items.length, 2, "There are 2 items displayed in the list"); + + is(items[0].textContent, "::before", "The first item is ::before"); + is(items[1].textContent, "::after", "The second item is ::after"); +}); diff --git a/devtools/client/inspector/flexbox/test/browser_flexbox_sizing_flexibility_not_displayed_when_useless.js b/devtools/client/inspector/flexbox/test/browser_flexbox_sizing_flexibility_not_displayed_when_useless.js new file mode 100644 index 0000000000..e25ebd5a6a --- /dev/null +++ b/devtools/client/inspector/flexbox/test/browser_flexbox_sizing_flexibility_not_displayed_when_useless.js @@ -0,0 +1,48 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +// Test that the flexibility section in the flex item sizing properties is not displayed +// when the item did not grow or shrink. + +const TEST_URI = URL_ROOT + "doc_flexbox_specific_cases.html"; + +add_task(async function () { + await addTab(TEST_URI); + const { inspector, flexboxInspector } = await openLayoutView(); + const { document: doc, store } = flexboxInspector; + + info( + "Select an item with flex:0 and wait for the sizing info to be rendered" + ); + let onUpdate = waitForDispatch(store, "UPDATE_FLEXBOX"); + await selectNode("#did-not-grow-or-shrink div", inspector); + await onUpdate; + + let flexSections = doc.querySelectorAll( + ".flex-item-sizing .section.flexibility" + ); + is( + flexSections.length, + 0, + "The flexibility section was not found in the DOM" + ); + + info( + "Select a more complex item which also doesn't flex and wait for the sizing info" + ); + onUpdate = waitForDispatch(store, "UPDATE_FLEXBOX"); + await selectNode( + "#just-enough-space-for-clamped-items div:last-child", + inspector + ); + await onUpdate; + + flexSections = doc.querySelectorAll(".flex-item-sizing .section.flexibility"); + is( + flexSections.length, + 0, + "The flexibility section was not found in the DOM" + ); +}); diff --git a/devtools/client/inspector/flexbox/test/browser_flexbox_sizing_info_do_not_show_unspecified_min_dimension.js b/devtools/client/inspector/flexbox/test/browser_flexbox_sizing_info_do_not_show_unspecified_min_dimension.js new file mode 100644 index 0000000000..45cae70d7b --- /dev/null +++ b/devtools/client/inspector/flexbox/test/browser_flexbox_sizing_info_do_not_show_unspecified_min_dimension.js @@ -0,0 +1,45 @@ +/* Any copyright is dedicated to the Public Domain. +http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +// Test that a flex item's min width/height value is not displayed if it's unspecified in +// the CSS. + +const TEST_URI = URL_ROOT + "doc_flexbox_unauthored_min_dimension.html"; + +async function checkFlexItemCSSProperty(inspector, store, doc, selector) { + info("Select the container's flex item sizing info."); + const onUpdate = waitForDispatch(store, "UPDATE_FLEXBOX"); + await selectNode(selector, inspector); + await onUpdate; + + info( + "Check that the minimum size section does not display minimum dimension text." + ); + const [sectionMinRowItem] = [ + ...doc.querySelectorAll(".flex-item-sizing .section.min"), + ]; + const minDimension = sectionMinRowItem.querySelector(".css-property-link"); + + ok(!minDimension, "Minimum dimension property should not be displayed."); +} + +add_task(async function () { + await addTab(TEST_URI); + const { inspector, flexboxInspector } = await openLayoutView(); + const { document: doc, store } = flexboxInspector; + + await checkFlexItemCSSProperty( + inspector, + store, + doc, + "#flex-item-with-unauthored-min-width" + ); + await checkFlexItemCSSProperty( + inspector, + store, + doc, + "#flex-item-with-unauthored-min-height" + ); +}); diff --git a/devtools/client/inspector/flexbox/test/browser_flexbox_sizing_info_exists.js b/devtools/client/inspector/flexbox/test/browser_flexbox_sizing_info_exists.js new file mode 100644 index 0000000000..e353eea0db --- /dev/null +++ b/devtools/client/inspector/flexbox/test/browser_flexbox_sizing_info_exists.js @@ -0,0 +1,36 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +// Test that the flex item sizing information exists when a flex item is selected. + +const TEST_URI = URL_ROOT + "doc_flexbox_specific_cases.html"; + +add_task(async function () { + await addTab(TEST_URI); + const { inspector, flexboxInspector } = await openLayoutView(); + const { document: doc } = flexboxInspector; + + // Select a flex item in the test document and wait for the sizing info to be rendered. + // Note that we select an item that has base, delta and final sizes, so we can check + // those sections exists. + const onFlexItemSizingRendered = waitForDOM(doc, "ul.flex-item-sizing"); + await selectNode(".container.growing .item", inspector); + const [flexSizingContainer] = await onFlexItemSizingRendered; + + ok(flexSizingContainer, "The flex sizing exists in the DOM"); + + info("Check that the base, flexibility and final sizes are displayed"); + const allSections = [ + ...flexSizingContainer.querySelectorAll(".section .name"), + ]; + const allSectionTitles = allSections.map(el => el.textContent); + + ["Base Size", "Flexibility", "Final Size"].forEach((expectedTitle, i) => { + ok( + allSectionTitles[i].includes(expectedTitle), + `Sizing section #${i + 1} (${expectedTitle}) was found` + ); + }); +}); diff --git a/devtools/client/inspector/flexbox/test/browser_flexbox_sizing_info_for_different_writing_modes.js b/devtools/client/inspector/flexbox/test/browser_flexbox_sizing_info_for_different_writing_modes.js new file mode 100644 index 0000000000..91a99d3da5 --- /dev/null +++ b/devtools/client/inspector/flexbox/test/browser_flexbox_sizing_info_for_different_writing_modes.js @@ -0,0 +1,75 @@ +/* Any copyright is dedicated to the Public Domain. +http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +// Test that the flex item sizing info shows the correct dimension values for different +// writing modes. For vertical writing modes, row items should display height values and +// column items should display width values. The opposite is true for horizontal mode +// where rows display width values and columns display height. + +const TEST_URI = URL_ROOT + "doc_flexbox_writing_modes.html"; + +async function checkFlexItemDimension( + inspector, + store, + doc, + selector, + expected +) { + info("Select the container's flex item."); + const onUpdate = waitForDispatch(store, "UPDATE_FLEXBOX"); + await selectNode(selector, inspector); + await onUpdate; + + info("Check that the minimum size section shows the correct dimension."); + const sectionMinRowItem = doc.querySelector(".flex-item-sizing .section.min"); + const minDimension = sectionMinRowItem.querySelector(".css-property-link"); + + ok( + minDimension.textContent.includes(expected), + "The flex item sizing has the correct dimension value." + ); +} + +add_task(async function () { + await addTab(TEST_URI); + const { inspector, flexboxInspector } = await openLayoutView(); + const { document: doc, store } = flexboxInspector; + + await checkFlexItemDimension( + inspector, + store, + doc, + ".row.vertical-rl.item", + "min-height" + ); + await checkFlexItemDimension( + inspector, + store, + doc, + ".column.vertical-tb.item", + "min-height" + ); + await checkFlexItemDimension( + inspector, + store, + doc, + ".row.vertical-bt.item", + "min-height" + ); + await checkFlexItemDimension( + inspector, + store, + doc, + ".column.horizontal-rl.item", + "min-width" + ); + await checkFlexItemDimension( + inspector, + store, + doc, + ".row.horizontal-lr.item", + "min-width" + ); +}); diff --git a/devtools/client/inspector/flexbox/test/browser_flexbox_sizing_info_for_pseudos.js b/devtools/client/inspector/flexbox/test/browser_flexbox_sizing_info_for_pseudos.js new file mode 100644 index 0000000000..75b3a00a4f --- /dev/null +++ b/devtools/client/inspector/flexbox/test/browser_flexbox_sizing_info_for_pseudos.js @@ -0,0 +1,40 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +// Test that the flex item sizing UI also appears for pseudo elements. + +const TEST_URI = URL_ROOT + "doc_flexbox_pseudos.html"; + +add_task(async function () { + await addTab(TEST_URI); + const { inspector, flexboxInspector } = await openLayoutView(); + const { document: doc } = flexboxInspector; + + info("Select the ::before pseudo-element in the inspector"); + const containerNode = await getNodeFront(".container", inspector); + const { nodes } = await inspector.walker.children(containerNode); + const beforeNode = nodes[0]; + + const onFlexItemSizingRendered = waitForDOM(doc, "ul.flex-item-sizing"); + const onFlexItemOutlineRendered = waitForDOM(doc, ".flex-outline-container"); + await selectNode(beforeNode, inspector); + const [flexSizingContainer] = await onFlexItemSizingRendered; + const [flexOutlineContainer] = await onFlexItemOutlineRendered; + + ok(flexSizingContainer, "The flex sizing exists in the DOM"); + ok(flexOutlineContainer, "The flex outline exists in the DOM"); + + info("Check that the various sizing sections are displayed"); + const allSections = [...flexSizingContainer.querySelectorAll(".section")]; + ok(allSections.length, "Sizing sections are displayed"); + + info("Check that the various parts of the outline are displayed"); + const [basis, final] = [ + ...flexOutlineContainer.querySelectorAll( + ".flex-outline-basis, .flex-outline-final" + ), + ]; + ok(basis && final, "The final and basis parts of the outline exist"); +}); diff --git a/devtools/client/inspector/flexbox/test/browser_flexbox_sizing_info_for_text_nodes.js b/devtools/client/inspector/flexbox/test/browser_flexbox_sizing_info_for_text_nodes.js new file mode 100644 index 0000000000..fc96505208 --- /dev/null +++ b/devtools/client/inspector/flexbox/test/browser_flexbox_sizing_info_for_text_nodes.js @@ -0,0 +1,40 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +// Test that the flex item sizing UI also appears for text nodes. + +const TEST_URI = URL_ROOT + "doc_flexbox_text_nodes.html"; + +add_task(async function () { + await addTab(TEST_URI); + const { inspector, flexboxInspector } = await openLayoutView(); + const { document: doc } = flexboxInspector; + + info("Select the first text node in the flex container"); + const containerNode = await getNodeFront(".container", inspector); + const { nodes } = await inspector.walker.children(containerNode); + const firstTextNode = nodes[0]; + + const onFlexItemSizingRendered = waitForDOM(doc, "ul.flex-item-sizing"); + const onFlexItemOutlineRendered = waitForDOM(doc, ".flex-outline-container"); + await selectNode(firstTextNode, inspector); + const [flexSizingContainer] = await onFlexItemSizingRendered; + const [flexOutlineContainer] = await onFlexItemOutlineRendered; + + ok(flexSizingContainer, "The flex sizing exists in the DOM"); + ok(flexOutlineContainer, "The flex outline exists in the DOM"); + + info("Check that the various sizing sections are displayed"); + const allSections = [...flexSizingContainer.querySelectorAll(".section")]; + ok(allSections.length, "Sizing sections are displayed"); + + info("Check that the various parts of the outline are displayed"); + const [basis, final] = [ + ...flexOutlineContainer.querySelectorAll( + ".flex-outline-basis, .flex-outline-final" + ), + ]; + ok(basis && final, "The final and basis parts of the outline exist"); +}); diff --git a/devtools/client/inspector/flexbox/test/browser_flexbox_sizing_info_has_correct_sections.js b/devtools/client/inspector/flexbox/test/browser_flexbox_sizing_info_has_correct_sections.js new file mode 100644 index 0000000000..e31366da15 --- /dev/null +++ b/devtools/client/inspector/flexbox/test/browser_flexbox_sizing_info_has_correct_sections.js @@ -0,0 +1,86 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +// Test that the flex item sizing UI contains the right sections, depending on which +// element is selected. Some items may be clamped, others not, so not all sections are +// visible at all times. + +const TEST_URI = URL_ROOT + "doc_flexbox_specific_cases.html"; + +const TEST_DATA = [ + { + selector: ".shrinking .item", + expectedSections: ["Base Size", "Flexibility", "Final Size"], + }, + { + selector: ".shrinking.is-clamped .item", + expectedSections: [ + "Base Size", + "Flexibility", + "Minimum Size", + "Final Size", + ], + }, + { + selector: ".growing .item", + expectedSections: ["Base Size", "Flexibility", "Final Size"], + }, + { + selector: ".growing.is-clamped .item", + expectedSections: [ + "Base Size", + "Flexibility", + "Maximum Size", + "Final Size", + ], + }, +]; + +add_task(async function () { + await addTab(TEST_URI); + const { inspector, flexboxInspector } = await openLayoutView(); + const { document: doc, store } = flexboxInspector; + + for (const { selector, expectedSections } of TEST_DATA) { + info(`Checking the list of sections for the flex item ${selector}`); + const sections = await selectNodeAndGetFlexSizingSections( + selector, + store, + inspector, + doc + ); + + is( + sections.length, + expectedSections.length, + "Correct number of sections found" + ); + expectedSections.forEach((expectedSection, i) => { + ok( + sections[i].includes(expectedSection), + `The ${expectedSection} section was found` + ); + }); + } +}); + +async function selectNodeAndGetFlexSizingSections( + selector, + store, + inspector, + doc +) { + const onUpdate = waitForDispatch(store, "UPDATE_FLEXBOX"); + await selectNode(selector, inspector); + await onUpdate; + + info(`Getting the list of displayed sections for ${selector}`); + const allSections = [ + ...doc.querySelectorAll("ul.flex-item-sizing .section .name"), + ]; + const allSectionTitles = allSections.map(el => el.textContent); + + return allSectionTitles; +} diff --git a/devtools/client/inspector/flexbox/test/browser_flexbox_sizing_info_matches_properties_with_!important.js b/devtools/client/inspector/flexbox/test/browser_flexbox_sizing_info_matches_properties_with_!important.js new file mode 100644 index 0000000000..ba14ef7a62 --- /dev/null +++ b/devtools/client/inspector/flexbox/test/browser_flexbox_sizing_info_matches_properties_with_!important.js @@ -0,0 +1,41 @@ +/* Any copyright is dedicated to the Public Domain. +http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +// Test that a flex item's sizing section shows the highest value of specificity for its +// CSS property. + +const TEST_URI = URL_ROOT + "doc_flexbox_CSS_property_with_!important.html"; + +add_task(async function () { + await addTab(TEST_URI); + const { inspector, flexboxInspector } = await openLayoutView(); + const { document: doc } = flexboxInspector; + + info("Select the container's flex item sizing info."); + const onFlexItemSizingRendered = waitForDOM(doc, "ul.flex-item-sizing"); + await selectNode(".item", inspector); + const [flexItemSizingContainer] = await onFlexItemSizingRendered; + + info( + "Check that the max and flexibility sections show correct CSS property value." + ); + const flexSection = flexItemSizingContainer.querySelector( + ".section.flexibility" + ); + const maxSection = flexItemSizingContainer.querySelector(".section.max"); + const flexGrow = flexSection.querySelector(".css-property-link"); + const maxSize = maxSection.querySelector(".css-property-link"); + + is( + maxSize.textContent, + "(max-width: 400px !important)", + "Maximum size section shows CSS property value with highest specificity." + ); + is( + flexGrow.textContent, + "(flex-grow: 5 !important)", + "Flexibility size section shows CSS property value with highest specificity." + ); +}); diff --git a/devtools/client/inspector/flexbox/test/browser_flexbox_sizing_info_updates_on_change.js b/devtools/client/inspector/flexbox/test/browser_flexbox_sizing_info_updates_on_change.js new file mode 100644 index 0000000000..9218022b02 --- /dev/null +++ b/devtools/client/inspector/flexbox/test/browser_flexbox_sizing_info_updates_on_change.js @@ -0,0 +1,50 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +// Test that the flexbox sizing info updates on changes to the flex item properties. + +const TEST_URI = ` + <style> + #container { + display: flex; + } + </style> + <div id="container"> + <div id="item"></div> + </div> +`; + +add_task(async function () { + await addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI)); + const { inspector, flexboxInspector } = await openLayoutView(); + const { document: doc } = flexboxInspector; + + const onFlexItemSizingRendered = waitForDOM(doc, "ul.flex-item-sizing"); + await selectNode("#item", inspector); + const [flexItemSizingContainer] = await onFlexItemSizingRendered; + + info("Checking the initial state of the flex item list."); + is( + flexItemSizingContainer.querySelectorAll("li").length, + 2, + "Got the correct number of flex item sizing properties in the list." + ); + + info("Changing the flexbox in the page."); + const onFlexItemSizingChanged = waitForDOM( + doc, + "ul.flex-item-sizing > li", + 3 + ); + SpecialPowers.spawn( + gBrowser.selectedBrowser, + [], + () => (content.document.getElementById("item").style.minWidth = "100px") + ); + const elements = await onFlexItemSizingChanged; + + info("Checking the flex item sizing info is correct."); + is(elements.length, 3, "Flex item sizing info was changed."); +}); diff --git a/devtools/client/inspector/flexbox/test/browser_flexbox_sizing_wanted_to_grow_but_was_clamped.js b/devtools/client/inspector/flexbox/test/browser_flexbox_sizing_wanted_to_grow_but_was_clamped.js new file mode 100644 index 0000000000..72e2861ef3 --- /dev/null +++ b/devtools/client/inspector/flexbox/test/browser_flexbox_sizing_wanted_to_grow_but_was_clamped.js @@ -0,0 +1,44 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +const { + getStr, +} = require("resource://devtools/client/inspector/layout/utils/l10n.js"); + +// Test the specific max-clamping scenario where an item wants to grow a certain amount +// but its max-size prevents it from growing that much. + +const TEST_URI = URL_ROOT + "doc_flexbox_specific_cases.html"; + +add_task(async function () { + await addTab(TEST_URI); + const { inspector, flexboxInspector } = await openLayoutView(); + const { document: doc } = flexboxInspector; + + info( + "Select the test item in the document and wait for the sizing info to render" + ); + const onRendered = waitForDOM(doc, ".flex-outline, .flex-item-sizing", 2); + await selectNode("#want-to-grow-more-than-max div", inspector); + const [outlineContainer, sizingContainer] = await onRendered; + + info( + "Check that the outline contains the max point and that it's equal to final" + ); + const maxPoint = outlineContainer.querySelector(".flex-outline-point.max"); + ok(maxPoint, "The max point is displayed"); + ok( + outlineContainer.style.gridTemplateColumns.includes("[final-end max]"), + "The final and max points are at the same position" + ); + + info("Check that the maximum sizing section displays the right info"); + const reasons = [...sizingContainer.querySelectorAll(".reasons li")]; + const expectedReason = getStr("flexbox.itemSizing.clampedToMax"); + ok( + reasons.some(r => r.textContent === expectedReason), + "The clampedToMax reason was found" + ); +}); diff --git a/devtools/client/inspector/flexbox/test/browser_flexbox_text_nodes_are_listed.js b/devtools/client/inspector/flexbox/test/browser_flexbox_text_nodes_are_listed.js new file mode 100644 index 0000000000..374ec77962 --- /dev/null +++ b/devtools/client/inspector/flexbox/test/browser_flexbox_text_nodes_are_listed.js @@ -0,0 +1,28 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +// Test that text nodes that are flex items do appear in the list of items. + +const TEST_URI = URL_ROOT + "doc_flexbox_text_nodes.html"; + +add_task(async function () { + await addTab(TEST_URI); + const { inspector, flexboxInspector } = await openLayoutView(); + const { document: doc } = flexboxInspector; + + // Select the flex container in the inspector. + const onItemsListRendered = waitForDOM( + doc, + ".layout-flexbox-wrapper .flex-item-list" + ); + await selectNode(".container", inspector); + const [flexItemList] = await onItemsListRendered; + + const items = [...flexItemList.querySelectorAll("button .objectBox")]; + is(items.length, 3, "There are 3 items displayed in the list"); + + is(items[0].textContent, "#text", "The first item is a text node"); + is(items[2].textContent, "#text", "The third item is a text node"); +}); diff --git a/devtools/client/inspector/flexbox/test/browser_flexbox_text_nodes_are_not_inlined.js b/devtools/client/inspector/flexbox/test/browser_flexbox_text_nodes_are_not_inlined.js new file mode 100644 index 0000000000..2494ac1dcb --- /dev/null +++ b/devtools/client/inspector/flexbox/test/browser_flexbox_text_nodes_are_not_inlined.js @@ -0,0 +1,52 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +// Test that single child text nodes that are also flex items can be selected in the +// flexbox inspector. +// This means that they are not inlined like normal single child text nodes, since +// selecting them in the flexbox inspector also means selecting them in the markup view. + +const TEST_URI = URL_ROOT + "doc_flexbox_text_nodes.html"; + +add_task(async function () { + await addTab(TEST_URI); + const { inspector, flexboxInspector } = await openLayoutView(); + const { document: doc } = flexboxInspector; + + // Select the flex container in the inspector. + const onItemsListRendered = waitForDOM( + doc, + ".layout-flexbox-wrapper .flex-item-list" + ); + await selectNode(".container.single-child", inspector); + const [flexItemList] = await onItemsListRendered; + + const items = [...flexItemList.querySelectorAll("button .objectBox")]; + is(items.length, 1, "There is 1 item displayed in the list"); + is(items[0].textContent, "#text", "The item in the list is a text node"); + + info("Click on the item to select it"); + const onFlexItemOutlineRendered = waitForDOM(doc, ".flex-outline-container"); + items[0].closest("button").click(); + const [flexOutlineContainer] = await onFlexItemOutlineRendered; + ok( + flexOutlineContainer, + "The flex outline is displayed for a single child short text node too" + ); + + ok( + inspector.selection.isTextNode(), + "The current inspector selection is the text node" + ); + + const markupContainer = inspector.markup.getContainer( + inspector.selection.nodeFront + ); + is( + markupContainer.elt.textContent, + "short text", + "This is the right text node" + ); +}); diff --git a/devtools/client/inspector/flexbox/test/browser_flexbox_toggle_flexbox_highlighter_01.js b/devtools/client/inspector/flexbox/test/browser_flexbox_toggle_flexbox_highlighter_01.js new file mode 100644 index 0000000000..2fbfccb162 --- /dev/null +++ b/devtools/client/inspector/flexbox/test/browser_flexbox_toggle_flexbox_highlighter_01.js @@ -0,0 +1,55 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +// Test toggling ON/OFF the flexbox highlighter from the flexbox inspector panel. + +const TEST_URI = URL_ROOT + "doc_flexbox_specific_cases.html"; + +add_task(async function () { + await addTab(TEST_URI); + const { inspector, flexboxInspector } = await openLayoutView(); + const { document: doc } = flexboxInspector; + const HIGHLIGHTER_TYPE = inspector.highlighters.TYPES.FLEXBOX; + const { getActiveHighlighter } = getHighlighterTestHelpers(inspector); + + const onFlexHighlighterToggleRendered = waitForDOM( + doc, + "#flexbox-checkbox-toggle" + ); + await selectNode("#container", inspector); + const [flexHighlighterToggle] = await onFlexHighlighterToggleRendered; + + info("Checking the initial state of the Flexbox Inspector."); + ok(flexHighlighterToggle, "The flexbox highlighter toggle is rendered."); + ok( + !flexHighlighterToggle.checked, + "The flexbox highlighter toggle is unchecked." + ); + ok( + !getActiveHighlighter(HIGHLIGHTER_TYPE), + "No flexbox highlighter is shown." + ); + + await toggleHighlighterON(flexHighlighterToggle, inspector); + + info("Checking the flexbox highlighter is created."); + ok(getActiveHighlighter(HIGHLIGHTER_TYPE), "Flexbox highlighter is shown."); + ok( + flexHighlighterToggle.checked, + "The flexbox highlighter toggle is checked." + ); + + await toggleHighlighterOFF(flexHighlighterToggle, inspector); + + info("Checking the flexbox highlighter is not shown."); + ok( + !getActiveHighlighter(HIGHLIGHTER_TYPE), + "No flexbox highlighter is shown." + ); + ok( + !flexHighlighterToggle.checked, + "The flexbox highlighter toggle is unchecked." + ); +}); diff --git a/devtools/client/inspector/flexbox/test/browser_flexbox_toggle_flexbox_highlighter_02.js b/devtools/client/inspector/flexbox/test/browser_flexbox_toggle_flexbox_highlighter_02.js new file mode 100644 index 0000000000..c7d7c35d9a --- /dev/null +++ b/devtools/client/inspector/flexbox/test/browser_flexbox_toggle_flexbox_highlighter_02.js @@ -0,0 +1,102 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +// Test toggling ON/OFF the flexbox highlighter on different flex containers from the +// flexbox inspector panel. + +const TEST_URI = URL_ROOT + "doc_flexbox_specific_cases.html"; + +add_task(async function () { + await addTab(TEST_URI); + const { inspector, flexboxInspector } = await openLayoutView(); + const { document: doc } = flexboxInspector; + const { store } = inspector; + const HIGHLIGHTER_TYPE = inspector.highlighters.TYPES.FLEXBOX; + const { getActiveHighlighter, getNodeForActiveHighlighter } = + getHighlighterTestHelpers(inspector); + + const onFlexHighlighterToggleRendered = waitForDOM( + doc, + "#flexbox-checkbox-toggle" + ); + await selectNode("#container", inspector); + const [flexHighlighterToggle] = await onFlexHighlighterToggleRendered; + + info("Checking the #container state of the Flexbox Inspector."); + ok(flexHighlighterToggle, "The flexbox highlighter toggle is rendered."); + ok( + !flexHighlighterToggle.checked, + "The flexbox highlighter toggle is unchecked." + ); + ok( + !getActiveHighlighter(HIGHLIGHTER_TYPE), + "No flexbox highlighter is shown." + ); + + info( + "Toggling ON the flexbox highlighter for #container from the layout panel." + ); + await toggleHighlighterON(flexHighlighterToggle, inspector); + + info("Checking the flexbox highlighter is created for #container."); + const highlightedNodeFront = store.getState().flexbox.flexContainer.nodeFront; + is( + getNodeForActiveHighlighter(HIGHLIGHTER_TYPE), + highlightedNodeFront, + "Flexbox highlighter is shown for #container." + ); + ok( + flexHighlighterToggle.checked, + "The flexbox highlighter toggle is checked." + ); + + info("Switching the selected flex container to .container.column"); + const onToggleChange = waitUntilState( + store, + state => !state.flexbox.highlighted + ); + await selectNode(".container.column", inspector); + await onToggleChange; + + info("Checking the .container.column state of the Flexbox Inspector."); + ok( + !flexHighlighterToggle.checked, + "The flexbox highlighter toggle is unchecked." + ); + is( + getNodeForActiveHighlighter(HIGHLIGHTER_TYPE), + highlightedNodeFront, + "Flexbox highlighter is still shown for #container." + ); + + info( + "Toggling ON the flexbox highlighter for .container.column from the layout " + + "panel." + ); + await toggleHighlighterON(flexHighlighterToggle, inspector); + + info("Checking the flexbox highlighter is created for .container.column"); + is( + getNodeForActiveHighlighter(HIGHLIGHTER_TYPE), + store.getState().flexbox.flexContainer.nodeFront, + "Flexbox highlighter is shown for .container.column." + ); + ok( + flexHighlighterToggle.checked, + "The flexbox highlighter toggle is checked." + ); + + await toggleHighlighterOFF(flexHighlighterToggle, inspector); + + info("Checking the flexbox highlighter is not shown."); + ok( + !getActiveHighlighter(HIGHLIGHTER_TYPE), + "No flexbox highlighter is shown." + ); + ok( + !flexHighlighterToggle.checked, + "The flexbox highlighter toggle is unchecked." + ); +}); diff --git a/devtools/client/inspector/flexbox/test/doc_flexbox_CSS_property_with_!important.html b/devtools/client/inspector/flexbox/test/doc_flexbox_CSS_property_with_!important.html new file mode 100644 index 0000000000..097d91215b --- /dev/null +++ b/devtools/client/inspector/flexbox/test/doc_flexbox_CSS_property_with_!important.html @@ -0,0 +1,22 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<style> +.container { + display: flex; + width: 500px; + height: 150px; + margin: 10px; +} + +.item { + background: yellow; + color: red; + flex-grow: 1 !important; + max-width: 350px; + max-width: 400px !important; + padding: 10px; +} +</style> +<div class="container"> + <div class="item" style="flex-grow: 5 !important">Item</div> +</div> diff --git a/devtools/client/inspector/flexbox/test/doc_flexbox_pseudos.html b/devtools/client/inspector/flexbox/test/doc_flexbox_pseudos.html new file mode 100644 index 0000000000..76474cbc37 --- /dev/null +++ b/devtools/client/inspector/flexbox/test/doc_flexbox_pseudos.html @@ -0,0 +1,27 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<style> +.container { + width: 300px; + height: 150px; + margin: 10px; + display: flex; +} + +.container::before, +.container::after { + color: #f06; + border: 1px solid #f06; + background: gold; + padding: 1em; +} + +.container::before { + content: "::before pseudo-element item"; +} + +.container::after { + content: "::after pseudo-element item"; +} +</style> +<div class="container"></div> diff --git a/devtools/client/inspector/flexbox/test/doc_flexbox_specific_cases.html b/devtools/client/inspector/flexbox/test/doc_flexbox_specific_cases.html new file mode 100644 index 0000000000..f5a6aaad24 --- /dev/null +++ b/devtools/client/inspector/flexbox/test/doc_flexbox_specific_cases.html @@ -0,0 +1,121 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<style> +@font-face { + font-family: Ahem; + src: url("Ahem.ttf"); +} +.container { + width: 300px; + height: 150px; + margin: 10px; + display: flex; +} +.container.column { + height: 300px; + width: 150px; + flex-direction: column; +} +.item { + background: #0004; +} +.shrinking .item { + flex-basis: 500px; + flex-shrink: 1; +} +.shrinking.is-clamped .item { + min-width: 350px; +} +.growing .item { + flex-basis: 200px; + flex-grow: 1; +} +.growing.is-clamped .item { + max-width: 250px; +} + +#want-to-grow-more-than-max { + width: 500px; + display: flex; +} +#want-to-grow-more-than-max div { + flex: 1; + max-width: 200px; +} + +#did-not-grow-or-shrink { + width: 500px; + display: flex; +} +#did-not-grow-or-shrink div { + flex: 0 300px; +} + +#just-enough-space-for-clamped-items { + display:flex; + width:100px; + height:40px +} +#just-enough-space-for-clamped-items div:first-child { + flex: 1 300px; + max-width: 20px; + background: teal; +} +#just-enough-space-for-clamped-items div:last-child { + flex: 1 10px; + min-width: 80px; + background: salmon; +} + +#wanted-to-shrink-more-than-basis { + display: flex; + width: 5px; +} +#wanted-to-shrink-more-than-basis div:first-child { + flex: 0 2 200px; + /* Using the Ahem test font to make sure the text has the exact same size on all test + platforms */ + font-family: Ahem; + font-size: 10px; +} +#wanted-to-shrink-more-than-basis div:last-child { + flex: 0 1 200px; +} +</style> +<div id="container" class="container"> + <div class="item">flex item in a row flex container</div> +</div> +<div class="container column"> + <div class="item">flex item in a column flex container</div> +</div> +<div class="container shrinking"> + <div class="item">Shrinking flex item</div> +</div> +<div class="container shrinking is-clamped"> + <div class="item">Shrinking and clamped flex item</div> +</div> +<div class="container growing"> + <div class="item">Growing flex item</div> +</div> +<div class="container growing is-clamped"> + <div class="item">Growing and clamped flex item</div> +</div> +<div id="want-to-grow-more-than-max"> + <div>item wants to grow more</div> +</div> +<div id="did-not-grow-or-shrink"> + <div>item did not grow or shrink</div> +</div> +<div id="just-enough-space-for-clamped-items"> + <div></div> + <div></div> +</div> +<div id="wanted-to-shrink-more-than-basis"> + <div>item wants to shrink more than its basis</div> + <div></div> +</div> +<div class="container" id="container-only"> + <div class="container" id="container-and-item"> + <div id="item-only">This item is inside a container-item element</div> + </div> +</div> diff --git a/devtools/client/inspector/flexbox/test/doc_flexbox_text_nodes.html b/devtools/client/inspector/flexbox/test/doc_flexbox_text_nodes.html new file mode 100644 index 0000000000..626d3aa47e --- /dev/null +++ b/devtools/client/inspector/flexbox/test/doc_flexbox_text_nodes.html @@ -0,0 +1,20 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<style> +.container { + width: 400px; + display: flex; +} +.container div { + flex-basis: 100px; + flex-shrink: 0; + background: #f06; + align-self: stretch; +} +</style> +<div class="container"> + A text node will be wrapped into an anonymous block container + <div></div> + Here is yet another text node +</div> +<div class="container single-child">short text</div> diff --git a/devtools/client/inspector/flexbox/test/doc_flexbox_unauthored_min_dimension.html b/devtools/client/inspector/flexbox/test/doc_flexbox_unauthored_min_dimension.html new file mode 100644 index 0000000000..2f05dbb7f8 --- /dev/null +++ b/devtools/client/inspector/flexbox/test/doc_flexbox_unauthored_min_dimension.html @@ -0,0 +1,29 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<style> +.flex-container { + display: flex; + height: 100vh; +} + +.column { + flex-direction: column; +} + +.flex-child { + height: 100%; + width: 100% +} +</style> +<div class="flex-container"> + <div class="flex-child"></div> + <div id="flex-item-with-unauthored-min-width"> + <h1>AAA</h1> + </div> +</div> +<div class="flex-container column"> + <div class="flex-child"></div> + <div id="flex-item-with-unauthored-min-height"> + <h1>BBB</h1> + </div> +</div> diff --git a/devtools/client/inspector/flexbox/test/doc_flexbox_writing_modes.html b/devtools/client/inspector/flexbox/test/doc_flexbox_writing_modes.html new file mode 100644 index 0000000000..b518c39631 --- /dev/null +++ b/devtools/client/inspector/flexbox/test/doc_flexbox_writing_modes.html @@ -0,0 +1,40 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<style> +.flex-container { + display: flex; +} + +.flex-container.vertical-rl { + writing-mode: vertical-rl; +} + +.flex-container.sideways-lr { + writing-mode: sideways-lr; +} + +.column { + flex-direction: column; +} + +.item { + min-width: 300px; + min-height: 300px; +} + +</style> +<div class="flex-container vertical-rl"> + <span class="row vertical-rl item">Vertical-tb Row content</span> +</div> +<div class="flex-container column"> + <span class="column vertical-tb item">Vertical-tb Column Content</span> +</div> +<div class="flex-container sideways-lr"> + <span class="row vertical-bt item">Vertical-bt Row Content</span> +</div> +<div class="flex-container vertical-rl column"> + <span class="column horizontal-rl item">Horizontal-rl Column Content</span> +</div> +<div class="flex-container"> + <span class="row horizontal-lr item">Horizontal-lr Row Content</span> +</div> diff --git a/devtools/client/inspector/flexbox/test/head.js b/devtools/client/inspector/flexbox/test/head.js new file mode 100644 index 0000000000..269dcea904 --- /dev/null +++ b/devtools/client/inspector/flexbox/test/head.js @@ -0,0 +1,81 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ +/* eslint no-unused-vars: [2, {"vars": "local"}] */ + +"use strict"; + +// Import the inspector's head.js first (which itself imports shared-head.js). +Services.scriptloader.loadSubScript( + "chrome://mochitests/content/browser/devtools/client/inspector/test/head.js", + this +); + +const FLEXBOX_OPENED_PREF = "devtools.layout.flexbox.opened"; +const FLEX_CONTAINER_OPENED_PREF = "devtools.layout.flex-container.opened"; +const FLEX_ITEM_OPENED_PREF = "devtools.layout.flex-item.opened"; +const GRID_OPENED_PREF = "devtools.layout.grid.opened"; +const BOXMODEL_OPENED_PREF = "devtools.layout.boxmodel.opened"; + +// Make sure only the flexbox layout accordions are opened, and the others are closed. +Services.prefs.setBoolPref(FLEXBOX_OPENED_PREF, true); +Services.prefs.setBoolPref(FLEX_CONTAINER_OPENED_PREF, true); +Services.prefs.setBoolPref(FLEX_ITEM_OPENED_PREF, true); +Services.prefs.setBoolPref(BOXMODEL_OPENED_PREF, false); +Services.prefs.setBoolPref(GRID_OPENED_PREF, false); + +// Clear all set prefs. +registerCleanupFunction(() => { + Services.prefs.clearUserPref(FLEXBOX_OPENED_PREF); + Services.prefs.clearUserPref(FLEX_CONTAINER_OPENED_PREF); + Services.prefs.clearUserPref(FLEX_ITEM_OPENED_PREF); + Services.prefs.clearUserPref(BOXMODEL_OPENED_PREF); + Services.prefs.clearUserPref(GRID_OPENED_PREF); +}); + +/** + * Toggles ON the flexbox highlighter given the flexbox highlighter button from the + * layout panel. + * + * @param {DOMNode} button + * The flexbox highlighter toggle button in the flex container panel. + * @param {Inspector} inspector + * Inspector panel instance. + */ +async function toggleHighlighterON(button, inspector) { + info("Toggling ON the flexbox highlighter from the layout panel."); + const { waitForHighlighterTypeShown } = getHighlighterTestHelpers(inspector); + const onHighlighterShown = waitForHighlighterTypeShown( + inspector.highlighters.TYPES.FLEXBOX + ); + const { store } = inspector; + const onToggleChange = waitUntilState( + store, + state => state.flexbox.highlighted + ); + button.click(); + await Promise.all([onHighlighterShown, onToggleChange]); +} + +/** + * Toggles OFF the flexbox highlighter given the flexbox highlighter button from the + * layout panel. + * + * @param {DOMNode} button + * The flexbox highlighter toggle button in the flex container panel. + * @param {Inspector} inspector + * Inspector panel instance. + */ +async function toggleHighlighterOFF(button, inspector) { + info("Toggling OFF the flexbox highlighter from the layout panel."); + const { waitForHighlighterTypeHidden } = getHighlighterTestHelpers(inspector); + const onHighlighterHidden = waitForHighlighterTypeHidden( + inspector.highlighters.TYPES.FLEXBOX + ); + const { store } = inspector; + const onToggleChange = waitUntilState( + store, + state => !state.flexbox.highlighted + ); + button.click(); + await Promise.all([onHighlighterHidden, onToggleChange]); +} |