fune/devtools/client/webconsole/test/browser/browser_webconsole_split.js
Emilio Cobos Álvarez 9dccf6f405 Bug 1792473 - Use modern flex emulation in devtools. r=devtools-reviewers,jdescottes
This shouldn't have any behavior change, other than avoiding XUL / CSS
interaction issues.

I had to tweak a bit a few of the webconsole split styles to preserve
behavior (even though without the styles it ends up working out because
the collapsed console would be out of view anyways).

The reason for the changes are:

 * visibility: collapse doesn't prevent min-height from applying on
   modern flexbox. So just collapse it using height properly. We need to
   use !important, at least on height, to override the style attribute
   set by the splitter.

 * Tweak the splitting setup of the console a bit more to match legacy
   behavior.

 * I need to contain: size on some scrollers and replaced elements so
   that they flex properly rather than taking as much space as they need
   (this kinda sucks but oh well). We could set min-width/height: 0
   instead if you think it's easier to understand but contain is more
   robust.

I needed to adjust the test since the fractional part of the container
wasn't getting rounded on my machine, but that's a pre-existing issue
that happens with my DPI settings both before and after the patch.

Differential Revision: https://phabricator.services.mozilla.com/D158183
2022-09-29 20:58:54 +00:00

365 lines
10 KiB
JavaScript

/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
const TEST_URI =
"data:text/html;charset=utf-8,<!DOCTYPE html>Web Console test for splitting";
// Test is slow on Linux EC2 instances - Bug 962931
requestLongerTimeout(4);
add_task(async function() {
let toolbox;
const getFluentString = await getFluentStringHelper([
"devtools/client/toolbox.ftl",
]);
const hideSplitConsoleLabel = getFluentString(
"toolbox-meatball-menu-hideconsole-label"
);
await addTab(TEST_URI);
await testConsoleLoadOnDifferentPanel();
await testKeyboardShortcuts();
await checkAllTools();
info("Testing host types");
checkHostType(Toolbox.HostType.BOTTOM);
await checkToolboxUI();
await toolbox.switchHost(Toolbox.HostType.RIGHT);
checkHostType(Toolbox.HostType.RIGHT);
await checkToolboxUI();
await toolbox.switchHost(Toolbox.HostType.WINDOW);
// checkHostType, below, will open the meatball menu to read the "Split
// console" menu item label. However, if we've just opened a new window then
// on some platforms when we switch focus to the new window we might end up
// triggering the auto-close behavior on the menu popup. To avoid that, wait
// a moment before querying the menu.
await new Promise(resolve => requestIdleCallback(resolve));
checkHostType(Toolbox.HostType.WINDOW);
await checkToolboxUI();
await toolbox.switchHost(Toolbox.HostType.BOTTOM);
async function testConsoleLoadOnDifferentPanel() {
info("About to check console loads even when non-webconsole panel is open");
await openPanel("inspector");
const webconsoleReady = toolbox.once("webconsole-ready");
await toolbox.toggleSplitConsole();
await webconsoleReady;
ok(
true,
"Webconsole has been triggered as loaded while another tool is active"
);
}
async function testKeyboardShortcuts() {
info("About to check that panel responds to ESCAPE keyboard shortcut");
const splitConsoleReady = toolbox.once("split-console");
EventUtils.sendKey("ESCAPE", toolbox.win);
await splitConsoleReady;
ok(true, "Split console has been triggered via ESCAPE keypress");
}
async function checkAllTools() {
info("About to check split console with each panel individually.");
await openAndCheckPanel("jsdebugger");
await openAndCheckPanel("inspector");
await openAndCheckPanel("styleeditor");
await openAndCheckPanel("performance");
await openAndCheckPanel("netmonitor");
await checkWebconsolePanelOpened();
}
async function getCurrentUIState() {
const deck = toolbox.doc.querySelector("#toolbox-deck");
const webconsolePanel = toolbox.webconsolePanel;
const splitter = toolbox.doc.querySelector("#toolbox-console-splitter");
const containerHeight = deck.parentNode.getBoundingClientRect().height;
const deckHeight = deck.getBoundingClientRect().height;
const webconsoleHeight = webconsolePanel.getBoundingClientRect().height;
const splitterVisibility = !splitter.hidden;
// Splitter height will be 1px since the margin is negative.
const splitterHeight = splitterVisibility ? 1 : 0;
const openedConsolePanel = toolbox.currentToolId === "webconsole";
const menuLabel = await getMenuLabel(toolbox);
return {
deckHeight,
containerHeight,
webconsoleHeight,
splitterVisibility,
splitterHeight,
openedConsolePanel,
menuLabel,
};
}
async function getMenuLabel() {
const button = toolbox.doc.getElementById("toolbox-meatball-menu-button");
const onPopupShown = new Promise(
resolve => {
toolbox.doc.addEventListener("popupshown", () => resolve());
},
{ once: true }
);
info("Click on menu and wait for the popup to be visible");
AccessibilityUtils.setEnv({
// Toobox toolbar buttons are handled with arrow keys.
nonNegativeTabIndexRule: false,
});
EventUtils.sendMouseEvent({ type: "click" }, button);
AccessibilityUtils.resetEnv();
await onPopupShown;
const menuItem = toolbox.doc.getElementById(
"toolbox-meatball-menu-splitconsole"
);
// Return undefined if the menu item is not available
let label;
if (menuItem && menuItem.querySelector(".label")) {
label =
menuItem.querySelector(".label").textContent === hideSplitConsoleLabel
? "hide"
: "split";
}
// Wait for menu to close
const onPopupHide = new Promise(resolve => {
toolbox.doc.addEventListener(
"popuphidden",
() => {
resolve(label);
},
{ once: true }
);
});
info("Hit escape and wait for the popup to be closed");
EventUtils.sendKey("ESCAPE", toolbox.win);
await onPopupHide;
return label;
}
async function checkWebconsolePanelOpened() {
info("About to check special cases when webconsole panel is open.");
// Start with console split, so we can test for transition to main panel.
await toolbox.toggleSplitConsole();
let currentUIState = await getCurrentUIState();
ok(
currentUIState.splitterVisibility,
"Splitter is visible when console is split"
);
ok(
currentUIState.deckHeight > 0,
"Deck has a height > 0 when console is split"
);
ok(
currentUIState.webconsoleHeight > 0,
"Web console has a height > 0 when console is split"
);
ok(
!currentUIState.openedConsolePanel,
"The console panel is not the current tool"
);
is(
currentUIState.menuLabel,
"hide",
"The menu item indicates the console is split"
);
await openPanel("webconsole");
currentUIState = await getCurrentUIState();
ok(
!currentUIState.splitterVisibility,
"Splitter is hidden when console is opened."
);
is(
currentUIState.deckHeight,
0,
"Deck has a height == 0 when console is opened."
);
is(
currentUIState.webconsoleHeight,
currentUIState.containerHeight,
"Web console is full height."
);
ok(
currentUIState.openedConsolePanel,
"The console panel is the current tool"
);
is(
currentUIState.menuLabel,
undefined,
"The menu item is hidden when console is opened"
);
// Make sure splitting console does nothing while webconsole is opened
await toolbox.toggleSplitConsole();
currentUIState = await getCurrentUIState();
ok(
!currentUIState.splitterVisibility,
"Splitter is hidden when console is opened."
);
is(
currentUIState.deckHeight,
0,
"Deck has a height == 0 when console is opened."
);
is(
currentUIState.webconsoleHeight,
currentUIState.containerHeight,
"Web console is full height."
);
ok(
currentUIState.openedConsolePanel,
"The console panel is the current tool"
);
is(
currentUIState.menuLabel,
undefined,
"The menu item is hidden when console is opened"
);
// Make sure that split state is saved after opening another panel
await openPanel("inspector");
currentUIState = await getCurrentUIState();
ok(
currentUIState.splitterVisibility,
"Splitter is visible when console is split"
);
ok(
currentUIState.deckHeight > 0,
"Deck has a height > 0 when console is split"
);
ok(
currentUIState.webconsoleHeight > 0,
"Web console has a height > 0 when console is split"
);
ok(
!currentUIState.openedConsolePanel,
"The console panel is not the current tool"
);
is(
currentUIState.menuLabel,
"hide",
"The menu item still indicates the console is split"
);
await toolbox.toggleSplitConsole();
}
async function checkToolboxUI() {
let currentUIState = await getCurrentUIState();
ok(!currentUIState.splitterVisibility, "Splitter is hidden by default");
is(
currentUIState.deckHeight,
currentUIState.containerHeight,
"Deck has a height > 0 by default"
);
is(
currentUIState.webconsoleHeight,
0,
"Web console is collapsed by default"
);
ok(
!currentUIState.openedConsolePanel,
"The console panel is not the current tool"
);
is(
currentUIState.menuLabel,
"split",
"The menu item indicates the console is not split"
);
await toolbox.toggleSplitConsole();
currentUIState = await getCurrentUIState();
ok(
currentUIState.splitterVisibility,
"Splitter is visible when console is split"
);
ok(
currentUIState.deckHeight > 0,
"Deck has a height > 0 when console is split"
);
ok(
currentUIState.webconsoleHeight > 0,
"Web console has a height > 0 when console is split"
);
is(
Math.round(
currentUIState.deckHeight +
currentUIState.webconsoleHeight +
currentUIState.splitterHeight
),
Math.round(currentUIState.containerHeight),
"Everything adds up to container height"
);
ok(
!currentUIState.openedConsolePanel,
"The console panel is not the current tool"
);
is(
currentUIState.menuLabel,
"hide",
"The menu item indicates the console is split"
);
await toolbox.toggleSplitConsole();
currentUIState = await getCurrentUIState();
ok(!currentUIState.splitterVisibility, "Splitter is hidden after toggling");
is(
currentUIState.deckHeight,
currentUIState.containerHeight,
"Deck has a height > 0 after toggling"
);
is(
currentUIState.webconsoleHeight,
0,
"Web console is collapsed after toggling"
);
ok(
!currentUIState.openedConsolePanel,
"The console panel is not the current tool"
);
is(
currentUIState.menuLabel,
"split",
"The menu item indicates the console is not split"
);
}
async function openPanel(toolId) {
const tab = gBrowser.selectedTab;
toolbox = await gDevTools.showToolboxForTab(tab, { toolId });
}
async function openAndCheckPanel(toolId) {
await openPanel(toolId);
await checkToolboxUI(toolbox.getCurrentPanel());
}
function checkHostType(hostType) {
is(toolbox.hostType, hostType, "host type is " + hostType);
const pref = Services.prefs.getCharPref("devtools.toolbox.host");
is(pref, hostType, "host pref is " + hostType);
}
});