mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-10 17:24:29 +00:00
Bug 1923899 - [bidi] Wait for currentWindowGlobal when sending commands to window global message handlers r=webdriver-reviewers,Sasha
When attempting to send commands on a very early browsing context, the command might fail due to a missing currentWindowGlobal. This patch adds a helper to wait for the currentWindowGlobal property to be set and uses it from RootTransport in order to avoid this issue. A browser mochitest is added to cover this scenario. Differential Revision: https://phabricator.services.mozilla.com/D225281
This commit is contained in:
parent
8e48f8f2fd
commit
8f75db2421
@ -79,6 +79,53 @@ add_task(async function test_windowglobalModule_command() {
|
||||
rootMessageHandler.destroy();
|
||||
});
|
||||
|
||||
// Test calling a windowglobal module as soon as possible.
|
||||
add_task(async function test_windowglobalModule_early_command() {
|
||||
const rootMessageHandler = createRootMessageHandler(
|
||||
"session-id-windowglobalModule-early"
|
||||
);
|
||||
|
||||
info("Setup an observer to send a command as soon as the context is created");
|
||||
const onContext = new Promise((resolve, reject) => {
|
||||
const onContextAttached = async browsingContext => {
|
||||
try {
|
||||
const result = await rootMessageHandler.handleCommand({
|
||||
moduleName: "command",
|
||||
commandName: "testWindowGlobalModule",
|
||||
destination: {
|
||||
type: WindowGlobalMessageHandler.type,
|
||||
id: browsingContext.id,
|
||||
},
|
||||
});
|
||||
info("Early command succeeded, resolve the retrieved value");
|
||||
resolve(result);
|
||||
} catch (e) {
|
||||
info("Early command failed, reject");
|
||||
reject(e);
|
||||
} finally {
|
||||
Services.obs.removeObserver(
|
||||
onContextAttached,
|
||||
"browsing-context-attached"
|
||||
);
|
||||
}
|
||||
};
|
||||
Services.obs.addObserver(onContextAttached, "browsing-context-attached");
|
||||
});
|
||||
|
||||
const tab = await addTab("https://example.com/document-builder.sjs?html=tab");
|
||||
|
||||
const windowGlobalValue = await onContext;
|
||||
is(
|
||||
windowGlobalValue,
|
||||
"windowglobal-value",
|
||||
"Retrieved the expected value from testWindowGlobalModule"
|
||||
);
|
||||
|
||||
rootMessageHandler.destroy();
|
||||
|
||||
gBrowser.removeTab(tab);
|
||||
});
|
||||
|
||||
// Test calling a method on a module which is only available in the "windowglobal"
|
||||
// folder. This will check that the MessageHandler/ModuleCache correctly moves
|
||||
// on to the next layer when no implementation can be found in the root layer.
|
||||
|
@ -2,6 +2,12 @@
|
||||
* 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/. */
|
||||
|
||||
const lazy = {};
|
||||
|
||||
ChromeUtils.defineESModuleGetters(lazy, {
|
||||
PollPromise: "chrome://remote/content/shared/Sync.sys.mjs",
|
||||
});
|
||||
|
||||
function isExtensionContext(browsingContext) {
|
||||
let principal;
|
||||
try {
|
||||
@ -93,3 +99,31 @@ export function isBrowsingContextCompatible(browsingContext, options = {}) {
|
||||
!isExtensionContext(browsingContext) && !isParentProcess(browsingContext)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait until `currentWindowGlobal` is available on a browsing context. When a
|
||||
* browsing context has just been created, the `currentWindowGlobal` might not
|
||||
* be attached yet.
|
||||
*
|
||||
* @param {CanonicalBrowsingContext} browsingContext
|
||||
* The browsing context to wait for.
|
||||
*
|
||||
* @returns {Promise}
|
||||
* Promise which resolves when `currentWindowGlobal` is set on the browsing
|
||||
* context or throws after 100ms.
|
||||
*/
|
||||
export async function waitForCurrentWindowGlobal(browsingContext) {
|
||||
await lazy.PollPromise(
|
||||
(resolve, reject) => {
|
||||
if (browsingContext.currentWindowGlobal) {
|
||||
resolve();
|
||||
} else {
|
||||
reject();
|
||||
}
|
||||
},
|
||||
{
|
||||
errorMessage: `currentWindowGlobal was not available for Browsing Context with id: ${browsingContext.id}`,
|
||||
timeout: 100,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
@ -15,6 +15,8 @@ ChromeUtils.defineESModuleGetters(lazy, {
|
||||
MessageHandlerFrameActor:
|
||||
"chrome://remote/content/shared/messagehandler/transports/js-window-actors/MessageHandlerFrameActor.sys.mjs",
|
||||
TabManager: "chrome://remote/content/shared/TabManager.sys.mjs",
|
||||
waitForCurrentWindowGlobal:
|
||||
"chrome://remote/content/shared/messagehandler/transports/BrowsingContextUtils.sys.mjs",
|
||||
});
|
||||
|
||||
ChromeUtils.defineLazyGetter(lazy, "logger", () => lazy.Log.get());
|
||||
@ -124,6 +126,9 @@ export class RootTransport {
|
||||
let attempts = 0;
|
||||
while (true) {
|
||||
try {
|
||||
if (!webProgress.browsingContext.currentWindowGlobal) {
|
||||
await lazy.waitForCurrentWindowGlobal(webProgress.browsingContext);
|
||||
}
|
||||
return await webProgress.browsingContext.currentWindowGlobal
|
||||
.getActor("MessageHandlerFrame")
|
||||
.sendCommand(command, this._messageHandler.sessionId);
|
||||
|
Loading…
x
Reference in New Issue
Block a user