From 90ece2181cb954f2e9cac32a537c572b63019c83 Mon Sep 17 00:00:00 2001 From: Alexandre Poirot Date: Tue, 30 Jul 2024 15:43:12 +0000 Subject: [PATCH] Bug 1907977 - [devtools] Fix source text content of worker ESM loaded via ChromeUtils methods. r=devtools-reviewers,nchevobbe Spidermonkey fails returning source text content via `Source.text` attribute. It returns "[no source]" and the urlContents fallback was trying to keep using this instead of the text content fetched via a request. Differential Revision: https://phabricator.services.mozilla.com/D218003 --- .../browser_dbg-browser-toolbox-workers.js | 42 ++++++++++++++++++- .../mochitest/examples/worker-esm-dep.mjs | 3 ++ .../test/mochitest/examples/worker-esm.mjs | 7 ++++ .../server/actors/utils/sources-manager.js | 5 ++- 4 files changed, 54 insertions(+), 3 deletions(-) create mode 100644 devtools/client/debugger/test/mochitest/examples/worker-esm-dep.mjs create mode 100644 devtools/client/debugger/test/mochitest/examples/worker-esm.mjs diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-browser-toolbox-workers.js b/devtools/client/debugger/test/mochitest/browser_dbg-browser-toolbox-workers.js index f08feb4ba97f..90d769d6feca 100644 --- a/devtools/client/debugger/test/mochitest/browser_dbg-browser-toolbox-workers.js +++ b/devtools/client/debugger/test/mochitest/browser_dbg-browser-toolbox-workers.js @@ -13,6 +13,8 @@ Services.scriptloader.loadSubScript( "chrome://mochitests/content/browser/devtools/client/framework/browser-toolbox/test/helpers-browser-toolbox.js", this ); +const WORKER_ESM = + "chrome://mochitests/content/browser/devtools/client/debugger/test/mochitest/examples/worker-esm.mjs"; add_task(async function () { await pushPref("devtools.browsertoolbox.scope", "everything"); @@ -20,17 +22,40 @@ add_task(async function () { await pushPref("dom.serviceWorkers.testing.enabled", true); const ToolboxTask = await initBrowserToolboxTask(); + 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({ waitUntil, waitForAllTargetsToBeAttached, + createDebuggerContext, + isWasmBinarySource, + DEBUGGER_L10N, + getCM, + waitForState, + waitForSelectedSource, + createLocation, + getUnicodeUrlPath, + findSource, + selectSource, + assertTextContentOnLine, }); await addTab(`${EXAMPLE_URL}doc-all-workers.html`); + globalThis.worker = new ChromeWorker(WORKER_ESM, { type: "module" }); + await ToolboxTask.spawn(null, async () => { /* global gToolbox */ await gToolbox.selectTool("jsdebugger"); - const dbg = gToolbox.getCurrentPanel().panelWin.dbg; + + const dbg = createDebuggerContext(gToolbox); await waitUntil(() => { const threads = dbg.selectors.getThreads(); @@ -41,14 +66,27 @@ add_task(async function () { return ( hasWorker("simple-worker.js") && hasWorker("shared-worker.js") && - hasWorker("service-worker.sjs") + hasWorker("service-worker.sjs") && + hasWorker("worker-esm.mjs") ); }); await waitForAllTargetsToBeAttached(gToolbox.commands.targetCommand); + + await selectSource(dbg, "worker-esm.mjs"); + assertTextContentOnLine( + dbg, + 7, + 'console.log("Worker ESM main script", foo);' + ); + await selectSource(dbg, "worker-esm-dep.mjs"); + assertTextContentOnLine(dbg, 1, 'console.log("Worker ESM dependency");'); }); ok(true, "All workers appear in browser toolbox debugger"); + globalThis.worker.terminate(); + delete globalThis.worker; + invokeInTab("unregisterServiceWorker"); await ToolboxTask.destroy(); diff --git a/devtools/client/debugger/test/mochitest/examples/worker-esm-dep.mjs b/devtools/client/debugger/test/mochitest/examples/worker-esm-dep.mjs new file mode 100644 index 000000000000..d2e8083f11c5 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/examples/worker-esm-dep.mjs @@ -0,0 +1,3 @@ +console.log("Worker ESM dependency"); + +export const foo = 42; diff --git a/devtools/client/debugger/test/mochitest/examples/worker-esm.mjs b/devtools/client/debugger/test/mochitest/examples/worker-esm.mjs new file mode 100644 index 000000000000..4c828e4881bb --- /dev/null +++ b/devtools/client/debugger/test/mochitest/examples/worker-esm.mjs @@ -0,0 +1,7 @@ +const { foo } = ChromeUtils.importESModule("chrome://mochitests/content/browser/devtools/client/debugger/test/mochitest/examples/worker-esm-dep.mjs", + { global: "current" } +); +// Using a regular import doesn't reproduce bug 1907977 issue: +// import { foo } from "./worker-esm-dep.mjs"; + +console.log("Worker ESM main script", foo); diff --git a/devtools/server/actors/utils/sources-manager.js b/devtools/server/actors/utils/sources-manager.js index 981a7c821385..bdd7181e2ba9 100644 --- a/devtools/server/actors/utils/sources-manager.js +++ b/devtools/server/actors/utils/sources-manager.js @@ -480,7 +480,10 @@ class SourcesManager extends EventEmitter { // actual text (otherwise it will be very confusing or unusable for users), // so replace the contents with the actual text if there is a mismatch. const actors = [...this._sourceActors.values()].filter( - actor => actor.url == url + // Bug 1907977: some source may not have a valid source text content exposed by spidermonkey + // and have their text be "[no source]", so avoid falling back to them and consider + // the request fallback. + actor => actor.url == url && actor.actualText() != "[no source]" ); if (!actors.every(actor => actor.contentMatches(result))) { if (actors.length > 1) {