commit 792a8ccf58ec9d8cc1adbc1e4a4a417c7018e485
parent a0e7334489e49a076bf97b9226a3865ce595b5d3
Author: Mike Conley <mconley@mozilla.com>
Date: Wed, 17 Dec 2025 16:19:02 +0000
Bug 2001387 - Part 1: Have BrowserUtils.callModulesFromCategory return a Promise that resolves when all module tasks are settled. r=Gijs
Differential Revision: https://phabricator.services.mozilla.com/D276294
Diffstat:
2 files changed, 65 insertions(+), 2 deletions(-)
diff --git a/toolkit/modules/BrowserUtils.sys.mjs b/toolkit/modules/BrowserUtils.sys.mjs
@@ -570,6 +570,8 @@ export var BrowserUtils = {
* order to do custom failure handling.
* @param {...any} args
* Arguments to pass to the consumers.
+ * @returns {Promise}
+ * A Promise that resolves when all consumers have settled.
*/
callModulesFromCategory(
{
@@ -613,15 +615,25 @@ export var BrowserUtils = {
}
};
+ let allTasks = [];
+
for (let listener of lazy.CatManListenerManager.getListeners(
categoryName
)) {
if (idleDispatch) {
- ChromeUtils.idleDispatch(() => callSingleListener(listener));
+ allTasks.push(
+ new Promise(resolve => {
+ ChromeUtils.idleDispatch(() => {
+ resolve(callSingleListener(listener));
+ });
+ })
+ );
} else {
- callSingleListener(listener);
+ allTasks.push(callSingleListener(listener));
}
}
+
+ return Promise.allSettled(allTasks);
},
/**
diff --git a/toolkit/modules/tests/xpcshell/test_BrowserUtils.js b/toolkit/modules/tests/xpcshell/test_BrowserUtils.js
@@ -386,6 +386,9 @@ add_task(async function test_callModulesFromCategory() {
Assert.equal("Hello", await idlePromise, "Idle calls should run eventually.");
Services.obs.removeObserver(ob, OBSTOPIC1);
+
+ // Now clean up our category for later tests.
+ Services.catMan.deleteCategory(CATEGORY);
});
// Test that errors are reported but do not throw at the callsite,
@@ -449,4 +452,52 @@ add_task(async function test_callModulesFromCategory_errors() {
"Uh oh",
"Exceptions should be handled."
);
+
+ // Now clean up our category for later tests.
+ Services.catMan.deleteCategory(OTHER_CAT);
+});
+
+/**
+ * Test that callModulesFromCategory returns a Promise that resolves when all
+ * category tasks have settled.
+ */
+add_task(async function test_callModulesFromCategory_returns_promise() {
+ const CATEGORY = "test-modules-from-catman";
+ const MODULE1 = "resource://test/my_catman_1.sys.mjs";
+ const OBSTOPIC1 = CATEGORY + "-notification";
+
+ let catManUpdated = TestUtils.topicObserved("xpcom-category-entry-added");
+ Services.catMan.addCategoryEntry(
+ CATEGORY,
+ MODULE1,
+ `Module1.test`,
+ false,
+ false
+ );
+ await catManUpdated;
+
+ let moduleResult = TestUtils.topicObserved(OBSTOPIC1).then(
+ ([_subj, data]) => data
+ );
+
+ let result = BrowserUtils.callModulesFromCategory(
+ { categoryName: CATEGORY },
+ "Hello"
+ );
+
+ Assert.ok(result.then, "Should return a Promise");
+
+ let settledResults = await result;
+ Assert.ok(Array.isArray(settledResults), "Should return an array of results");
+ Assert.equal(settledResults.length, 1, "Should have one result");
+ Assert.equal(
+ settledResults[0].status,
+ "fulfilled",
+ "Task should have been fulfilled"
+ );
+
+ Assert.equal(await moduleResult, "Hello", "Module should have been called");
+
+ // Now clean up our category for later tests.
+ Services.catMan.deleteCategory(CATEGORY);
});