summaryrefslogtreecommitdiffstats
path: root/devtools/client/debugger/test/mochitest/browser_dbg-backgroundtask-debugging.js
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--devtools/client/debugger/test/mochitest/browser_dbg-backgroundtask-debugging.js161
1 files changed, 161 insertions, 0 deletions
diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-backgroundtask-debugging.js b/devtools/client/debugger/test/mochitest/browser_dbg-backgroundtask-debugging.js
new file mode 100644
index 0000000000..6e0f62deb9
--- /dev/null
+++ b/devtools/client/debugger/test/mochitest/browser_dbg-backgroundtask-debugging.js
@@ -0,0 +1,161 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
+
+/**
+ * Tests that `--backgroundtask` debugging works.
+ *
+ * This test is subtle. We launch a `--backgroundtask` with `--jsdebugger` and
+ * `--wait-for-jsdebugger` within the test. The background task infrastructure
+ * launches a browser toolbox, and the test connects to that browser toolbox
+ * instance. The test drives the instance, verifying that the automatically
+ * placed breakpoint paused execution. It then closes the browser toolbox,
+ * which resumes the execution and the task exits.
+ *
+ * In the future, it would be nice to change the task's running environment, for
+ * example by redefining a failing exit code to exit code 0. Attempts to do
+ * this have so far not been robust in automation.
+ */
+
+"use strict";
+
+requestLongerTimeout(4);
+
+Services.scriptloader.loadSubScript(
+ "chrome://mochitests/content/browser/devtools/client/framework/browser-toolbox/test/helpers-browser-toolbox.js",
+ this
+);
+
+const { BackgroundTasksTestUtils } = ChromeUtils.importESModule(
+ "resource://testing-common/BackgroundTasksTestUtils.sys.mjs"
+);
+BackgroundTasksTestUtils.init(this);
+const do_backgroundtask = BackgroundTasksTestUtils.do_backgroundtask.bind(
+ BackgroundTasksTestUtils
+);
+
+add_task(async function test_backgroundtask_debugger() {
+ // In this test, the background task infrastructure launches the browser
+ // toolbox. The browser toolbox profile prefs are taken from the default
+ // profile (which is the standard place for background tasks to look for
+ // task-specific configuration). The current test profile will be
+ // considered the default profile by the background task apparatus, so this
+ // is how we configure the browser toolbox profile prefs.
+ //
+ // These prefs are not set for the background task under test directly: the
+ // relevant prefs are set in the background task defaults.
+ await pushPref("devtools.chrome.enabled", true);
+ await pushPref("devtools.debugger.remote-enabled", true);
+ await pushPref("devtools.browsertoolbox.enable-test-server", true);
+ await pushPref("devtools.debugger.prompt-connection", false);
+
+ // Before we start the background task, the preference file must be flushed to disk.
+ Services.prefs.savePrefFile(null);
+
+ // This invokes the test-only background task `BackgroundTask_jsdebugger.jsm`.
+ const p = do_backgroundtask("jsdebugger", {
+ extraArgs: [`--jsdebugger`, "--wait-for-jsdebugger"],
+ extraEnv: {
+ // Force the current test profile to be considered the default profile.
+ MOZ_BACKGROUNDTASKS_DEFAULT_PROFILE_PATH: Services.dirsvc.get(
+ "ProfD",
+ Ci.nsIFile
+ ).path,
+ },
+ });
+
+ ok(true, "Launched background task");
+
+ const existingProcessClose = async () => {
+ const exitCode = await p;
+ return { exitCode };
+ };
+ const ToolboxTask = await initBrowserToolboxTask({ existingProcessClose });
+
+ await ToolboxTask.spawn(selectors, () => {
+ const {
+ LocalizationHelper,
+ } = require("resource://devtools/shared/l10n.js");
+ // We have to expose this symbol as global for waitForSelectedSource
+ this.DEBUGGER_L10N = new LocalizationHelper(
+ "devtools/client/locales/debugger.properties"
+ );
+ });
+
+ await ToolboxTask.importFunctions({
+ checkEvaluateInTopFrame,
+ evaluateInTopFrame,
+ createDebuggerContext,
+ expandAllScopes,
+ findElement,
+ findElementWithSelector,
+ getSelector,
+ getVisibleSelectedFrameLine,
+ isPaused,
+ resume,
+ stepOver,
+ toggleObjectInspectorNode,
+ toggleScopeNode,
+ waitForElement,
+ waitForLoadedScopes,
+ waitForPaused,
+ waitForResumed,
+ waitForSelectedSource,
+ waitForState,
+ waitUntil,
+ createLocation,
+ getCM,
+ log: (msg, data) =>
+ console.log(`${msg} ${!data ? "" : JSON.stringify(data)}`),
+ info: (msg, data) =>
+ console.info(`${msg} ${!data ? "" : JSON.stringify(data)}`),
+ });
+
+ // ToolboxTask.spawn passes input arguments by stringify-ing them via string
+ // concatenation. But functions do not survive this process, so we manually
+ // recreate (in the toolbox process) the single function the `expandAllScopes`
+ // invocation in this test needs.
+ await ToolboxTask.spawn(selectors, async _selectors => {
+ this.selectors = _selectors;
+ this.selectors.scopeNode = i =>
+ `.scopes-list .tree-node:nth-child(${i}) .object-label`;
+ });
+
+ // The debugger should automatically be selected.
+ await ToolboxTask.spawn(null, async () => {
+ await waitUntil(() => gToolbox.currentToolId == "jsdebugger");
+ });
+ ok(true, "Debugger selected");
+
+ // The debugger should automatically pause.
+ await ToolboxTask.spawn(null, async () => {
+ try {
+ /* global gToolbox */
+ // Wait for the debugger to finish loading.
+ await gToolbox.getPanelWhenReady("jsdebugger");
+
+ const dbg = createDebuggerContext(gToolbox);
+
+ // Scopes are supposed to be automatically expanded, but with
+ // `setBreakpointOnLoad` that doesn't seem to be happening. Explicitly
+ // expand scopes so that they are expanded for `waitForPaused`.
+ await expandAllScopes(dbg);
+
+ await waitForPaused(dbg);
+
+ if (!gToolbox.isHighlighted("jsdebugger")) {
+ throw new Error("Debugger not highlighted");
+ }
+ } catch (e) {
+ console.log("Caught exception in spawn", e);
+ throw e;
+ }
+ });
+ ok(true, "Paused in backgroundtask script");
+
+ // If we `resume`, then the task completes and the Browser Toolbox exits,
+ // which isn't handled cleanly by `spawn`, resulting in a test time out. This
+ // closes the toolbox "from the inside", which continues execution. The test
+ // then waits for the background task to terminate with exit code 0.
+ await ToolboxTask.destroy();
+});