Skip to content

Conversation

sadym-chromium
Copy link
Contributor

@sadym-chromium sadym-chromium commented Aug 19, 2025

Support for user-agent emulations. Required for WebDriver BiDi: https://www.w3.org/TR/webdriver-bidi/#command-emulation-setUserAgentOverride (w3c/webdriver-bidi#448).

Introduce "environment default User-Agent value" to reference it from the HTML specification.

(See WHATWG Working Mode: Changes for more details.)


Preview | Diff

@sadym-chromium sadym-chromium changed the title WebDriver BiDi emulated user-agent [WebDriver BiDi] emulate user-agent string Aug 19, 2025
sadym-chromium added a commit to w3c/webdriver-bidi that referenced this pull request Sep 10, 2025
Specification for `emulation.setUserAgentOverride` command. 
* Introduce a new hook "WebDriver BiDi emulated User-Agent".
* Fetch spec update required, as the default `User-Agent` headers is set BEFORE the "[WebDriver BiDi before request sent](https://w3c.github.io/webdriver-bidi/#webdriver-bidi-before-request-sent)" is invoked, so there is no way to distinguish between the user explicitly set the `User-Agent` vs the [default `User-Agent` value](https://fetch.spec.whatwg.org/#default-user-agent-value) was used. Use the hook in Fetch spec: whatwg/fetch#1851
* HTML spec update required to return the proper `User-Agent` as the result of the `navigator.userAgent`. Use the hook in HTML spec: whatwg/html#11576
@sadym-chromium sadym-chromium marked this pull request as ready for review September 16, 2025 11:44
@sadym-chromium
Copy link
Contributor Author

@noamr PTAL

Copy link
Contributor

@noamr noamr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unofficial LGTM

@sadym-chromium sadym-chromium force-pushed the sadym/emulation.setUserAgentOverride branch from 63b1d36 to 042c341 Compare September 16, 2025 12:16
@sadym-chromium sadym-chromium force-pushed the sadym/emulation.setUserAgentOverride branch from 29769d0 to b677da0 Compare September 16, 2025 12:58
@sadym-chromium sadym-chromium force-pushed the sadym/emulation.setUserAgentOverride branch from da890bd to 4076b59 Compare September 16, 2025 13:28
Copy link
Member

@annevk annevk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had these comments, but you just refactored it further. I'm not sure I like removing the default User-Agent value concept entirely. Is that really what we want?

I now also wonder at what point implementations ask WebDriver for this value as it seems unlikely to happen in het network layer, where the User-Agent value is currently appended.

sadym-chromium and others added 3 commits September 16, 2025 15:43
@sadym-chromium
Copy link
Contributor Author

sadym-chromium commented Sep 16, 2025

I had these comments, but you just refactored it further. I'm not sure I like removing the default User-Agent value concept entirely. Is that really what we want?

I now also wonder at what point implementations ask WebDriver for this value as it seems unlikely to happen in het network layer, where the User-Agent value is currently appended.

@annevk Ok, I reverted the last change where I merged the "environment default <code>User-Agent</code> value" and "default <code>User-Agent</code> value" and applied your proposed changes.

@annevk
Copy link
Member

annevk commented Sep 16, 2025

So this looks good, but what about the timing of this call? Presumably it happens earlier, but maybe we can decide not to worry about that for now? Hmm.

@sadym-chromium
Copy link
Contributor Author

I now also wonder at what point implementations ask WebDriver for this value as it seems unlikely to happen in het network layer, where the User-Agent value is currently appended.

@annevk in Chromium, we rely on Emulation.setUserAgentOverride method, which sets the user agent override, which is read in the renderer.

@annevk
Copy link
Member

annevk commented Sep 16, 2025

I think that does mean there are some issues with this setup. In that if you hit a couple of redirects and you call that method repeatedly, the User-Agent header would not change in value, but per this specification as written it ought to change.

To fix that and some race issues we'd have to grab the current User-Agent header before we go in parallel and use it for the entire duration of the fetch. I'm okay with not doing that for now, but I'm curious what other people think about what level of accuracy we need here. Maybe @jgraham is willing to chime in.

@sadym-chromium
Copy link
Contributor Author

I think that does mean there are some issues with this setup. In that if you hit a couple of redirects and you call that method repeatedly, the User-Agent header would not change in value, but per this specification as written it ought to change.

To fix that and some race issues we'd have to grab the current User-Agent header before we go in parallel and use it for the entire duration of the fetch. I'm okay with not doing that for now, but I'm curious what other people think about what level of accuracy we need here. Maybe @jgraham is willing to chime in.

The WebDriver BiDi "WebDriver BiDi emulated User-Agent" hook returns the emulated user context based on pre-configured emulations per top-level navigable, so it is not expected to be changed during navigations or redirects. Even though the JS environments will be changed, it would not influence the return result. BiDi uses the environment only to associate the request with the navigable.

@annevk
Copy link
Member

annevk commented Sep 16, 2025

I see. So you are you saying it's set before navigation starts and can't be changed after?

@sadym-chromium
Copy link
Contributor Author

I see. So you are you saying it's set before navigation starts and can't be changed after?

Theoretically the user can change the emulation during navigation, but otherwise it is persistent per top-level navigable. I cannot imagine a real-world automation scenario when the user needs to change emulation during navigation and expect persistent results.

@jgraham
Copy link
Member

jgraham commented Sep 16, 2025

You can change it in the middle of a fetch, so I think it's true that redirects could see different user agent headers (you could also do the same thing with request interception).

In general I don't think people are expected to change this often for existing traversables; the typical use case is "set the user agent when creating a top-level traversable and use it for the entire lifetime of that traversable".

So I think I agree that in principle caching the value at the start of a redirect loop is the right thing to do, but in practice it's likely to be a rare edge case.

@annevk
Copy link
Member

annevk commented Sep 17, 2025

Since WebDriver interoperability is quite a bit less crucial than web platform interoperability I'll go ahead and merge this. Let's revamp if people end up hitting this in the wild after all.

@annevk annevk merged commit 70908ed into whatwg:main Sep 17, 2025
2 checks passed
@sadym-chromium
Copy link
Contributor Author

Since WebDriver interoperability is quite a bit less crucial than web platform interoperability I'll go ahead and merge this. Let's revamp if people end up hitting this in the wild after all.

Thanks a lot!

@sadym-chromium sadym-chromium deleted the sadym/emulation.setUserAgentOverride branch September 17, 2025 07:23
annevk pushed a commit to whatwg/html that referenced this pull request Sep 17, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

4 participants