summaryrefslogtreecommitdiffstats
path: root/devtools/client/inspector/flexbox/test
diff options
context:
space:
mode:
Diffstat (limited to 'devtools/client/inspector/flexbox/test')
-rw-r--r--devtools/client/inspector/flexbox/test/Ahem.ttfbin0 -> 12480 bytes
-rw-r--r--devtools/client/inspector/flexbox/test/browser.ini54
-rw-r--r--devtools/client/inspector/flexbox/test/browser_flexbox_accordion_state.js120
-rw-r--r--devtools/client/inspector/flexbox/test/browser_flexbox_container_and_item.js43
-rw-r--r--devtools/client/inspector/flexbox/test/browser_flexbox_container_and_item_accordion_state.js107
-rw-r--r--devtools/client/inspector/flexbox/test/browser_flexbox_container_and_item_updates_on_change.js54
-rw-r--r--devtools/client/inspector/flexbox/test/browser_flexbox_container_element_rep.js51
-rw-r--r--devtools/client/inspector/flexbox/test/browser_flexbox_container_properties.js59
-rw-r--r--devtools/client/inspector/flexbox/test/browser_flexbox_empty_state.js24
-rw-r--r--devtools/client/inspector/flexbox/test/browser_flexbox_grand_parent_flex.js55
-rw-r--r--devtools/client/inspector/flexbox/test/browser_flexbox_highlighter_color_picker_on_ESC.js71
-rw-r--r--devtools/client/inspector/flexbox/test/browser_flexbox_highlighter_color_picker_on_RETURN.js92
-rw-r--r--devtools/client/inspector/flexbox/test/browser_flexbox_highlighter_opened_telemetry.js37
-rw-r--r--devtools/client/inspector/flexbox/test/browser_flexbox_item_list_01.js49
-rw-r--r--devtools/client/inspector/flexbox/test/browser_flexbox_item_list_02.js35
-rw-r--r--devtools/client/inspector/flexbox/test/browser_flexbox_item_list_updates_on_change.js47
-rw-r--r--devtools/client/inspector/flexbox/test/browser_flexbox_item_outline_exists.js30
-rw-r--r--devtools/client/inspector/flexbox/test/browser_flexbox_item_outline_has_correct_layout.js67
-rw-r--r--devtools/client/inspector/flexbox/test/browser_flexbox_item_outline_hidden_when_useless.js46
-rw-r--r--devtools/client/inspector/flexbox/test/browser_flexbox_item_outline_renders_basisfinal_points_correctly.js40
-rw-r--r--devtools/client/inspector/flexbox/test/browser_flexbox_item_outline_rotates_for_column.js49
-rw-r--r--devtools/client/inspector/flexbox/test/browser_flexbox_item_outline_rotates_for_different_writing_modes.js42
-rw-r--r--devtools/client/inspector/flexbox/test/browser_flexbox_non_flex_item_is_not_shown.js30
-rw-r--r--devtools/client/inspector/flexbox/test/browser_flexbox_pseudo_elements_are_listed.js28
-rw-r--r--devtools/client/inspector/flexbox/test/browser_flexbox_sizing_flexibility_not_displayed_when_useless.js48
-rw-r--r--devtools/client/inspector/flexbox/test/browser_flexbox_sizing_info_do_not_show_unspecified_min_dimension.js45
-rw-r--r--devtools/client/inspector/flexbox/test/browser_flexbox_sizing_info_exists.js36
-rw-r--r--devtools/client/inspector/flexbox/test/browser_flexbox_sizing_info_for_different_writing_modes.js75
-rw-r--r--devtools/client/inspector/flexbox/test/browser_flexbox_sizing_info_for_pseudos.js40
-rw-r--r--devtools/client/inspector/flexbox/test/browser_flexbox_sizing_info_for_text_nodes.js40
-rw-r--r--devtools/client/inspector/flexbox/test/browser_flexbox_sizing_info_has_correct_sections.js86
-rw-r--r--devtools/client/inspector/flexbox/test/browser_flexbox_sizing_info_matches_properties_with_!important.js41
-rw-r--r--devtools/client/inspector/flexbox/test/browser_flexbox_sizing_info_updates_on_change.js50
-rw-r--r--devtools/client/inspector/flexbox/test/browser_flexbox_sizing_wanted_to_grow_but_was_clamped.js44
-rw-r--r--devtools/client/inspector/flexbox/test/browser_flexbox_text_nodes_are_listed.js28
-rw-r--r--devtools/client/inspector/flexbox/test/browser_flexbox_text_nodes_are_not_inlined.js52
-rw-r--r--devtools/client/inspector/flexbox/test/browser_flexbox_toggle_flexbox_highlighter_01.js55
-rw-r--r--devtools/client/inspector/flexbox/test/browser_flexbox_toggle_flexbox_highlighter_02.js102
-rw-r--r--devtools/client/inspector/flexbox/test/doc_flexbox_CSS_property_with_!important.html22
-rw-r--r--devtools/client/inspector/flexbox/test/doc_flexbox_pseudos.html27
-rw-r--r--devtools/client/inspector/flexbox/test/doc_flexbox_specific_cases.html121
-rw-r--r--devtools/client/inspector/flexbox/test/doc_flexbox_text_nodes.html20
-rw-r--r--devtools/client/inspector/flexbox/test/doc_flexbox_unauthored_min_dimension.html29
-rw-r--r--devtools/client/inspector/flexbox/test/doc_flexbox_writing_modes.html40
-rw-r--r--devtools/client/inspector/flexbox/test/head.js81
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
new file mode 100644
index 0000000000..ac81cb0316
--- /dev/null
+++ b/devtools/client/inspector/flexbox/test/Ahem.ttf
Binary files differ
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]);
+}