feat: add support for useragentdata (#7378)

Adds userAgentData to setUserAgent that supports specifying user agent
data for the new navigator.userAgentData and Client Hints headers.
This commit is contained in:
Rowan Merewood 2021-06-29 17:29:55 +01:00 committed by GitHub
parent 558b35567c
commit 7200b1a6fb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 94 additions and 8 deletions

View File

@ -180,7 +180,7 @@
* [page.setJavaScriptEnabled(enabled)](#pagesetjavascriptenabledenabled)
* [page.setOfflineMode(enabled)](#pagesetofflinemodeenabled)
* [page.setRequestInterception(value)](#pagesetrequestinterceptionvalue)
* [page.setUserAgent(userAgent)](#pagesetuseragentuseragent)
* [page.setUserAgent(userAgent[, userAgentMetadata])](#pagesetuseragentuseragent-useragentmetadata)
* [page.setViewport(viewport)](#pagesetviewportviewport)
* [page.tap(selector)](#pagetapselector)
* [page.target()](#pagetarget)
@ -942,7 +942,7 @@ the method will return an array with all the targets in all browser contexts.
- returns: <[Promise]<[string]>> Promise which resolves to the browser's original user agent.
> **NOTE** Pages can override browser user agent with [page.setUserAgent](#pagesetuseragentuseragent)
> **NOTE** Pages can override browser user agent with [page.setUserAgent](#pagesetuseragentuseragent-useragentdata)
#### browser.version()
@ -1558,7 +1558,7 @@ const puppeteer = require('puppeteer');
Emulates given device metrics and user agent. This method is a shortcut for calling two methods:
- [page.setUserAgent(userAgent)](#pagesetuseragentuseragent)
- [page.setUserAgent(userAgent)](#pagesetuseragentuseragent-useragentdata)
- [page.setViewport(viewport)](#pagesetviewportviewport)
To aid emulation, Puppeteer provides a list of device descriptors that can be obtained via the [`puppeteer.devices`](#puppeteerdevices).
@ -2344,11 +2344,39 @@ const puppeteer = require('puppeteer');
})();
```
#### page.setUserAgent(userAgent)
#### page.setUserAgent(userAgent[, userAgentMetadata])
- `userAgent` <[string]> Specific user agent to use in this page
- `userAgentMetadata` <[Object]> Optional user agent data to use in this page. Any
values not provided will use the client's default.
- `brands` <[Array]<[Object]>> Optional brand information
- `brand` <[string]> Browser or client brand name.
- `version` <[string]> Browser or client major version.
- `fullVersion` <[string]> Optional browser or client full version.
- `platform` <[string]> Operating system name.
- `platformVersion` <[string]> Operating system version.
- `architecture` <[string]> CPU architecture.
- `model` <[string]> Device model.
- `mobile` <[boolean]> Indicate if this is a mobile device.
- returns: <[Promise]> Promise which resolves when the user agent is set.
> **NOTE** support for `userAgentMetadata` is experimental in the DevTools
> protocol and more properties will be added.
Providing the optional `userAgentMetadata` header will update the related
entries in `navigator.userAgentData` and associated `Sec-CH-UA`* headers.
```js
const page = await browser.newPage();
await page.setUserAgent('MyBrowser', {
architecture: 'My1',
mobile: false,
model: 'Mybook',
platform: 'MyOS',
platformVersion: '3.1',
});
```
#### page.setViewport(viewport)
- `viewport` <[Object]>

View File

@ -218,8 +218,14 @@ export class NetworkManager extends EventEmitter {
});
}
async setUserAgent(userAgent: string): Promise<void> {
await this._client.send('Network.setUserAgentOverride', { userAgent });
async setUserAgent(
userAgent: string,
userAgentMetadata?: Protocol.Emulation.UserAgentMetadata
): Promise<void> {
await this._client.send('Network.setUserAgentOverride', {
userAgent: userAgent,
userAgentMetadata: userAgentMetadata,
});
}
async setCacheEnabled(enabled: boolean): Promise<void> {

View File

@ -1383,10 +1383,17 @@ export class Page extends EventEmitter {
/**
* @param userAgent - Specific user agent to use in this page
* @param userAgentData - Specific user agent client hint data to use in this
* page
* @returns Promise which resolves when the user agent is set.
*/
async setUserAgent(userAgent: string): Promise<void> {
return this._frameManager.networkManager().setUserAgent(userAgent);
async setUserAgent(
userAgent: string,
userAgentMetadata?: Protocol.Emulation.UserAgentMetadata
): Promise<void> {
return this._frameManager
.networkManager()
.setUserAgent(userAgent, userAgentMetadata);
}
/**

View File

@ -998,6 +998,44 @@ describe('Page', function () {
'iPhone'
);
});
itFailsFirefox('should work with additional userAgentMetdata', async () => {
const { page, server } = getTestState();
await page.setUserAgent('MockBrowser', {
architecture: 'Mock1',
mobile: false,
model: 'Mockbook',
platform: 'MockOS',
platformVersion: '3.1',
});
const [request] = await Promise.all([
server.waitForRequest('/empty.html'),
page.goto(server.EMPTY_PAGE),
]);
expect(
await page.evaluate(() => {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: userAgentData not yet in TypeScript DOM API
return navigator.userAgentData.mobile;
})
).toBe(false);
const uaData = await page.evaluate(() => {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: userAgentData not yet in TypeScript DOM API
return navigator.userAgentData.getHighEntropyValues([
'architecture',
'model',
'platform',
'platformVersion',
]);
});
expect(uaData['architecture']).toBe('Mock1');
expect(uaData['model']).toBe('Mockbook');
expect(uaData['platform']).toBe('MockOS');
expect(uaData['platformVersion']).toBe('3.1');
expect(request.headers['user-agent']).toBe('MockBrowser');
});
});
describe('Page.setContent', function () {

View File

@ -697,6 +697,13 @@ function compareDocumentations(actual, expected) {
expectedName: 'NetworkConditions',
},
],
[
'Method Page.setUserAgent() userAgentMetadata',
{
actualName: 'Object',
expectedName: 'UserAgentMetadata',
},
],
[
'Method Page.setViewport() options.viewport',
{