/* Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ */ /* This test records which services, JS components, frame scripts, process * scripts, and JS modules are loaded when creating a new content process for a * subframe. * * If you made changes that cause this test to fail, it's likely because you * are loading more JS code during content process startup. Please try to * avoid this. * * If your code isn't strictly required to show an iframe, consider loading it * lazily. If you can't, consider delaying its load until after we have started * handling user events. * * This test differs from browser_startup_content.js in that it tests a process * with no toplevel browsers opened, but with a single subframe document * loaded. This leads to a different set of scripts being loaded. */ "use strict"; const actorModuleURI = getRootDirectory(gTestPath) + "StartupContentSubframe.sys.mjs"; const subframeURI = getRootDirectory(gTestPath).replace( "chrome://mochitests/content", "https://example.com" ) + "file_empty.html"; // Set this to true only for debugging purpose; it makes the output noisy. const kDumpAllStacks = false; const known_scripts = { modules: new Set([ // Loaded by this test actorModuleURI, // General utilities "resource://gre/modules/AppConstants.sys.mjs", "resource://gre/modules/XPCOMUtils.sys.mjs", // Logging related "resource://gre/modules/Log.sys.mjs", // Telemetry "resource://gre/modules/TelemetryControllerBase.sys.mjs", // bug 1470339 "resource://gre/modules/TelemetryControllerContent.sys.mjs", // bug 1470339 // Extensions "resource://gre/modules/ExtensionProcessScript.sys.mjs", "resource://gre/modules/ExtensionUtils.sys.mjs", ]), processScripts: new Set([ "chrome://global/content/process-content.js", "resource://gre/modules/extensionProcessScriptLoader.js", ]), }; // Items on this list *might* load when creating the process, as opposed to // items in the main list, which we expect will always load. const intermittently_loaded_scripts = { modules: new Set([ "resource://gre/modules/nsAsyncShutdown.sys.mjs", // Cookie banner handling. "resource://gre/actors/CookieBannerChild.sys.mjs", "resource://gre/modules/PrivateBrowsingUtils.sys.mjs", // Test related "chrome://remote/content/marionette/actors/MarionetteEventsChild.sys.mjs", "chrome://remote/content/shared/Log.sys.mjs", "resource://testing-common/BrowserTestUtilsChild.sys.mjs", "resource://testing-common/ContentEventListenerChild.sys.mjs", "resource://testing-common/SpecialPowersChild.sys.mjs", "resource://specialpowers/AppTestDelegateChild.sys.mjs", "resource://testing-common/WrapPrivileged.sys.mjs", ]), processScripts: new Set([]), }; const forbiddenScripts = { services: new Set([ "@mozilla.org/base/telemetry-startup;1", "@mozilla.org/embedcomp/default-tooltiptextprovider;1", "@mozilla.org/push/Service;1", ]), }; add_task(async function () { SimpleTest.requestCompleteLog(); // Increase the maximum number of webIsolated content processes to make sure // our newly-created iframe is spawned into a new content process. // // Unfortunately, we don't have something like `forceNewProcess` for subframe // loads. await SpecialPowers.pushPrefEnv({ set: [["dom.ipc.processCount.webIsolated", 10]], }); Services.ppmm.releaseCachedProcesses(); // Register a custom window actor which will send us a notification when the // script loading information is available. ChromeUtils.registerWindowActor("StartupContentSubframe", { parent: { esModuleURI: actorModuleURI, }, child: { esModuleURI: actorModuleURI, events: { load: { mozSystemGroup: true, capture: true }, }, }, matches: [subframeURI], allFrames: true, }); // Create a tab, and load a remote subframe with the specific URI in it. let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser); SpecialPowers.spawn(tab.linkedBrowser, [subframeURI], uri => { let iframe = content.document.createElement("iframe"); iframe.src = uri; content.document.body.appendChild(iframe); }); // Wait for the reply to come in, remove the XPCOM wrapper, and unregister our actor. let [subject] = await TestUtils.topicObserved( "startup-content-subframe-loaded-scripts" ); let loadedInfo = subject.wrappedJSObject; ChromeUtils.unregisterWindowActor("StartupContentSubframe"); BrowserTestUtils.removeTab(tab); // Gather loaded process scripts. loadedInfo.processScripts = {}; for (let [uri] of Services.ppmm.getDelayedProcessScripts()) { loadedInfo.processScripts[uri] = ""; } await checkLoadedScripts({ loadedInfo, known: known_scripts, intermittent: intermittently_loaded_scripts, forbidden: forbiddenScripts, dumpAllStacks: kDumpAllStacks, }); });