summaryrefslogtreecommitdiffstats
path: root/browser/base/content/test/performance/browser_startup_content_subframe.js
diff options
context:
space:
mode:
Diffstat (limited to 'browser/base/content/test/performance/browser_startup_content_subframe.js')
-rw-r--r--browser/base/content/test/performance/browser_startup_content_subframe.js150
1 files changed, 150 insertions, 0 deletions
diff --git a/browser/base/content/test/performance/browser_startup_content_subframe.js b/browser/base/content/test/performance/browser_startup_content_subframe.js
new file mode 100644
index 0000000000..204d0ac1ba
--- /dev/null
+++ b/browser/base/content/test/performance/browser_startup_content_subframe.js
@@ -0,0 +1,150 @@
+/* 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,
+ });
+});