diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
commit | 36d22d82aa202bb199967e9512281e9a53db42c9 (patch) | |
tree | 105e8c98ddea1c1e4784a60a5a6410fa416be2de /devtools/shared/commands/target-configuration/tests/browser_target_configuration_command_custom_user_agent.js | |
parent | Initial commit. (diff) | |
download | firefox-esr-upstream.tar.xz firefox-esr-upstream.zip |
Adding upstream version 115.7.0esr.upstream/115.7.0esrupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'devtools/shared/commands/target-configuration/tests/browser_target_configuration_command_custom_user_agent.js')
-rw-r--r-- | devtools/shared/commands/target-configuration/tests/browser_target_configuration_command_custom_user_agent.js | 309 |
1 files changed, 309 insertions, 0 deletions
diff --git a/devtools/shared/commands/target-configuration/tests/browser_target_configuration_command_custom_user_agent.js b/devtools/shared/commands/target-configuration/tests/browser_target_configuration_command_custom_user_agent.js new file mode 100644 index 0000000000..3ed0f8e142 --- /dev/null +++ b/devtools/shared/commands/target-configuration/tests/browser_target_configuration_command_custom_user_agent.js @@ -0,0 +1,309 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +// Test setting custom user agent. +const TEST_DOCUMENT = "target_configuration_test_doc.sjs"; +const TEST_URI = URL_ROOT_COM_SSL + TEST_DOCUMENT; + +add_task(async function () { + const tab = await addTab(TEST_URI); + + info("Create commands for the tab"); + const commands = await CommandsFactory.forTab(tab); + + const targetConfigurationCommand = commands.targetConfigurationCommand; + const targetCommand = commands.targetCommand; + await targetCommand.startListening(); + + const initialUserAgent = await getTopLevelUserAgent(); + + info("Update configuration to change user agent"); + const CUSTOM_USER_AGENT = "<MY_BORING_CUSTOM_USER_AGENT>"; + + await targetConfigurationCommand.updateConfiguration({ + customUserAgent: CUSTOM_USER_AGENT, + }); + + is( + await getTopLevelUserAgent(), + CUSTOM_USER_AGENT, + "The user agent is properly set on the top level document after updating the configuration" + ); + is( + await getUserAgentForTopLevelRequest(commands), + CUSTOM_USER_AGENT, + "The custom user agent is used when retrieving resources on the top level document" + ); + + is( + await getIframeUserAgent(), + CUSTOM_USER_AGENT, + "The user agent is properly set on the iframe after updating the configuration" + ); + is( + await getUserAgentForIframeRequest(commands), + CUSTOM_USER_AGENT, + "The custom user agent is used when retrieving resources on the iframe" + ); + + info("Reload the page"); + await BrowserTestUtils.reloadTab(tab, /* includeSubFrames */ true); + + is( + await getTopLevelDocumentUserAgentAtStartup(), + CUSTOM_USER_AGENT, + "The custom user agent was set in the content page when it loaded after reloading" + ); + is( + await getTopLevelUserAgent(), + CUSTOM_USER_AGENT, + "The custom user agent is set in the content page after reloading" + ); + is( + await getUserAgentForTopLevelRequest(commands), + CUSTOM_USER_AGENT, + "The custom user agent is used when retrieving resources after reloading" + ); + is( + await getIframeUserAgentAtStartup(), + CUSTOM_USER_AGENT, + "The custom user agent was set in the remote iframe when it loaded after reloading" + ); + is( + await getIframeUserAgent(), + CUSTOM_USER_AGENT, + "The custom user agent is set in the remote iframe after reloading" + ); + is( + await getUserAgentForIframeRequest(commands), + CUSTOM_USER_AGENT, + "The custom user agent is used when retrieving resources in the remote iframe after reloading" + ); + + const previousBrowsingContextId = gBrowser.selectedBrowser.browsingContext.id; + info( + "Check that navigating to a page that forces the creation of a new browsing context keep the simulation enabled" + ); + + const onPageLoaded = BrowserTestUtils.browserLoaded( + gBrowser.selectedBrowser, + /* includeSubFrames */ true + ); + BrowserTestUtils.loadURIString( + gBrowser.selectedBrowser, + URL_ROOT_ORG_SSL + TEST_DOCUMENT + "?crossOriginIsolated=true" + ); + await onPageLoaded; + + isnot( + gBrowser.selectedBrowser.browsingContext.id, + previousBrowsingContextId, + "A new browsing context was created" + ); + + is( + await getTopLevelDocumentUserAgentAtStartup(), + CUSTOM_USER_AGENT, + "The custom user agent was set in the content page when it loaded after navigating to a new browsing context" + ); + is( + await getTopLevelUserAgent(), + CUSTOM_USER_AGENT, + "The custom user agent is set in the content page after navigating to a new browsing context" + ); + is( + await getUserAgentForTopLevelRequest(commands), + CUSTOM_USER_AGENT, + "The custom user agent is used when retrieving resources after navigating to a new browsing context" + ); + is( + await getIframeUserAgentAtStartup(), + CUSTOM_USER_AGENT, + "The custom user agent was set in the remote iframe when it loaded after navigating to a new browsing context" + ); + is( + await getIframeUserAgent(), + CUSTOM_USER_AGENT, + "The custom user agent is set in the remote iframe after navigating to a new browsing context" + ); + is( + await getUserAgentForTopLevelRequest(commands), + CUSTOM_USER_AGENT, + "The custom user agent is used when retrieving resources in the remote iframes after navigating to a new browsing context" + ); + + info( + "Create another commands instance and check that destroying it won't reset the user agent" + ); + const otherCommands = await CommandsFactory.forTab(tab); + const otherTargetConfigurationCommand = + otherCommands.targetConfigurationCommand; + const otherTargetCommand = otherCommands.targetCommand; + await otherTargetCommand.startListening(); + // wait for the target to be fully attached to avoid pending connection to the server + await otherTargetCommand.watchTargets({ + types: [otherTargetCommand.TYPES.FRAME], + onAvailable: () => {}, + }); + + // Let's update the configuration with this commands instance to make sure we hit the TargetConfigurationActor + await otherTargetConfigurationCommand.updateConfiguration({ + colorSchemeSimulation: "dark", + }); + + otherTargetCommand.destroy(); + await otherCommands.destroy(); + + is( + await getTopLevelUserAgent(), + CUSTOM_USER_AGENT, + "The custom user agent is still set on the page after destroying another commands instance" + ); + + info( + "Check that destroying the commands we set the user agent in will reset the user agent" + ); + targetCommand.destroy(); + await commands.destroy(); + + // XXX: This is needed at the moment since Navigator.cpp retrieve the UserAgent from the + // headers (when there's no custom user agent). And here, since we reloaded the page once + // we set the custom user agent, the header was set accordingly and still holds the custom + // user agent value. This should be fixed by Bug 1705326. + is( + await getTopLevelUserAgent(), + CUSTOM_USER_AGENT, + "The custom user agent is still set on the page after destroying the first commands instance. Bug 1705326 will fix that and make it equal to `initialUserAgent`" + ); + + await BrowserTestUtils.reloadTab(tab, /* includeSubFrames */ true); + is( + await getTopLevelUserAgent(), + initialUserAgent, + "The user agent was reset in the content page after destroying the commands" + ); + is( + await getIframeUserAgent(), + initialUserAgent, + "The user agent was reset in the remote iframe after destroying the commands" + ); + + // We need commands to retrieve the headers of the network request, and + // all those we created so far were destroyed; let's create new ones. + const newCommands = await CommandsFactory.forTab(tab); + await newCommands.targetCommand.startListening(); + is( + await getUserAgentForTopLevelRequest(newCommands), + initialUserAgent, + "The initial user agent is used when retrieving resources after destroying the commands" + ); + is( + await getUserAgentForIframeRequest(newCommands), + initialUserAgent, + "The initial user agent is used when retrieving resources on the remote iframe after destroying the commands" + ); +}); + +function getUserAgent(browserOrBrowsingContext) { + return SpecialPowers.spawn(browserOrBrowsingContext, [], () => { + return content.navigator.userAgent; + }); +} + +function getUserAgentAtStartup(browserOrBrowsingContext) { + return SpecialPowers.spawn( + browserOrBrowsingContext, + [], + () => content.wrappedJSObject.initialUserAgent + ); +} + +function getTopLevelUserAgent() { + return getUserAgent(gBrowser.selectedBrowser); +} + +function getTopLevelDocumentUserAgentAtStartup() { + return getUserAgentAtStartup(gBrowser.selectedBrowser); +} + +function getIframeBrowsingContext() { + return SpecialPowers.spawn( + gBrowser.selectedBrowser, + [], + () => content.document.querySelector("iframe").browsingContext + ); +} + +async function getIframeUserAgent() { + const iframeBC = await getIframeBrowsingContext(); + return getUserAgent(iframeBC); +} + +async function getIframeUserAgentAtStartup() { + const iframeBC = await getIframeBrowsingContext(); + return getUserAgentAtStartup(iframeBC); +} + +async function getRequestUserAgent(commands, browserOrBrowsingContext) { + const url = `unknown?${Date.now()}`; + + // Wait for the resource and its headers to be available + const onAvailable = () => {}; + let onUpdated; + + const onResource = new Promise(resolve => { + onUpdated = updates => { + for (const { resource } of updates) { + if (resource.url.includes(url) && resource.requestHeadersAvailable) { + resolve(resource); + } + } + }; + + commands.resourceCommand.watchResources( + [commands.resourceCommand.TYPES.NETWORK_EVENT], + { + onAvailable, + onUpdated, + ignoreExistingResources: true, + } + ); + }); + + info(`Fetch ${url}`); + SpecialPowers.spawn(browserOrBrowsingContext, [url], innerUrl => { + content.fetch(`./${innerUrl}`); + }); + info("waiting for matching resource…"); + const networkResource = await onResource; + + info("…got resource, retrieve headers"); + const packet = { + to: networkResource.actor, + type: "getRequestHeaders", + }; + + const { headers } = await commands.client.request(packet); + + commands.resourceCommand.unwatchResources( + [commands.resourceCommand.TYPES.NETWORK_EVENT], + { + onAvailable, + onUpdated, + ignoreExistingResources: true, + } + ); + + return headers.find(header => header.name == "User-Agent")?.value; +} + +async function getUserAgentForTopLevelRequest(commands) { + return getRequestUserAgent(commands, gBrowser.selectedBrowser); +} + +async function getUserAgentForIframeRequest(commands) { + const iframeBC = await getIframeBrowsingContext(); + return getRequestUserAgent(commands, iframeBC); +} |