fix(chromium): propagate setUserAgent() to service workers via Network domain#41071
fix(chromium): propagate setUserAgent() to service workers via Network domain#41071sriram687 wants to merge 1 commit into
setUserAgent() to service workers via Network domain#41071Conversation
…k domain Service workers do not expose the Emulation domain, so Emulation.setUserAgentOverride cannot be used on their CDP session. However, Network.setUserAgentOverride is available and works correctly. Previously, browserContext.setUserAgent() silently skipped all existing service workers (a TODO comment acknowledged this gap). Now: - CRServiceWorker.updateUserAgent() applies Network.setUserAgentOverride on the service worker session, matching the acceptLanguage (locale) option as well. - updateUserAgent() is called during SW construction alongside the other network-level setup (updateOffline, updateHttpCredentials, etc.). - CRBrowserContext.setUserAgent() now loops over serviceWorkers() and calls updateUserAgent() on each, consistent with doUpdateOffline() and doSetHTTPCredentials(). Fixes the TODO comment at crBrowser.ts setUserAgent.
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Adds support for propagating userAgent (and locale-derived acceptLanguage) overrides to Chromium service workers by using the Network domain (since Emulation isn’t available there).
Changes:
- Invoke service worker
updateUserAgent()during initialization. - Implement
CRServiceWorker.updateUserAgent()viaNetwork.setUserAgentOverride. - Update
CRBrowserContext.doUpdateUserAgent()to also apply updates to existing service workers.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| packages/playwright-core/src/server/chromium/crServiceWorker.ts | Adds a service worker user agent update method and calls it during session initialization. |
| packages/playwright-core/src/server/chromium/crBrowser.ts | Extends browser context UA updates to include service workers. |
| const options = this.browserContext._options; | ||
| await this._session.send('Network.setUserAgentOverride', { | ||
| userAgent: options.userAgent || '', | ||
| acceptLanguage: options.locale, | ||
| }).catch(() => {}); |
| for (const page of this.pages()) | ||
| await (page.delegate as CRPage).updateUserAgent(); | ||
| // TODO: service workers don't have Emulation domain? | ||
| for (const sw of this.serviceWorkers()) | ||
| await (sw as CRServiceWorker).updateUserAgent(); |
| async updateUserAgent(): Promise<void> { | ||
| if (!this._isNetworkInspectionEnabled()) | ||
| return; | ||
| // Service workers do not expose the Emulation domain, so we use the Network | ||
| // domain's setUserAgentOverride which is available on the service worker session. | ||
| const options = this.browserContext._options; | ||
| await this._session.send('Network.setUserAgentOverride', { | ||
| userAgent: options.userAgent || '', | ||
| acceptLanguage: options.locale, | ||
| }).catch(() => {}); | ||
| } |
@microsoft-github-policy-service agree |
fix(chromium): propagate
setUserAgent()to service workers viaNetworkdomainResolves: (link your issue here)
What
Closes the long-standing TODO in
crBrowser.tswherebrowserContext.setUserAgent()silently skipped all active service workers with no warning to the developer.Why
Service workers do not expose the
EmulationCDP domain, soEmulation.setUserAgentOverride— which pages use — cannot be called on their sessions. The fix usesNetwork.setUserAgentOverride, which is available on service worker sessions. This is the same domain already used byupdateOffline(),updateHttpCredentials(), andupdateExtraHTTPHeaders()for service workers.Changes
crServiceWorker.tsupdateUserAgent()usingNetwork.setUserAgentOverridewithuserAgentandacceptLanguage(locale) from browser context optionscrBrowser.tssetUserAgent()now loops overserviceWorkers()and callsupdateUserAgent()on each — consistent withdoUpdateOffline()anddoSetHTTPCredentials()Problem
Playwright tried to update the Service Worker's User-Agent using the page-only command:
Emulation.setUserAgentOverrideBut Service Workers do not support the Emulation category. As a result, Playwright skipped them, leaving service workers using the default user-agent while the web page used the overridden one.
The Fix
We updated the code to use the Network category command instead:
Network.setUserAgentOverrideSince Service Workers already use the Network category to check offline modes and intercepts, this command works. We then updated
crBrowser.tsto loop over all active service workers and call this update whenever the user-agent is changed.Testing
Existing tests in
tests/library/chromium/extensions.spec.tspass without modification.Checklist
updateOffline/updateHttpCredentialspattern exactly.catch(() => {})— consistent with all sibling methodsResolves: #41070