Skip to content

Commit

Permalink
feat: add support for useragentdata (#7378)
Browse files Browse the repository at this point in the history
Adds userAgentData to setUserAgent that supports specifying user agent
data for the new navigator.userAgentData and Client Hints headers.
  • Loading branch information
rowan-m committed Jun 29, 2021
1 parent 558b355 commit 7200b1a
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 8 deletions.
36 changes: 32 additions & 4 deletions docs/api.md
Expand Up @@ -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)
Expand Down Expand Up @@ -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()

Expand Down Expand Up @@ -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).
Expand Down Expand Up @@ -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]>
Expand Down
10 changes: 8 additions & 2 deletions src/common/NetworkManager.ts
Expand Up @@ -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> {
Expand Down
11 changes: 9 additions & 2 deletions src/common/Page.ts
Expand Up @@ -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);
}

/**
Expand Down
38 changes: 38 additions & 0 deletions test/page.spec.ts
Expand Up @@ -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 () {
Expand Down
7 changes: 7 additions & 0 deletions utils/doclint/check_public_api/index.js
Expand Up @@ -697,6 +697,13 @@ function compareDocumentations(actual, expected) {
expectedName: 'NetworkConditions',
},
],
[
'Method Page.setUserAgent() userAgentMetadata',
{
actualName: 'Object',
expectedName: 'UserAgentMetadata',
},
],
[
'Method Page.setViewport() options.viewport',
{
Expand Down

1 comment on commit 7200b1a

@fahisfr
Copy link

Choose a reason for hiding this comment

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

fine i do myself

Please sign in to comment.