Bug 1753939 - [remote] Do not create message handlers for webextension contexts r=webdriver-reviewers,rpl,whimboo

Differential Revision: https://phabricator.services.mozilla.com/D138523
This commit is contained in:
Julian Descottes 2022-02-14 23:07:45 +00:00
parent 28158b5d80
commit a881d0f446
4 changed files with 102 additions and 18 deletions

View File

@ -8,17 +8,39 @@ const TEST_PAGE = "https://example.com/document-builder.sjs?html=tab";
/**
* Check that message handlers are not created for parent process browser
* elements, even if they have the type="content" attribute (eg used for the
* DevTools toolbox).
* DevTools toolbox), as well as for webextension contexts.
*/
add_task(async function test_session_data_broadcast() {
// Prepare:
// - one content tab
// - one browser type content
// - one browser type chrome
// - one sidebar webextension
// We only expect session data to be applied to the content tab
const tab1 = BrowserTestUtils.addTab(gBrowser, TEST_PAGE);
const contentBrowser1 = tab1.linkedBrowser;
await BrowserTestUtils.browserLoaded(contentBrowser1);
const parentBrowser1 = createParentBrowserElement(tab1, "content");
const parentBrowser2 = createParentBrowserElement(tab1, "chrome");
const {
extension: extension1,
sidebarBrowser: extSidebarBrowser1,
} = await installSidebarExtension();
const root = createRootMessageHandler("session-id-event");
// When the windowglobal command.jsm module applies the session data
// browser_session_data_browser_element, it will emit an internal event.
// Collect the events to detect which MessageHandlers have been started.
info("Watch internal events emitted when session data is applied");
const sessionDataEvents = [];
const onRootEvent = function(evtName, wrappedEvt) {
if (wrappedEvt.name === "received-session-data") {
sessionDataEvents.push(wrappedEvt.data.contextId);
}
};
root.on("message-handler-event", onRootEvent);
info("Add a new session data item, expect one return value");
await root.addSessionData({
moduleName: "command",
@ -29,12 +51,17 @@ add_task(async function test_session_data_broadcast() {
values: [true],
});
function hasSessionData(browsingContext) {
return sessionDataEvents.includes(browsingContext.id);
}
info(
"Check that only the content tab window global received the session data"
);
is(await hasSessionDataFlag(contentBrowser1), true);
is(await hasSessionDataFlag(parentBrowser1), undefined);
is(await hasSessionDataFlag(parentBrowser2), undefined);
is(hasSessionData(contentBrowser1.browsingContext), true);
is(hasSessionData(parentBrowser1.browsingContext), false);
is(hasSessionData(parentBrowser2.browsingContext), false);
is(hasSessionData(extSidebarBrowser1.browsingContext), false);
const tab2 = BrowserTestUtils.addTab(gBrowser, TEST_PAGE);
const contentBrowser2 = tab2.linkedBrowser;
@ -42,23 +69,30 @@ add_task(async function test_session_data_broadcast() {
const parentBrowser3 = createParentBrowserElement(contentBrowser2, "content");
const parentBrowser4 = createParentBrowserElement(contentBrowser2, "chrome");
const {
extension: extension2,
sidebarBrowser: extSidebarBrowser2,
} = await installSidebarExtension();
info("Wait until the session data was applied to the new tab");
await SpecialPowers.spawn(contentBrowser2, [], async () => {
await ContentTaskUtils.waitForCondition(() => content.hasSessionDataFlag);
});
await TestUtils.waitForCondition(() =>
sessionDataEvents.includes(contentBrowser2.browsingContext.id)
);
info("Check that parent browser elements did not apply the session data");
is(await hasSessionDataFlag(parentBrowser3), undefined);
is(await hasSessionDataFlag(parentBrowser4), undefined);
is(hasSessionData(parentBrowser3.browsingContext), false);
is(hasSessionData(parentBrowser4.browsingContext), false);
info(
"Check that extension did not apply the session data, " +
extSidebarBrowser2.browsingContext.id
);
is(hasSessionData(extSidebarBrowser2.browsingContext), false);
root.destroy();
gBrowser.removeTab(tab1);
gBrowser.removeTab(tab2);
await extension1.unload();
await extension2.unload();
});
function hasSessionDataFlag(browser) {
return SpecialPowers.spawn(browser, [], () => {
return content.hasSessionDataFlag;
});
}

View File

@ -113,3 +113,52 @@ function createTestMarkupWithFrames() {
TEST_URI_MARKUP
)}`;
}
/**
* Install a sidebar extension.
*
* @return {Object}
* Return value with two properties:
* - extension: test wrapper as returned by SpecialPowers.loadExtension.
* Make sure to explicitly call extension.unload() before the end of the test.
* - sidebarBrowser: the browser element containing the extension sidebar.
*/
async function installSidebarExtension() {
info("Load the test extension");
let extension = ExtensionTestUtils.loadExtension({
manifest: {
sidebar_action: {
default_panel: "sidebar.html",
},
},
useAddonManager: "temporary",
files: {
"sidebar.html": `
<!DOCTYPE html>
<html>
Test extension
<script src="sidebar.js"></script>
</html>
`,
"sidebar.js": function() {
browser.test.sendMessage("sidebar-loaded", {
bcId: SpecialPowers.wrap(window).browsingContext.id,
});
},
},
});
info("Wait for the extension to start");
await extension.startup();
info("Wait for the extension browsing context");
const { bcId } = await extension.awaitMessage("sidebar-loaded");
const sidebarBrowser = BrowsingContext.get(bcId).top.embedderElement;
ok(sidebarBrowser, "Got a browser element for the extension sidebar");
return {
extension,
sidebarBrowser,
};
}

View File

@ -41,9 +41,9 @@ class Command extends Module {
}
if (params.category === "browser_session_data_browser_element") {
BrowsingContext.get(
this.messageHandler.contextId
).window.hasSessionDataFlag = true;
this.emitEvent("received-session-data", {
contextId: this.messageHandler.contextId,
});
}
return {};

View File

@ -30,6 +30,7 @@ const FRAME_ACTOR_CONFIG = {
},
},
allFrames: true,
messageManagerGroups: ["browsers"],
};
/**