browser_startup_content_subframe.js (5071B)
1 /* Any copyright is dedicated to the Public Domain. 2 http://creativecommons.org/publicdomain/zero/1.0/ */ 3 4 /* This test records which services, JS components, frame scripts, process 5 * scripts, and JS modules are loaded when creating a new content process for a 6 * subframe. 7 * 8 * If you made changes that cause this test to fail, it's likely because you 9 * are loading more JS code during content process startup. Please try to 10 * avoid this. 11 * 12 * If your code isn't strictly required to show an iframe, consider loading it 13 * lazily. If you can't, consider delaying its load until after we have started 14 * handling user events. 15 * 16 * This test differs from browser_startup_content.js in that it tests a process 17 * with no toplevel browsers opened, but with a single subframe document 18 * loaded. This leads to a different set of scripts being loaded. 19 */ 20 21 "use strict"; 22 23 const actorModuleURI = 24 getRootDirectory(gTestPath) + "StartupContentSubframe.sys.mjs"; 25 const subframeURI = 26 getRootDirectory(gTestPath).replace( 27 "chrome://mochitests/content", 28 "https://example.com" 29 ) + "file_empty.html"; 30 31 // Set this to true only for debugging purpose; it makes the output noisy. 32 const kDumpAllStacks = false; 33 34 const known_scripts = { 35 modules: new Set([ 36 // Loaded by this test 37 actorModuleURI, 38 39 // General utilities 40 "resource://gre/modules/AppConstants.sys.mjs", 41 "resource://gre/modules/XPCOMUtils.sys.mjs", 42 43 // Logging related 44 // eslint-disable-next-line mozilla/use-console-createInstance 45 "resource://gre/modules/Log.sys.mjs", 46 47 // Telemetry 48 "resource://gre/modules/TelemetryControllerBase.sys.mjs", // bug 1470339 49 "resource://gre/modules/TelemetryControllerContent.sys.mjs", // bug 1470339 50 51 // Extensions 52 "resource://gre/modules/ExtensionProcessScript.sys.mjs", 53 "resource://gre/modules/ExtensionUtils.sys.mjs", 54 ]), 55 processScripts: new Set([ 56 "chrome://global/content/process-content.js", 57 "resource://gre/modules/extensionProcessScriptLoader.js", 58 ]), 59 }; 60 61 // Items on this list *might* load when creating the process, as opposed to 62 // items in the main list, which we expect will always load. 63 const intermittently_loaded_scripts = { 64 modules: new Set([ 65 "resource://gre/modules/nsAsyncShutdown.sys.mjs", 66 67 // Cookie banner handling. 68 "resource://gre/actors/CookieBannerChild.sys.mjs", 69 "resource://gre/modules/PrivateBrowsingUtils.sys.mjs", 70 71 // Test related 72 "chrome://remote/content/marionette/actors/MarionetteEventsChild.sys.mjs", 73 "chrome://remote/content/shared/Log.sys.mjs", 74 "resource://testing-common/BrowserTestUtilsChild.sys.mjs", 75 "resource://testing-common/ContentEventListenerChild.sys.mjs", 76 "resource://testing-common/SpecialPowersChild.sys.mjs", 77 "resource://specialpowers/AppTestDelegateChild.sys.mjs", 78 "resource://testing-common/WrapPrivileged.sys.mjs", 79 ]), 80 processScripts: new Set([]), 81 }; 82 83 const forbiddenScripts = { 84 services: new Set([ 85 "@mozilla.org/base/telemetry-startup;1", 86 "@mozilla.org/embedcomp/default-tooltiptextprovider;1", 87 "@mozilla.org/push/Service;1", 88 ]), 89 }; 90 91 add_task(async function () { 92 SimpleTest.requestCompleteLog(); 93 94 // Increase the maximum number of webIsolated content processes to make sure 95 // our newly-created iframe is spawned into a new content process. 96 // 97 // Unfortunately, we don't have something like `forceNewProcess` for subframe 98 // loads. 99 await SpecialPowers.pushPrefEnv({ 100 set: [["dom.ipc.processCount.webIsolated", 10]], 101 }); 102 Services.ppmm.releaseCachedProcesses(); 103 104 // Register a custom window actor which will send us a notification when the 105 // script loading information is available. 106 ChromeUtils.registerWindowActor("StartupContentSubframe", { 107 parent: { 108 esModuleURI: actorModuleURI, 109 }, 110 child: { 111 esModuleURI: actorModuleURI, 112 events: { 113 load: { mozSystemGroup: true, capture: true }, 114 }, 115 }, 116 matches: [subframeURI], 117 allFrames: true, 118 }); 119 120 // Create a tab, and load a remote subframe with the specific URI in it. 121 let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser); 122 123 SpecialPowers.spawn(tab.linkedBrowser, [subframeURI], uri => { 124 let iframe = content.document.createElement("iframe"); 125 iframe.src = uri; 126 content.document.body.appendChild(iframe); 127 }); 128 129 // Wait for the reply to come in, remove the XPCOM wrapper, and unregister our actor. 130 let [subject] = await TestUtils.topicObserved( 131 "startup-content-subframe-loaded-scripts" 132 ); 133 let loadedInfo = subject.wrappedJSObject; 134 135 ChromeUtils.unregisterWindowActor("StartupContentSubframe"); 136 BrowserTestUtils.removeTab(tab); 137 138 // Gather loaded process scripts. 139 loadedInfo.processScripts = new Map(); 140 for (let [uri] of Services.ppmm.getDelayedProcessScripts()) { 141 loadedInfo.processScripts.set(uri, ""); 142 } 143 144 await checkLoadedScripts({ 145 loadedInfo, 146 known: known_scripts, 147 intermittent: intermittently_loaded_scripts, 148 forbidden: forbiddenScripts, 149 dumpAllStacks: kDumpAllStacks, 150 }); 151 });