diff options
Diffstat (limited to 'remote/shared/messagehandler/test/browser/head.js')
-rw-r--r-- | remote/shared/messagehandler/test/browser/head.js | 236 |
1 files changed, 236 insertions, 0 deletions
diff --git a/remote/shared/messagehandler/test/browser/head.js b/remote/shared/messagehandler/test/browser/head.js new file mode 100644 index 0000000000..5397fc0761 --- /dev/null +++ b/remote/shared/messagehandler/test/browser/head.js @@ -0,0 +1,236 @@ +/* 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/. */ + +"use strict"; + +var { ContextDescriptorType } = ChromeUtils.importESModule( + "chrome://remote/content/shared/messagehandler/MessageHandler.sys.mjs" +); + +var { WindowGlobalMessageHandler } = ChromeUtils.importESModule( + "chrome://remote/content/shared/messagehandler/WindowGlobalMessageHandler.sys.mjs" +); + +var contextDescriptorAll = { + type: ContextDescriptorType.All, +}; + +function createRootMessageHandler(sessionId) { + const { RootMessageHandlerRegistry } = ChromeUtils.importESModule( + "chrome://remote/content/shared/messagehandler/RootMessageHandlerRegistry.sys.mjs" + ); + return RootMessageHandlerRegistry.getOrCreateMessageHandler(sessionId); +} + +/** + * Load the provided url in an existing browser. + * Returns a promise which will resolve when the page is loaded. + * + * @param {Browser} browser + * The browser element where the URL should be loaded. + * @param {string} url + * The URL to load in the new tab + */ +async function loadURL(browser, url) { + const loaded = BrowserTestUtils.browserLoaded(browser); + BrowserTestUtils.loadURIString(browser, url); + return loaded; +} + +/** + * Create a new foreground tab loading the provided url. + * Returns a promise which will resolve when the page is loaded. + * + * @param {string} url + * The URL to load in the new tab + */ +async function addTab(url) { + const tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, url); + registerCleanupFunction(() => { + gBrowser.removeTab(tab); + }); + return tab; +} + +/** + * Create inline markup for a simple iframe that can be used with + * document-builder.sjs. The iframe will be served under the provided domain. + * + * @param {string} domain + * A domain (eg "example.com"), compatible with build/pgo/server-locations.txt + */ +function createFrame(domain) { + return createFrameForUri( + `https://${domain}/document-builder.sjs?html=frame-${domain}` + ); +} + +function createFrameForUri(uri) { + return `<iframe src="${encodeURI(uri)}"></iframe>`; +} + +/** + * Create a XUL browser element in the provided XUL tab, with the provided type. + * + * @param {XULTab} tab + * The XUL tab in which the browser element should be inserted. + * @param {string} type + * The type attribute of the browser element, "chrome" or "content". + * @returns {XULBrowser} + * The created browser element. + */ +function createParentBrowserElement(tab, type) { + const parentBrowser = gBrowser.ownerDocument.createXULElement("browser"); + parentBrowser.setAttribute("type", type); + const container = gBrowser.getBrowserContainer(tab.linkedBrowser); + container.appendChild(parentBrowser); + + return parentBrowser; +} + +// Create a test page with 2 iframes: +// - one with a different eTLD+1 (example.com) +// - one with a nested iframe on a different eTLD+1 (example.net) +// +// Overall the document structure should look like: +// +// html (example.org) +// iframe (example.org) +// iframe (example.net) +// iframe(example.com) +// +// Which means we should have 4 browsing contexts in total. +function createTestMarkupWithFrames() { + // Create the markup for an example.net frame nested in an example.com frame. + const NESTED_FRAME_MARKUP = createFrameForUri( + `https://example.org/document-builder.sjs?html=${createFrame( + "example.net" + )}` + ); + + // Combine the nested frame markup created above with an example.com frame. + const TEST_URI_MARKUP = `${NESTED_FRAME_MARKUP}${createFrame("example.com")}`; + + // Create the test page URI on example.org. + return `https://example.org/document-builder.sjs?html=${encodeURI( + TEST_URI_MARKUP + )}`; +} + +const hasPromiseResolved = async function (promise) { + let resolved = false; + promise.finally(() => (resolved = true)); + // Make sure microtasks have time to run. + await new Promise(resolve => Services.tm.dispatchToMainThread(resolve)); + return resolved; +}; + +/** + * Install a sidebar extension. + * + * @returns {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 () { + const { browser } = this; + browser.test.sendMessage("sidebar-loaded", { + bcId: SpecialPowers.wrap(window).browsingContext.id, + }); + }, + "tab.html": ` + <!DOCTYPE html> + <html> + Test extension (tab) + <script src="tab.js"></script> + </html> + `, + "tab.js": function () { + const { browser } = this; + browser.test.sendMessage("tab-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, + }; +} + +const SessionDataUpdateHelpers = { + getUpdates(rootMessageHandler, browsingContext) { + return rootMessageHandler.handleCommand({ + moduleName: "sessiondataupdate", + commandName: "getSessionDataUpdates", + destination: { + id: browsingContext.id, + type: WindowGlobalMessageHandler.type, + }, + }); + }, + + createSessionDataUpdate( + values, + method, + category, + descriptor = { type: ContextDescriptorType.All } + ) { + return { + method, + values, + moduleName: "sessiondataupdate", + category, + contextDescriptor: descriptor, + }; + }, + + assertUpdate(update, expectedValues, expectedCategory) { + is( + update.length, + expectedValues.length, + "Update has the expected number of values" + ); + + for (const item of update) { + info(`Check session data update item '${item.value}'`); + is(item.category, expectedCategory, "Item has the expected category"); + is( + expectedValues[update.indexOf(item)], + item.value, + "Item has the expected value" + ); + } + }, +}; |