Loading devtools/client/framework/moz.build +0 −1 Original line number Diff line number Diff line Loading @@ -6,7 +6,6 @@ BROWSER_CHROME_MANIFESTS += [ 'test/allocations/browser_allocations_target.ini', 'test/browser-rtl.ini', 'test/browser-telemetry-startup.ini', 'test/browser.ini', 'test/metrics/browser_metrics_debugger.ini', Loading devtools/client/framework/test/browser-rtl.inideleted 100644 → 0 +0 −14 Original line number Diff line number Diff line [DEFAULT] tags = devtools subsuite = devtools prefs = # This test suite is dedicated to tests that need to run with the browser in RTL mode. # This mode cannot be dynamically changed between tests reusing the browser instance and # window. intl.uidirection=1 support-files = head.js !/devtools/client/shared/test/shared-head.js !/devtools/client/shared/test/telemetry-test-helpers.js [browser_browser_toolbox_rtl.js] devtools/client/framework/test/browser.ini +5 −4 Original line number Diff line number Diff line Loading @@ -42,7 +42,6 @@ support-files = serviceworker.js sjs_code_reload.sjs sjs_code_bundle_reload_map.sjs test_browser_toolbox_debugger.js test_chrome_page.html !/devtools/client/debugger/test/mochitest/head.js !/devtools/client/debugger/test/mochitest/helpers.js Loading @@ -59,11 +58,13 @@ prefs = [browser_about-devtools-toolbox_load.js] [browser_about-devtools-toolbox_reload.js] [browser_browser_toolbox.js] skip-if = coverage # Bug 1387827 skip-if = coverage || asan # Bug 1387827, Bug 1591064 [browser_browser_toolbox_debugger.js] skip-if = os == 'win' || debug || (bits == 64 && !debug && (os == 'mac' || os == 'linux')) # Bug 1282269, 1448084, Bug 1270731 skip-if = os == 'win' || debug || (bits == 64 && !debug && (os == 'mac' || os == 'linux')) || asan # Bug 1282269, Bug 1448084, Bug 1270731, Bug 1591064 [browser_browser_toolbox_fission_inspector.js] skip-if = coverage # Bug 1387827 skip-if = coverage || asan # Bug 1387827, Bug 1591064 [browser_browser_toolbox_rtl.js] skip-if = asan # Bug 1591064 [browser_devtools_api_destroy.js] [browser_dynamic_tool_enabling.js] [browser_front_parentFront.js] Loading devtools/client/framework/test/browser_browser_toolbox.js +12 −76 Original line number Diff line number Diff line /* Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ */ /* import-globals-from helpers.js */ Services.scriptloader.loadSubScript( "chrome://mochitests/content/browser/devtools/client/framework/test/helpers.js", this ); // There are shutdown issues for which multiple rejections are left uncaught. // See bug 1018184 for resolving these issues. const { PromiseTestUtils } = ChromeUtils.import( Loading @@ -12,84 +18,14 @@ PromiseTestUtils.whitelistRejectionsGlobally(/File closed/); requestLongerTimeout(4); add_task(async function() { await setupPreferencesForBrowserToolbox(); // Wait for a notification sent by a script evaluated in the webconsole // of the browser toolbox. const onCustomMessage = new Promise(done => { Services.obs.addObserver(function listener(target, aTop, data) { Services.obs.removeObserver(listener, "browser-toolbox-console-works"); done(data === "true"); }, "browser-toolbox-console-works"); }); const ToolboxTask = await initBrowserToolboxTask(); await ToolboxTask.importFunctions({}); // Be careful, this JS function is going to be executed in the addon toolbox, // which lives in another process. So do not try to use any scope variable! const env = Cc["@mozilla.org/process/environment;1"].getService( Ci.nsIEnvironment ); /* global toolbox */ const testScript = function() { toolbox .selectTool("webconsole") .then(console => { // This is for checking Browser Toolbox doesn't have a close button. const hasCloseButton = !!toolbox.doc.getElementById("toolbox-close"); const { wrapper } = console.hud.ui; const js = `Services.obs.notifyObservers(null, 'browser-toolbox-console-works', ${hasCloseButton} )`; const onResult = new Promise(resolve => { const onNewMessages = messages => { for (const message of messages) { if (message.node.classList.contains("result")) { console.hud.ui.off("new-messages", onNewMessages); resolve(); } } }; console.hud.ui.on("new-messages", onNewMessages); }); wrapper.dispatchEvaluateExpression(js); return onResult; }) .then(() => toolbox.destroy()); }; env.set("MOZ_TOOLBOX_TEST_SCRIPT", "new " + testScript); registerCleanupFunction(() => { env.set("MOZ_TOOLBOX_TEST_SCRIPT", ""); const hasCloseButton = await ToolboxTask.spawn(null, async () => { /* global gToolbox */ return !!gToolbox.doc.getElementById("toolbox-close"); }); const { BrowserToolboxProcess } = ChromeUtils.import( "resource://devtools/client/framework/ToolboxProcess.jsm" ); is( BrowserToolboxProcess.getBrowserToolboxSessionState(), false, "No session state initially" ); let closePromise; await new Promise(onRun => { closePromise = new Promise(onClose => { info("Opening the browser toolbox\n"); BrowserToolboxProcess.init(onClose, onRun); }); }); ok(true, "Browser toolbox started\n"); is( BrowserToolboxProcess.getBrowserToolboxSessionState(), true, "Has session state" ); const hasCloseButton = await onCustomMessage; ok(true, "Received the custom message"); ok(!hasCloseButton, "Browser toolbox doesn't have a close button"); await closePromise; ok(true, "Browser toolbox process just closed"); is( BrowserToolboxProcess.getBrowserToolboxSessionState(), false, "No session state after closing" ); await ToolboxTask.destroy(); }); devtools/client/framework/test/browser_browser_toolbox_debugger.js +76 −93 Original line number Diff line number Diff line Loading @@ -2,9 +2,12 @@ http://creativecommons.org/publicdomain/zero/1.0/ */ // This test asserts that the new debugger works from the browser toolbox process // Its pass a big piece of Javascript string to the browser toolbox process via // MOZ_TOOLBOX_TEST_SCRIPT env variable. It does that as test resources fetched from // chrome://mochitests/ package isn't available from browser toolbox process. /* import-globals-from helpers.js */ Services.scriptloader.loadSubScript( "chrome://mochitests/content/browser/devtools/client/framework/test/helpers.js", this ); // There are shutdown issues for which multiple rejections are left uncaught. // See bug 1018184 for resolving these issues. Loading @@ -23,11 +26,8 @@ const debuggerHeadURL = const helpersURL = CHROME_URL_ROOT + "../../debugger/test/mochitest/helpers.js"; const helpersContextURL = CHROME_URL_ROOT + "../../debugger/test/mochitest/helpers/context.js"; const testScriptURL = CHROME_URL_ROOT + "test_browser_toolbox_debugger.js"; add_task(async function runTest() { await setupPreferencesForBrowserToolbox(); const s = Cu.Sandbox("http://mozilla.org"); // Use a unique id for the fake script name in order to be able to run Loading Loading @@ -57,17 +57,25 @@ add_task(async function runTest() { // Execute the function every second in order to trigger the breakpoint const interval = setInterval(s.plop, 1000); // Be careful, this JS function is going to be executed in the browser toolbox, // which lives in another process. So do not try to use any scope variable! const env = Cc["@mozilla.org/process/environment;1"].getService( Ci.nsIEnvironment let { content: debuggerHead } = await fetch(debuggerHeadURL); // Also include the debugger helpers which are separated from debugger's head to be // reused in other modules. const { content: debuggerHelpers } = await fetch(helpersURL); const { content: debuggerContextHelpers } = await fetch(helpersContextURL); debuggerHead = debuggerHead + debuggerContextHelpers + debuggerHelpers; // We remove its import of shared-head, which isn't available in browser toolbox process // And isn't needed thanks to testHead's symbols debuggerHead = debuggerHead.replace( /Services.scriptloader.loadSubScript[^\)]*\);/g, "" ); // First inject a very minimal head, with simplest assertion methods // and very common globals /* eslint-disable no-unused-vars */ const testHead = function() { const info = msg => dump(msg + "\n"); const is = (a, b, description) => { const ToolboxTask = await initBrowserToolboxTask(); await ToolboxTask.importScript(debuggerHead); await ToolboxTask.importFunctions({ info: msg => dump(msg + "\n"), is: (a, b, description) => { let msg = "'" + JSON.stringify(a) + "' is equal to '" + JSON.stringify(b) + "'"; if (description) { Loading @@ -81,8 +89,8 @@ add_task(async function runTest() { msg = "SUCCESS: " + msg; dump(msg + "\n"); } }; const ok = (a, description) => { }, ok: (a, description) => { let msg = "'" + JSON.stringify(a) + "' is true"; if (description) { msg += " - " + description; Loading @@ -95,92 +103,67 @@ add_task(async function runTest() { msg = "SUCCESS: " + msg; dump(msg + "\n"); } }; const registerCleanupFunction = () => {}; }, waitUntil, }); const { require } = ChromeUtils.import( "resource://devtools/shared/Loader.jsm" ); await ToolboxTask.spawn(`"${testUrl}"`, async _testUrl => { /* global createDebuggerContext, waitForSources, waitForPaused, addBreakpoint, assertPausedLocation, stepIn, findSource, removeBreakpoint, resume, selectSource */ const { Services } = ChromeUtils.import( "resource://gre/modules/Services.jsm" ); // Copied from shared-head.js: // test_browser_toolbox_debugger.js uses waitForPaused, which relies on waitUntil // which is normally provided by shared-head.js const { setTimeout } = ChromeUtils.import( "resource://gre/modules/Timer.jsm" ); function waitUntil(predicate, interval = 10) { if (predicate()) { return Promise.resolve(true); } return new Promise(resolve => { // TODO: fixme. // eslint-disable-next-line mozilla/no-arbitrary-setTimeout setTimeout(function() { waitUntil(predicate, interval).then(() => resolve(true)); }, interval); }); } } .toSource() .replace(/^\(function\(\) \{|\}\)$/g, ""); /* eslint-enable no-unused-vars */ // Stringify testHead's function and remove `(function {` prefix and `})` suffix // to ensure inner symbols gets exposed to next pieces of code // Then inject new debugger head file let { content: debuggerHead } = await fetch(debuggerHeadURL); Services.prefs.clearUserPref("devtools.debugger.tabs"); Services.prefs.clearUserPref("devtools.debugger.pending-selected-location"); // Also include the debugger helpers which are separated from debugger's head to be // reused in other modules. const { content: debuggerHelpers } = await fetch(helpersURL); const { content: debuggerContextHelpers } = await fetch(helpersContextURL); debuggerHead = debuggerHead + debuggerContextHelpers + debuggerHelpers; info("Waiting for debugger load"); /* global gToolbox */ await gToolbox.selectTool("jsdebugger"); const dbg = createDebuggerContext(gToolbox); const window = dbg.win; const document = window.document; // We remove its import of shared-head, which isn't available in browser toolbox process // And isn't needed thanks to testHead's symbols debuggerHead = debuggerHead.replace( /Services.scriptloader.loadSubScript[^\)]*\);/g, "" ); await waitForSources(dbg, _testUrl); // Finally, fetch the debugger test script that is going to be execute in the browser // toolbox process const testScript = (await fetch(testScriptURL)).content; const source = 'try { let testUrl = "' + testUrl + '";' + testHead + debuggerHead + testScript + "} catch (e) {" + " dump('Exception: '+ e + ' at ' + e.fileName + ':' + " + " e.lineNumber + '\\nStack: ' + e.stack + '\\n');" + "}"; env.set("MOZ_TOOLBOX_TEST_SCRIPT", source); registerCleanupFunction(() => { env.set("MOZ_TOOLBOX_TEST_SCRIPT", ""); info("Loaded, selecting the test script to debug"); // First expand the domain const domain = [...document.querySelectorAll(".tree-node")].find(node => { return node.querySelector(".label").textContent.trim() == "mozilla.org"; }); const arrow = domain.querySelector(".arrow"); arrow.click(); const { BrowserToolboxProcess } = ChromeUtils.import( "resource://devtools/client/framework/ToolboxProcess.jsm" ); // Use two promises, one for each BrowserToolboxProcess.init callback // arguments, to ensure that we wait for toolbox run and close events. let closePromise; await new Promise(onRun => { closePromise = new Promise(onClose => { info("Opening the browser toolbox\n"); BrowserToolboxProcess.init(onClose, onRun); }); const fileName = _testUrl.match(/browser-toolbox-test.*\.js/)[0]; let script = [...document.querySelectorAll(".tree-node")].find(node => { return node.textContent.includes(fileName); }); ok(true, "Browser toolbox started\n"); script = script.querySelector(".node"); script.click(); const onPaused = waitForPaused(dbg); await selectSource(dbg, fileName); await addBreakpoint(dbg, fileName, 2); await onPaused; await closePromise; ok(true, "Browser toolbox process just closed"); assertPausedLocation(dbg, fileName, 2); await stepIn(dbg); assertPausedLocation(dbg, fileName, 3); // Remove the breakpoint before resuming in order to prevent hitting the breakpoint // again during test closing. const source = findSource(dbg, fileName); await removeBreakpoint(dbg, source.id, 2); await resume(dbg); }); clearInterval(interval); await ToolboxTask.destroy(); }); Loading
devtools/client/framework/moz.build +0 −1 Original line number Diff line number Diff line Loading @@ -6,7 +6,6 @@ BROWSER_CHROME_MANIFESTS += [ 'test/allocations/browser_allocations_target.ini', 'test/browser-rtl.ini', 'test/browser-telemetry-startup.ini', 'test/browser.ini', 'test/metrics/browser_metrics_debugger.ini', Loading
devtools/client/framework/test/browser-rtl.inideleted 100644 → 0 +0 −14 Original line number Diff line number Diff line [DEFAULT] tags = devtools subsuite = devtools prefs = # This test suite is dedicated to tests that need to run with the browser in RTL mode. # This mode cannot be dynamically changed between tests reusing the browser instance and # window. intl.uidirection=1 support-files = head.js !/devtools/client/shared/test/shared-head.js !/devtools/client/shared/test/telemetry-test-helpers.js [browser_browser_toolbox_rtl.js]
devtools/client/framework/test/browser.ini +5 −4 Original line number Diff line number Diff line Loading @@ -42,7 +42,6 @@ support-files = serviceworker.js sjs_code_reload.sjs sjs_code_bundle_reload_map.sjs test_browser_toolbox_debugger.js test_chrome_page.html !/devtools/client/debugger/test/mochitest/head.js !/devtools/client/debugger/test/mochitest/helpers.js Loading @@ -59,11 +58,13 @@ prefs = [browser_about-devtools-toolbox_load.js] [browser_about-devtools-toolbox_reload.js] [browser_browser_toolbox.js] skip-if = coverage # Bug 1387827 skip-if = coverage || asan # Bug 1387827, Bug 1591064 [browser_browser_toolbox_debugger.js] skip-if = os == 'win' || debug || (bits == 64 && !debug && (os == 'mac' || os == 'linux')) # Bug 1282269, 1448084, Bug 1270731 skip-if = os == 'win' || debug || (bits == 64 && !debug && (os == 'mac' || os == 'linux')) || asan # Bug 1282269, Bug 1448084, Bug 1270731, Bug 1591064 [browser_browser_toolbox_fission_inspector.js] skip-if = coverage # Bug 1387827 skip-if = coverage || asan # Bug 1387827, Bug 1591064 [browser_browser_toolbox_rtl.js] skip-if = asan # Bug 1591064 [browser_devtools_api_destroy.js] [browser_dynamic_tool_enabling.js] [browser_front_parentFront.js] Loading
devtools/client/framework/test/browser_browser_toolbox.js +12 −76 Original line number Diff line number Diff line /* Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ */ /* import-globals-from helpers.js */ Services.scriptloader.loadSubScript( "chrome://mochitests/content/browser/devtools/client/framework/test/helpers.js", this ); // There are shutdown issues for which multiple rejections are left uncaught. // See bug 1018184 for resolving these issues. const { PromiseTestUtils } = ChromeUtils.import( Loading @@ -12,84 +18,14 @@ PromiseTestUtils.whitelistRejectionsGlobally(/File closed/); requestLongerTimeout(4); add_task(async function() { await setupPreferencesForBrowserToolbox(); // Wait for a notification sent by a script evaluated in the webconsole // of the browser toolbox. const onCustomMessage = new Promise(done => { Services.obs.addObserver(function listener(target, aTop, data) { Services.obs.removeObserver(listener, "browser-toolbox-console-works"); done(data === "true"); }, "browser-toolbox-console-works"); }); const ToolboxTask = await initBrowserToolboxTask(); await ToolboxTask.importFunctions({}); // Be careful, this JS function is going to be executed in the addon toolbox, // which lives in another process. So do not try to use any scope variable! const env = Cc["@mozilla.org/process/environment;1"].getService( Ci.nsIEnvironment ); /* global toolbox */ const testScript = function() { toolbox .selectTool("webconsole") .then(console => { // This is for checking Browser Toolbox doesn't have a close button. const hasCloseButton = !!toolbox.doc.getElementById("toolbox-close"); const { wrapper } = console.hud.ui; const js = `Services.obs.notifyObservers(null, 'browser-toolbox-console-works', ${hasCloseButton} )`; const onResult = new Promise(resolve => { const onNewMessages = messages => { for (const message of messages) { if (message.node.classList.contains("result")) { console.hud.ui.off("new-messages", onNewMessages); resolve(); } } }; console.hud.ui.on("new-messages", onNewMessages); }); wrapper.dispatchEvaluateExpression(js); return onResult; }) .then(() => toolbox.destroy()); }; env.set("MOZ_TOOLBOX_TEST_SCRIPT", "new " + testScript); registerCleanupFunction(() => { env.set("MOZ_TOOLBOX_TEST_SCRIPT", ""); const hasCloseButton = await ToolboxTask.spawn(null, async () => { /* global gToolbox */ return !!gToolbox.doc.getElementById("toolbox-close"); }); const { BrowserToolboxProcess } = ChromeUtils.import( "resource://devtools/client/framework/ToolboxProcess.jsm" ); is( BrowserToolboxProcess.getBrowserToolboxSessionState(), false, "No session state initially" ); let closePromise; await new Promise(onRun => { closePromise = new Promise(onClose => { info("Opening the browser toolbox\n"); BrowserToolboxProcess.init(onClose, onRun); }); }); ok(true, "Browser toolbox started\n"); is( BrowserToolboxProcess.getBrowserToolboxSessionState(), true, "Has session state" ); const hasCloseButton = await onCustomMessage; ok(true, "Received the custom message"); ok(!hasCloseButton, "Browser toolbox doesn't have a close button"); await closePromise; ok(true, "Browser toolbox process just closed"); is( BrowserToolboxProcess.getBrowserToolboxSessionState(), false, "No session state after closing" ); await ToolboxTask.destroy(); });
devtools/client/framework/test/browser_browser_toolbox_debugger.js +76 −93 Original line number Diff line number Diff line Loading @@ -2,9 +2,12 @@ http://creativecommons.org/publicdomain/zero/1.0/ */ // This test asserts that the new debugger works from the browser toolbox process // Its pass a big piece of Javascript string to the browser toolbox process via // MOZ_TOOLBOX_TEST_SCRIPT env variable. It does that as test resources fetched from // chrome://mochitests/ package isn't available from browser toolbox process. /* import-globals-from helpers.js */ Services.scriptloader.loadSubScript( "chrome://mochitests/content/browser/devtools/client/framework/test/helpers.js", this ); // There are shutdown issues for which multiple rejections are left uncaught. // See bug 1018184 for resolving these issues. Loading @@ -23,11 +26,8 @@ const debuggerHeadURL = const helpersURL = CHROME_URL_ROOT + "../../debugger/test/mochitest/helpers.js"; const helpersContextURL = CHROME_URL_ROOT + "../../debugger/test/mochitest/helpers/context.js"; const testScriptURL = CHROME_URL_ROOT + "test_browser_toolbox_debugger.js"; add_task(async function runTest() { await setupPreferencesForBrowserToolbox(); const s = Cu.Sandbox("http://mozilla.org"); // Use a unique id for the fake script name in order to be able to run Loading Loading @@ -57,17 +57,25 @@ add_task(async function runTest() { // Execute the function every second in order to trigger the breakpoint const interval = setInterval(s.plop, 1000); // Be careful, this JS function is going to be executed in the browser toolbox, // which lives in another process. So do not try to use any scope variable! const env = Cc["@mozilla.org/process/environment;1"].getService( Ci.nsIEnvironment let { content: debuggerHead } = await fetch(debuggerHeadURL); // Also include the debugger helpers which are separated from debugger's head to be // reused in other modules. const { content: debuggerHelpers } = await fetch(helpersURL); const { content: debuggerContextHelpers } = await fetch(helpersContextURL); debuggerHead = debuggerHead + debuggerContextHelpers + debuggerHelpers; // We remove its import of shared-head, which isn't available in browser toolbox process // And isn't needed thanks to testHead's symbols debuggerHead = debuggerHead.replace( /Services.scriptloader.loadSubScript[^\)]*\);/g, "" ); // First inject a very minimal head, with simplest assertion methods // and very common globals /* eslint-disable no-unused-vars */ const testHead = function() { const info = msg => dump(msg + "\n"); const is = (a, b, description) => { const ToolboxTask = await initBrowserToolboxTask(); await ToolboxTask.importScript(debuggerHead); await ToolboxTask.importFunctions({ info: msg => dump(msg + "\n"), is: (a, b, description) => { let msg = "'" + JSON.stringify(a) + "' is equal to '" + JSON.stringify(b) + "'"; if (description) { Loading @@ -81,8 +89,8 @@ add_task(async function runTest() { msg = "SUCCESS: " + msg; dump(msg + "\n"); } }; const ok = (a, description) => { }, ok: (a, description) => { let msg = "'" + JSON.stringify(a) + "' is true"; if (description) { msg += " - " + description; Loading @@ -95,92 +103,67 @@ add_task(async function runTest() { msg = "SUCCESS: " + msg; dump(msg + "\n"); } }; const registerCleanupFunction = () => {}; }, waitUntil, }); const { require } = ChromeUtils.import( "resource://devtools/shared/Loader.jsm" ); await ToolboxTask.spawn(`"${testUrl}"`, async _testUrl => { /* global createDebuggerContext, waitForSources, waitForPaused, addBreakpoint, assertPausedLocation, stepIn, findSource, removeBreakpoint, resume, selectSource */ const { Services } = ChromeUtils.import( "resource://gre/modules/Services.jsm" ); // Copied from shared-head.js: // test_browser_toolbox_debugger.js uses waitForPaused, which relies on waitUntil // which is normally provided by shared-head.js const { setTimeout } = ChromeUtils.import( "resource://gre/modules/Timer.jsm" ); function waitUntil(predicate, interval = 10) { if (predicate()) { return Promise.resolve(true); } return new Promise(resolve => { // TODO: fixme. // eslint-disable-next-line mozilla/no-arbitrary-setTimeout setTimeout(function() { waitUntil(predicate, interval).then(() => resolve(true)); }, interval); }); } } .toSource() .replace(/^\(function\(\) \{|\}\)$/g, ""); /* eslint-enable no-unused-vars */ // Stringify testHead's function and remove `(function {` prefix and `})` suffix // to ensure inner symbols gets exposed to next pieces of code // Then inject new debugger head file let { content: debuggerHead } = await fetch(debuggerHeadURL); Services.prefs.clearUserPref("devtools.debugger.tabs"); Services.prefs.clearUserPref("devtools.debugger.pending-selected-location"); // Also include the debugger helpers which are separated from debugger's head to be // reused in other modules. const { content: debuggerHelpers } = await fetch(helpersURL); const { content: debuggerContextHelpers } = await fetch(helpersContextURL); debuggerHead = debuggerHead + debuggerContextHelpers + debuggerHelpers; info("Waiting for debugger load"); /* global gToolbox */ await gToolbox.selectTool("jsdebugger"); const dbg = createDebuggerContext(gToolbox); const window = dbg.win; const document = window.document; // We remove its import of shared-head, which isn't available in browser toolbox process // And isn't needed thanks to testHead's symbols debuggerHead = debuggerHead.replace( /Services.scriptloader.loadSubScript[^\)]*\);/g, "" ); await waitForSources(dbg, _testUrl); // Finally, fetch the debugger test script that is going to be execute in the browser // toolbox process const testScript = (await fetch(testScriptURL)).content; const source = 'try { let testUrl = "' + testUrl + '";' + testHead + debuggerHead + testScript + "} catch (e) {" + " dump('Exception: '+ e + ' at ' + e.fileName + ':' + " + " e.lineNumber + '\\nStack: ' + e.stack + '\\n');" + "}"; env.set("MOZ_TOOLBOX_TEST_SCRIPT", source); registerCleanupFunction(() => { env.set("MOZ_TOOLBOX_TEST_SCRIPT", ""); info("Loaded, selecting the test script to debug"); // First expand the domain const domain = [...document.querySelectorAll(".tree-node")].find(node => { return node.querySelector(".label").textContent.trim() == "mozilla.org"; }); const arrow = domain.querySelector(".arrow"); arrow.click(); const { BrowserToolboxProcess } = ChromeUtils.import( "resource://devtools/client/framework/ToolboxProcess.jsm" ); // Use two promises, one for each BrowserToolboxProcess.init callback // arguments, to ensure that we wait for toolbox run and close events. let closePromise; await new Promise(onRun => { closePromise = new Promise(onClose => { info("Opening the browser toolbox\n"); BrowserToolboxProcess.init(onClose, onRun); }); const fileName = _testUrl.match(/browser-toolbox-test.*\.js/)[0]; let script = [...document.querySelectorAll(".tree-node")].find(node => { return node.textContent.includes(fileName); }); ok(true, "Browser toolbox started\n"); script = script.querySelector(".node"); script.click(); const onPaused = waitForPaused(dbg); await selectSource(dbg, fileName); await addBreakpoint(dbg, fileName, 2); await onPaused; await closePromise; ok(true, "Browser toolbox process just closed"); assertPausedLocation(dbg, fileName, 2); await stepIn(dbg); assertPausedLocation(dbg, fileName, 3); // Remove the breakpoint before resuming in order to prevent hitting the breakpoint // again during test closing. const source = findSource(dbg, fileName); await removeBreakpoint(dbg, source.id, 2); await resume(dbg); }); clearInterval(interval); await ToolboxTask.destroy(); });