Source code

Revision control

Copy as Markdown

Other Tools

Test Info: Errors

/* Any copyright is dedicated to the Public Domain.
"use strict";
Services.scriptloader.loadSubScript(
this
);
/* import-globals-from helper-addons.js */
Services.scriptloader.loadSubScript(CHROME_URL_ROOT + "helper-addons.js", this);
const L10N = new LocalizationHelper(
"devtools/client/locales/toolbox.properties"
);
const EXTENSION_NAME = "temporary-web-extension";
const EXTENSION_ID = "test-devtools@mozilla.org";
add_task(async function testOpenDebuggerReload() {
await enableExtensionDebugging();
info(
"The debugger should show the source codes of extension even if " +
"devtools.chrome.enabled and devtools.debugger.remote-enabled are off"
);
await pushPref("devtools.chrome.enabled", false);
await pushPref("devtools.debugger.remote-enabled", false);
const { document, tab, window } = await openAboutDebugging();
await selectThisFirefoxPage(document, window.AboutDebugging.store);
await installTemporaryExtensionFromXPI(
{
background() {
window.someRandomMethodName = () => {
// This will not be referred from anywhere.
// However this is necessary to show as the source code in the debugger.
};
},
id: EXTENSION_ID,
name: EXTENSION_NAME,
},
document
);
// Select the debugger right away to avoid any noise coming from the inspector.
await pushPref("devtools.toolbox.selectedTool", "jsdebugger");
const { devtoolsWindow } = await openAboutDevtoolsToolbox(
document,
tab,
window,
EXTENSION_NAME
);
const toolbox = getToolbox(devtoolsWindow);
const { panelWin } = toolbox.getCurrentPanel();
info("Check the state of redux");
ok(
panelWin.dbg.store.getState().sourcesTree.isWebExtension,
"isWebExtension flag in sourcesTree is true"
);
const descriptorTitle = devtoolsWindow.document.querySelector(
".qa-descriptor-title"
);
is(
descriptorTitle.textContent,
EXTENSION_NAME,
"The add-on name is displayed in the toolbox header"
);
info("Check whether the element displays correctly");
let sourceList = panelWin.document.querySelector(".sources-list");
ok(sourceList, "Source list element displays correctly");
ok(
sourceList.textContent.includes("temporary-web-extension"),
"Extension name displays correctly"
);
const { onResource: onDomCompleteResource } =
await toolbox.commands.resourceCommand.waitForNextResource(
toolbox.commands.resourceCommand.TYPES.DOCUMENT_EVENT,
{
ignoreExistingResources: true,
predicate: resource => {
return (
resource.name === "dom-complete" &&
resource.targetFront.url.endsWith("background_page.html")
);
},
}
);
info("Reload the addon using a toolbox reload shortcut");
toolbox.win.focus();
synthesizeKeyShortcut(L10N.getStr("toolbox.reload.key"), toolbox.win);
await onDomCompleteResource;
info("Wait until a new background log message is logged");
await waitFor(() => {
// As React may re-create a new sources-list element,
// fetch the latest instance
sourceList = panelWin.document.querySelector(".sources-list");
return sourceList?.textContent.includes("temporary-web-extension");
}, "Wait for the source to re-appear");
await closeWebExtAboutDevtoolsToolbox(devtoolsWindow, window);
await removeTemporaryExtension(EXTENSION_NAME, document);
await removeTab(tab);
});
add_task(async function testAddAndRemoveBreakpoint() {
await enableExtensionDebugging();
const { document, tab, window } = await openAboutDebugging();
await selectThisFirefoxPage(document, window.AboutDebugging.store);
await installTemporaryExtensionFromXPI(
{
background() {
window.invokeLogFromWebextension = () => {
console.log("From webextension");
};
},
id: EXTENSION_ID,
name: EXTENSION_NAME,
},
document
);
// Select the debugger right away to avoid any noise coming from the inspector.
await pushPref("devtools.toolbox.selectedTool", "jsdebugger");
const { devtoolsWindow } = await openAboutDevtoolsToolbox(
document,
tab,
window,
EXTENSION_NAME
);
const toolbox = getToolbox(devtoolsWindow);
const dbg = createDebuggerContext(toolbox);
info("Assert the threads displayed in Source Tree as well as Threads pane");
const sourceTreeThreads = findAllElements(dbg, "sourceTreeThreads");
is(
sourceTreeThreads.length,
1,
"There is only one thread with source in the Source Tree"
);
is(
sourceTreeThreads[0].textContent,
"/_generated_background_page.html",
"That thread is the background page"
);
const threadLabels = findAllElements(dbg, "threadsPaneItems");
is(threadLabels.length, 2, "But there are two threads in the thread panel");
is(threadLabels[0].textContent, "Web Extension Fallback Document");
is(threadLabels[1].textContent, "/_generated_background_page.html");
info("Select the source and add a breakpoint");
// Note: the background script filename is dynamically generated id, so we
// simply get the first source from the list.
const displayedSources = dbg.selectors.getDisplayedSourcesList();
const backgroundScript = displayedSources[0];
await selectSource(dbg, backgroundScript);
await addBreakpoint(dbg, backgroundScript, 3);
info("Trigger the breakpoint and wait for the debugger to pause");
const webconsole = await toolbox.selectTool("webconsole");
const { hud } = webconsole;
hud.ui.wrapper.dispatchEvaluateExpression("invokeLogFromWebextension()");
await waitForPaused(dbg);
info("Resume and remove the breakpoint");
await resume(dbg);
await removeBreakpoint(dbg, backgroundScript.id, 3);
info("Trigger the function again and check the debugger does not pause");
hud.ui.wrapper.dispatchEvaluateExpression("invokeLogFromWebextension()");
await wait(500);
assertNotPaused(dbg);
await closeWebExtAboutDevtoolsToolbox(devtoolsWindow, window);
await removeTemporaryExtension(EXTENSION_NAME, document);
await removeTab(tab);
});