Bug 1780912 - [devtools] Open toolboxes for local WebExtension in dedicated window. r=jdescottes

This should hopefully help debug addons displaying panels/popups.

Differential Revision: https://phabricator.services.mozilla.com/D155393
This commit is contained in:
Alexandre Poirot 2022-09-07 21:00:17 +00:00
Родитель e3d1d71728
Коммит 8792e1fba5
12 изменённых файлов: 108 добавлений и 53 удалений

Просмотреть файл

@ -26,7 +26,10 @@ const {
getCurrentRuntime,
} = require("devtools/client/aboutdebugging/src/modules/runtimes-state-helper");
const { gDevTools } = require("devtools/client/framework/devtools");
const {
DEBUG_TARGETS,
DEBUG_TARGET_PANE,
REQUEST_EXTENSIONS_FAILURE,
REQUEST_EXTENSIONS_START,
@ -73,29 +76,39 @@ function inspectDebugTarget(type, id) {
return async ({ dispatch, getState }) => {
const runtime = getCurrentRuntime(getState().runtimes);
const urlParams = {
id,
type,
};
if (runtime.id !== RUNTIMES.THIS_FIREFOX) {
urlParams.remoteId = remoteClientManager.getRemoteId(
runtime.id,
runtime.type
);
}
const url = `about:devtools-toolbox?${new window.URLSearchParams(
urlParams
)}`;
const existingTab = getTabForUrl(url);
if (existingTab) {
const navigator = existingTab.ownerGlobal;
navigator.gBrowser.selectedTab = existingTab;
navigator.focus();
if (
type == DEBUG_TARGETS.EXTENSION &&
runtime.id === RUNTIMES.THIS_FIREFOX
) {
// Bug 1780912: To avoid UX issues when debugging local web extensions,
// we are opening the toolbox in an independant window.
// Whereas all others are opened in new tabs.
gDevTools.showToolboxForWebExtension(id);
} else {
window.open(url);
const urlParams = {
id,
type,
};
if (runtime.id !== RUNTIMES.THIS_FIREFOX) {
urlParams.remoteId = remoteClientManager.getRemoteId(
runtime.id,
runtime.type
);
}
const url = `about:devtools-toolbox?${new window.URLSearchParams(
urlParams
)}`;
const existingTab = getTabForUrl(url);
if (existingTab) {
const navigator = existingTab.ownerGlobal;
navigator.gBrowser.selectedTab = existingTab;
navigator.focus();
} else {
window.open(url);
}
}
dispatch(

Просмотреть файл

@ -75,6 +75,7 @@ class DebugTargetItem extends PureComponent {
return dom.li(
{
className: "card debug-target-item qa-debug-target-item",
"data-qa-target-type": this.props.target.type,
},
this.renderIcon(),
this.renderName(),

Просмотреть файл

@ -134,7 +134,7 @@ add_task(async function testWebExtensionsToolboxWebConsole() {
document
);
const { devtoolsTab, devtoolsWindow } = await openAboutDevtoolsToolbox(
const { devtoolsWindow } = await openAboutDevtoolsToolbox(
document,
tab,
window,
@ -250,7 +250,7 @@ add_task(async function testWebExtensionsToolboxWebConsole() {
// And we received the evaluation result
await onEvaluationResultAfterReload;
await closeAboutDevtoolsToolbox(document, devtoolsTab, window);
await closeWebExtAboutDevtoolsToolbox(devtoolsWindow, window);
// Note that it seems to be important to remove the addons in the reverse order
// from which they were installed...
@ -301,7 +301,7 @@ add_task(async function testWebExtensionNoBgScript() {
document
);
const { devtoolsTab, devtoolsWindow } = await openAboutDevtoolsToolbox(
const { devtoolsWindow } = await openAboutDevtoolsToolbox(
document,
tab,
window,
@ -340,7 +340,7 @@ add_task(async function testWebExtensionNoBgScript() {
"We get the addon's popup CSS error message"
);
await closeAboutDevtoolsToolbox(document, devtoolsTab, window);
await closeWebExtAboutDevtoolsToolbox(devtoolsWindow, window);
await removeTemporaryExtension(POPUPONLY_ADDON_NAME, document);
await removeTab(tab);
});
@ -383,7 +383,7 @@ add_task(async function testWebExtensionTwoReloads() {
// instead.
const addonTarget = findDebugTargetByText(BACKGROUND_ADDON_NAME, document);
const { devtoolsTab, devtoolsWindow } = await openAboutDevtoolsToolbox(
const { devtoolsWindow } = await openAboutDevtoolsToolbox(
document,
tab,
window,
@ -431,7 +431,7 @@ add_task(async function testWebExtensionTwoReloads() {
hud.ui.wrapper.dispatchEvaluateExpression("40+2");
await waitUntil(() => findMessageByType(hud, "42", ".result"));
await closeAboutDevtoolsToolbox(document, devtoolsTab, window);
await closeWebExtAboutDevtoolsToolbox(devtoolsWindow, window);
await removeTemporaryExtension(BACKGROUND_ADDON_NAME, document);
await removeTab(tab);
});

Просмотреть файл

@ -35,7 +35,7 @@ add_task(async () => {
document
);
const { devtoolsTab, devtoolsWindow } = await openAboutDevtoolsToolbox(
const { devtoolsWindow } = await openAboutDevtoolsToolbox(
document,
tab,
window,
@ -59,7 +59,7 @@ add_task(async () => {
"Extension name displays correctly"
);
await closeAboutDevtoolsToolbox(document, devtoolsTab, window);
await closeWebExtAboutDevtoolsToolbox(devtoolsWindow, window);
await removeTemporaryExtension(EXTENSION_NAME, document);
await removeTab(tab);
});

Просмотреть файл

@ -40,7 +40,7 @@ add_task(async function testWebExtensionsToolboxWebConsole() {
);
info("Open a toolbox to debug the addon");
const { devtoolsTab, devtoolsWindow } = await openAboutDevtoolsToolbox(
const { devtoolsWindow } = await openAboutDevtoolsToolbox(
document,
tab,
window,
@ -80,7 +80,7 @@ add_task(async function testWebExtensionsToolboxWebConsole() {
"The dark color scheme simulation button exists and is hidden"
);
await closeAboutDevtoolsToolbox(document, devtoolsTab, window);
await closeWebExtAboutDevtoolsToolbox(devtoolsWindow, window);
await removeTemporaryExtension(ADDON_NAME, document);
await removeTab(tab);
});

Просмотреть файл

@ -37,7 +37,7 @@ add_task(async function testWebExtensionsToolboxNoBackgroundPage() {
);
info("Open a toolbox to debug the addon");
const { devtoolsTab, devtoolsWindow } = await openAboutDevtoolsToolbox(
const { devtoolsWindow } = await openAboutDevtoolsToolbox(
document,
tab,
window,
@ -70,7 +70,7 @@ add_task(async function testWebExtensionsToolboxNoBackgroundPage() {
"nodeActor has the expected inlineTextChild value"
);
await closeAboutDevtoolsToolbox(document, devtoolsTab, window);
await closeWebExtAboutDevtoolsToolbox(devtoolsWindow, window);
await removeTemporaryExtension(ADDON_NOBG_NAME, document);
await removeTab(tab);
});

Просмотреть файл

@ -57,12 +57,13 @@ add_task(async function testWebExtensionsToolboxWebConsole() {
);
info("Open a toolbox to debug the addon");
const { devtoolsTab, devtoolsWindow } = await openAboutDevtoolsToolbox(
const { devtoolsWindow } = await openAboutDevtoolsToolbox(
document,
tab,
aboutDebuggingWindow,
ADDON_NAME
);
const toolbox = getToolbox(devtoolsWindow);
const webconsole = await toolbox.selectTool("webconsole");
@ -117,7 +118,7 @@ add_task(async function testWebExtensionsToolboxWebConsole() {
"Got the expected manifest from WebExtension API"
);
await closeAboutDevtoolsToolbox(document, devtoolsTab, aboutDebuggingWindow);
await closeWebExtAboutDevtoolsToolbox(devtoolsWindow, aboutDebuggingWindow);
is(
Services.prefs.getBoolPref("ui.popup.disable_autohide"),
@ -230,7 +231,6 @@ async function waitForExtension(addonName) {
*/
function disablePopupAutohide(toolbox) {
return new Promise(resolve => {
toolbox.doc.getElementById("toolbox-meatball-menu-button").click();
toolbox.doc.addEventListener(
"popupshown",
() => {
@ -242,5 +242,6 @@ function disablePopupAutohide(toolbox) {
},
{ once: true }
);
toolbox.doc.getElementById("toolbox-meatball-menu-button").click();
});
}

Просмотреть файл

@ -40,11 +40,12 @@ add_task(async function testWebExtensionToolboxReload() {
document
);
const {
devtoolsDocument,
devtoolsTab,
devtoolsWindow,
} = await openAboutDevtoolsToolbox(document, tab, window, ADDON_NAME);
const { devtoolsDocument, devtoolsWindow } = await openAboutDevtoolsToolbox(
document,
tab,
window,
ADDON_NAME
);
const toolbox = getToolbox(devtoolsWindow);
ok(
@ -123,7 +124,7 @@ add_task(async function testWebExtensionToolboxReload() {
await waitForLoadedPanelsReload();
await closeAboutDevtoolsToolbox(document, devtoolsTab, window);
await closeWebExtAboutDevtoolsToolbox(devtoolsWindow, window);
await removeTemporaryExtension(ADDON_NAME, document);
await removeTab(tab);
});

Просмотреть файл

@ -40,7 +40,7 @@ add_task(async () => {
document
);
const { devtoolsTab, devtoolsWindow } = await openAboutDevtoolsToolbox(
const { devtoolsWindow } = await openAboutDevtoolsToolbox(
document,
tab,
window,
@ -84,7 +84,7 @@ add_task(async () => {
is(user2.name, "Bob", "user 2 has the expected name");
is(user2.age, 24, "user 2 has the expected age");
await closeAboutDevtoolsToolbox(document, devtoolsTab, window);
await closeWebExtAboutDevtoolsToolbox(devtoolsWindow, window);
await removeTemporaryExtension(EXTENSION_NAME, document);
await removeTab(tab);
});

Просмотреть файл

@ -86,7 +86,7 @@ add_task(
});
info("Open a DevTools toolbox on the target extension");
const { devtoolsTab, devtoolsWindow } = await openAboutDevtoolsToolbox(
const { devtoolsWindow } = await openAboutDevtoolsToolbox(
document,
tab,
window,
@ -183,7 +183,7 @@ add_task(
"Verify event page is terminated on idle after closing the DevTools toolbox"
);
await closeAboutDevtoolsToolbox(document, devtoolsTab, window);
await closeWebExtAboutDevtoolsToolbox(devtoolsWindow, window);
await triggerExtensionEventPageIdleTimeout(EXTENSION_ID);
await waitForBGStatusUpdate;
await assertBackgroundStatus(EXTENSION_NAME, {

Просмотреть файл

@ -54,7 +54,7 @@ add_task(async function testNodePickerInExtensionPopup() {
document
);
const { devtoolsTab, devtoolsWindow } = await openAboutDevtoolsToolbox(
const { devtoolsWindow } = await openAboutDevtoolsToolbox(
document,
tab,
window,
@ -93,7 +93,7 @@ add_task(async function testNodePickerInExtensionPopup() {
const nodeFront = await onNewNodeFront;
is(nodeFront.id, "pick-me", "The expected node front was selected");
await closeAboutDevtoolsToolbox(document, devtoolsTab, window);
await closeWebExtAboutDevtoolsToolbox(devtoolsWindow, window);
await removeTemporaryExtension(ADDON_NAME, document);
await removeTab(tab);
});

Просмотреть файл

@ -85,17 +85,34 @@ async function openAboutDevtoolsToolbox(
info("Open about:devtools-toolbox page");
const target = findDebugTargetByText(targetText, doc);
ok(target, `${targetText} tab target appeared`);
const {
DEBUG_TARGETS,
} = require("devtools/client/aboutdebugging/src/constants");
const isWebExtension = target.dataset.qaTargetType == DEBUG_TARGETS.EXTENSION;
const inspectButton = target.querySelector(".qa-debug-target-inspect-button");
ok(inspectButton, `Inspect button for ${targetText} appeared`);
inspectButton.click();
const onToolboxReady = gDevTools.once("toolbox-ready");
await Promise.all([
waitUntil(() => tab.nextElementSibling),
waitForAboutDebuggingRequests(win.AboutDebugging.store),
shouldWaitToolboxReady
? gDevTools.once("toolbox-ready")
: Promise.resolve(),
shouldWaitToolboxReady ? onToolboxReady : Promise.resolve(),
]);
// WebExtension open a toolbox in a dedicated window
if (isWebExtension) {
const toolbox = await onToolboxReady;
return {
devtoolsBrowser: null,
devtoolsDocument: toolbox.doc,
devtoolsTab: null,
devtoolsWindow: toolbox.win,
};
}
await waitUntil(() => tab.nextElementSibling);
info("Wait for about:devtools-toolbox tab will be selected");
const devtoolsTab = tab.nextElementSibling;
await waitUntil(() => gBrowser.selectedTab === devtoolsTab);
@ -155,6 +172,17 @@ async function closeAboutDevtoolsToolbox(
await waitForAboutDebuggingRequests(win.AboutDebugging.store);
}
async function closeWebExtAboutDevtoolsToolbox(devtoolsWindow, win) {
// Wait for all requests to settle on the opened about:devtools toolbox.
const toolbox = getToolbox(devtoolsWindow);
await toolbox.commands.client.waitForRequestsToSettle();
info("Close the toolbox and wait for its destruction");
await toolbox.destroy();
await waitForAboutDebuggingRequests(win.AboutDebugging.store);
}
async function reloadAboutDebugging(tab) {
info("reload about:debugging");
@ -443,6 +471,12 @@ async function synthesizeUrlKeyInput(toolbox, inputEl, url) {
* The ID of the add-on to click on.
*/
function clickOnAddonWidget(addonId) {
// Devtools are in another window and may have the focus.
// Ensure focusing the browser window when clicking on the widget.
const focusedWin = Services.focus.focusedWindow;
if (focusedWin != window) {
window.focus();
}
// Find the browserAction button that will show the webextension popup.
const widgetId = addonId.toLowerCase().replace(/[^a-z0-9_-]/g, "_");
const browserActionId = widgetId + "-browser-action";
@ -451,4 +485,9 @@ function clickOnAddonWidget(addonId) {
info("Show the web extension popup");
browserActionEl.click();
// And restore the focus right after having clicked.
if (focusedWin != window) {
focusedWin.focus();
}
}