--- a/browser/components/extensions/test/browser/browser_ext_devtools_panel.js
+++ b/browser/components/extensions/test/browser/browser_ext_devtools_panel.js
@@ -35,16 +35,45 @@ async function testThemeSwitching(extens
`The onThemeChanged event listener fired for the ${location}.`);
is(await extension.awaitMessage(`current_theme_${location}`),
newTheme,
`The current theme is reported as expected for the ${location}.`);
}
}
}
+add_task(async function setup_blank_panel() {
+ // Create a blank custom tool so that we don't need to wait the webconsole
+ // to be fully loaded/unloaded to prevent intermittent failures (related
+ // to a webconsole that is still loading when the test has been completed).
+ const testBlankPanel = {
+ id: "testBlankPanel",
+ url: "about:blank",
+ label: "Blank Tool",
+ isTargetSupported() {
+ return true;
+ },
+ build(iframeWindow, toolbox) {
+ return Promise.resolve({
+ target: toolbox.target,
+ toolbox: toolbox,
+ isReady: true,
+ panelDoc: iframeWindow.document,
+ destroy() {},
+ });
+ },
+ };
+
+ registerCleanupFunction(() => {
+ gDevTools.unregisterTool(testBlankPanel.id);
+ });
+
+ gDevTools.registerTool(testBlankPanel);
+});
+
add_task(async function test_theme_name_no_panel() {
let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, "http://mochi.test:8888/");
async function devtools_page() {
browser.devtools.panels.onThemeChanged.addListener(themeName => {
browser.test.sendMessage("devtools_theme_changed_page", themeName);
browser.test.sendMessage("current_theme_page", browser.devtools.panels.themeName);
});
@@ -71,17 +100,17 @@ add_task(async function test_theme_name_
});
// Ensure that the initial value of the devtools theme is "light".
await SpecialPowers.pushPrefEnv({set: [[DEVTOOLS_THEME_PREF, "light"]]});
await extension.startup();
let target = gDevTools.getTargetForTab(tab);
- await gDevTools.showToolbox(target, "webconsole");
+ await gDevTools.showToolbox(target, "testBlankPanel");
info("developer toolbox opened");
is(await extension.awaitMessage("initial_theme"),
"light",
"The initial theme is reported as expected.");
await testThemeSwitching(extension);
@@ -191,17 +220,17 @@ add_task(async function test_devtools_pa
// Ensure that the initial value of the devtools theme is "light".
Preferences.set(DEVTOOLS_THEME_PREF, "light");
await extension.startup();
let target = gDevTools.getTargetForTab(tab);
- const toolbox = await gDevTools.showToolbox(target, "webconsole");
+ const toolbox = await gDevTools.showToolbox(target, "testBlankPanel");
info("developer toolbox opened");
await extension.awaitMessage("devtools_panel_created");
is(await extension.awaitMessage("initial_theme_page"),
"light",
"The initial theme is reported as expected from a devtools page.");
const toolboxAdditionalTools = toolbox.getAdditionalTools();
@@ -221,29 +250,29 @@ add_task(async function test_devtools_pa
"Got the same devtools.inspectedWindow.tabId from devtools page and panel");
is(await extension.awaitMessage("initial_theme_panel"),
"light",
"The initial theme is reported as expected from a devtools panel.");
info("Addon Devtools Panel shown");
await testThemeSwitching(extension, ["page", "panel"]);
- await gDevTools.showToolbox(target, "webconsole");
+ await gDevTools.showToolbox(target, "testBlankPanel");
const results = await extension.awaitMessage("devtools_panel_hidden");
info("Addon Devtools Panel hidden");
is(results.panelCreated, 1, "devtools.panel.create callback has been called once");
is(results.panelShown, 1, "panel.onShown listener has been called once");
is(results.panelHidden, 1, "panel.onHidden listener has been called once");
await gDevTools.showToolbox(target, panelId);
await extension.awaitMessage("devtools_panel_shown");
info("Addon Devtools Panel shown - second cycle");
- await gDevTools.showToolbox(target, "webconsole");
+ await gDevTools.showToolbox(target, "testBlankPanel");
const secondCycleResults = await extension.awaitMessage("devtools_panel_hidden");
info("Addon Devtools Panel hidden - second cycle");
is(secondCycleResults.panelCreated, 1, "devtools.panel.create callback has been called once");
is(secondCycleResults.panelShown, 2, "panel.onShown listener has been called twice");
is(secondCycleResults.panelHidden, 2, "panel.onHidden listener has been called twice");
// Turn off the addon devtools panel using the visibilityswitch.
@@ -286,17 +315,17 @@ add_task(async function test_devtools_pa
"The initial theme is reported as expected from a devtools panel.");
info("Addon Devtools Panel shown - after visibilityswitch toggled");
info("Wait until the Addon Devtools Panel has been loaded - after visibilityswitch toggled");
const panelTabIdAfterToggle = await extension.awaitMessage("devtools_panel_inspectedWindow_tabId");
is(panelTabIdAfterToggle, devtoolsPageTabId,
"Got the same devtools.inspectedWindow.tabId from devtools panel after visibility toggled");
- await gDevTools.showToolbox(target, "webconsole");
+ await gDevTools.showToolbox(target, "testBlankPanel");
const toolToggledResults = await extension.awaitMessage("devtools_panel_hidden");
info("Addon Devtools Panel hidden - after visibilityswitch toggled");
is(toolToggledResults.panelCreated, 1, "devtools.panel.create callback has been called once");
is(toolToggledResults.panelShown, 3, "panel.onShown listener has been called three times");
is(toolToggledResults.panelHidden, 3, "panel.onHidden listener has been called three times");
await gDevTools.closeToolbox(target);
@@ -364,17 +393,17 @@ add_task(async function test_devtools_pa
},
});
await extension.startup();
let target = gDevTools.getTargetForTab(tab);
- const toolbox = await gDevTools.showToolbox(target, "webconsole");
+ const toolbox = await gDevTools.showToolbox(target, "testBlankPanel");
info("developer toolbox opened");
await extension.awaitMessage("devtools_panel_created");
const toolboxAdditionalTools = toolbox.getAdditionalTools();
is(toolboxAdditionalTools.length, 1,
"Got the expected number of toolbox specific panel registered.");
@@ -433,32 +462,38 @@ add_task(async function test_devtools_pa
add_task(async function test_devtools_page_invalid_panel_urls() {
let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, "http://mochi.test:8888/");
async function devtools_page() {
const matchInvalidPanelURL = /must be a relative URL/;
const matchInvalidIconURL = /be one of \[""\], or match the format "strictRelativeUrl"/;
- const test_cases = [
- // Invalid panel urls (validated by the schema wrappers, throws on invalid urls).
+ // Invalid panel urls (validated by the schema wrappers, throws on invalid urls).
+ const invalid_panels = [
{panel: "about:about", icon: "icon.png", expectError: matchInvalidPanelURL},
{panel: "about:addons", icon: "icon.png", expectError: matchInvalidPanelURL},
{panel: "http://mochi.test:8888", icon: "icon.png", expectError: matchInvalidPanelURL},
// Invalid icon urls (validated inside the API method because of the empty icon string
// which have to be resolved to the default icon, reject the returned promise).
{panel: "panel.html", icon: "about:about", expectError: matchInvalidIconURL},
{panel: "panel.html", icon: "http://mochi.test:8888", expectError: matchInvalidIconURL},
- // Valid panel urls
+ ];
+
+ const valid_panels = [
{panel: "panel.html", icon: "icon.png"},
{panel: "./panel.html", icon: "icon.png"},
{panel: "/panel.html", icon: "icon.png"},
{panel: "/panel.html", icon: ""},
];
+ let valid_panels_length = valid_panels.length;
+
+ const test_cases = [].concat(invalid_panels, valid_panels);
+
browser.test.onMessage.addListener(async msg => {
if (msg !== "start_test_panel_create") {
return;
}
for (let {panel, icon, expectError} of test_cases) {
browser.test.log(`Testing devtools.panels.create for ${JSON.stringify({panel, icon})}`);
@@ -471,32 +506,36 @@ add_task(async function test_devtools_pa
`panel url ${panel} and icon ${icon}`
);
} else {
// Verify that with valid panel and icon urls the panel is created and loaded
// as expected.
try {
const pane = await browser.devtools.panels.create("Test Panel", icon, panel);
+ valid_panels_length--;
+
// Wait the panel to be loaded.
const oncePanelLoaded = new Promise(resolve => {
pane.onShown.addListener(paneWin => {
browser.test.assertTrue(
paneWin.location.href.endsWith("/panel.html"),
`The panel has loaded the expected extension URL with ${panel}`);
resolve();
});
});
// Ask the privileged code to select the last created panel.
- browser.test.sendMessage("select-devtools-panel");
+ const done = valid_panels_length === 0;
+ browser.test.sendMessage("select-devtools-panel", done);
await oncePanelLoaded;
} catch (err) {
browser.test.fail("Unexpected failure on creating a devtools panel with " +
`panel url ${panel} and icon ${icon}`);
+ throw err;
}
}
}
browser.test.sendMessage("test_invalid_devtools_panel_urls_done");
});
browser.test.sendMessage("devtools_page_ready");
@@ -533,31 +572,37 @@ add_task(async function test_devtools_pa
"default-icon.png": imageBuffer,
},
});
await extension.startup();
let target = gDevTools.getTargetForTab(tab);
- let toolbox = await gDevTools.showToolbox(target, "webconsole");
-
- extension.onMessage("select-devtools-panel", () => {
- const toolboxAdditionalTools = toolbox.getAdditionalTools();
- const lastTool = toolboxAdditionalTools[toolboxAdditionalTools.length - 1];
-
- gDevTools.showToolbox(target, lastTool.id);
- });
+ let toolbox = await gDevTools.showToolbox(target, "testBlankPanel");
info("developer toolbox opened");
await extension.awaitMessage("devtools_page_ready");
extension.sendMessage("start_test_panel_create");
+ let done = false;
+
+ while (!done) {
+ info("Waiting test extension request to select the last created panel");
+ done = await extension.awaitMessage("select-devtools-panel");
+
+ const toolboxAdditionalTools = toolbox.getAdditionalTools();
+ const lastTool = toolboxAdditionalTools[toolboxAdditionalTools.length - 1];
+
+ gDevTools.showToolbox(target, lastTool.id);
+ info("Last created panel selected");
+ }
+
await extension.awaitMessage("test_invalid_devtools_panel_urls_done");
await gDevTools.closeToolbox(target);
await target.destroy();
await extension.unload();
await BrowserTestUtils.removeTab(tab);