Skip to content

Commit

Permalink
feat: implement permissions for WebDriver BiDi (#11979)
Browse files Browse the repository at this point in the history
  • Loading branch information
OrKoN committed Feb 23, 2024
1 parent bba2811 commit 3a467c3
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 34 deletions.
10 changes: 5 additions & 5 deletions docs/webdriver-bidi.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,11 @@ This is an exciting step towards a more unified and efficient cross-browser auto
- Page.pdf (only `format`, `height`, `landscape`, `margin`, `pageRanges`, `printBackground`, `scale`, `width` are supported)
- Page.createPDFStream (only `format`, `height`, `landscape`, `margin`, `pageRanges`, `printBackground`, `scale`, `width` are supported)

- Permissions (Supported in Chrome only)

- BrowserContext.clearPermissionOverrides()
- BrowserContext.overridePermissions()

## Puppeteer features not yet supported over WebDriver BiDi

- [Request interception](https://pptr.dev/guides/request-interception)
Expand All @@ -111,11 +116,6 @@ This is an exciting step towards a more unified and efficient cross-browser auto
- HTTPRequest.responseForRequest()
- Page.setRequestInterception()

- Permissions

- BrowserContext.clearPermissionOverrides()
- BrowserContext.overridePermissions()

- Various emulations (most are supported with Chrome)

- Page.emulate() (supported only in Chrome)
Expand Down
59 changes: 54 additions & 5 deletions packages/puppeteer-core/src/bidi/BrowserContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@

import * as Bidi from 'chromium-bidi/lib/cjs/protocol/protocol.js';

import type {Permission} from '../api/Browser.js';
import {WEB_PERMISSION_TO_PROTOCOL_PERMISSION} from '../api/Browser.js';
import type {BrowserContextEvents} from '../api/BrowserContext.js';
import {BrowserContext, BrowserContextEvent} from '../api/BrowserContext.js';
import {PageEvent, type Page} from '../api/Page.js';
import type {Target} from '../api/Target.js';
import {UnsupportedOperation} from '../common/Errors.js';
import {EventEmitter} from '../common/EventEmitter.js';
import {debugError} from '../common/util.js';
import type {Viewport} from '../common/Viewport.js';
Expand Down Expand Up @@ -62,6 +63,8 @@ export class BidiBrowserContext extends BrowserContext {
]
>();

#overrides: Array<{origin: string; permission: Permission}> = [];

private constructor(
browser: BidiBrowser,
userContext: UserContext,
Expand Down Expand Up @@ -202,12 +205,58 @@ export class BidiBrowserContext extends BrowserContext {
return this.userContext.id !== UserContext.DEFAULT;
}

override overridePermissions(): never {
throw new UnsupportedOperation();
override async overridePermissions(
origin: string,
permissions: Permission[]
): Promise<void> {
const permissionsSet = new Set(
permissions.map(permission => {
const protocolPermission =
WEB_PERMISSION_TO_PROTOCOL_PERMISSION.get(permission);
if (!protocolPermission) {
throw new Error('Unknown permission: ' + permission);
}
return permission;
})
);
await Promise.all(
Array.from(WEB_PERMISSION_TO_PROTOCOL_PERMISSION.keys()).map(
permission => {
const result = this.userContext.setPermissions(
origin,
{
name: permission,
},
permissionsSet.has(permission)
? Bidi.Permissions.PermissionState.Granted
: Bidi.Permissions.PermissionState.Denied
);
this.#overrides.push({origin, permission});
// TODO: some permissions are outdated and setting them to denied does
// not work.
if (!permissionsSet.has(permission)) {
return result.catch(debugError);
}
return result;
}
)
);
}

override clearPermissionOverrides(): never {
throw new UnsupportedOperation();
override async clearPermissionOverrides(): Promise<void> {
const promises = this.#overrides.map(({permission, origin}) => {
return this.userContext
.setPermissions(
origin,
{
name: permission,
},
Bidi.Permissions.PermissionState.Prompt
)
.catch(debugError);
});
this.#overrides = [];
await Promise.all(promises);
}

override get id(): string | undefined {
Expand Down
5 changes: 5 additions & 0 deletions packages/puppeteer-core/src/bidi/core/Connection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,11 @@ export interface Commands {
returnType: Bidi.EmptyResult;
};

'permissions.setPermission': {
params: Bidi.Permissions.SetPermissionParameters;
returnType: Bidi.EmptyResult;
};

'session.end': {
params: Bidi.EmptyParams;
returnType: Bidi.EmptyResult;
Expand Down
18 changes: 18 additions & 0 deletions packages/puppeteer-core/src/bidi/core/UserContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,24 @@ export class UserContext extends EventEmitter<{
});
}

@throwIfDisposed<UserContext>(context => {
// SAFETY: Disposal implies this exists.
return context.#reason!;
})
async setPermissions(
origin: string,
descriptor: Bidi.Permissions.PermissionDescriptor,
state: Bidi.Permissions.PermissionState
): Promise<void> {
await this.#session.send('permissions.setPermission', {
origin,
descriptor,
state,
// @ts-expect-error not standard implementation.
'goog:userContext': this.#id,
});
}

[disposeSymbol](): void {
this.#reason ??=
'User context already closed, probably because the browser disconnected/closed.';
Expand Down
36 changes: 12 additions & 24 deletions test/TestExpectations.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,6 @@
"parameters": ["webDriverBiDi"],
"expectations": ["SKIP"]
},
{
"testIdPattern": "[browsercontext.spec] BrowserContext BrowserContext.overridePermissions *",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["webDriverBiDi"],
"expectations": ["FAIL"]
},
{
"testIdPattern": "[device-request-prompt.spec] *",
"platforms": ["darwin", "linux", "win32"],
Expand Down Expand Up @@ -233,12 +227,6 @@
"parameters": ["firefox", "webDriverBiDi"],
"expectations": ["FAIL"]
},
{
"testIdPattern": "[browsercontext.spec] BrowserContext BrowserContext.overridePermissions *",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["chrome", "webDriverBiDi"],
"expectations": ["FAIL"]
},
{
"testIdPattern": "[browsercontext.spec] BrowserContext BrowserContext.overridePermissions should be prompt by default",
"platforms": ["darwin", "linux", "win32"],
Expand Down Expand Up @@ -704,12 +692,6 @@
"parameters": ["webDriverBiDi"],
"expectations": ["FAIL"]
},
{
"testIdPattern": "[page.spec] Page Page.setGeolocation should work",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["webDriverBiDi"],
"expectations": ["FAIL"]
},
{
"testIdPattern": "[page.spec] Page Page.setOfflineMode should emulate navigator.onLine",
"platforms": ["darwin", "linux", "win32"],
Expand Down Expand Up @@ -922,6 +904,12 @@
"parameters": ["cdp", "firefox"],
"expectations": ["FAIL"]
},
{
"testIdPattern": "[browsercontext.spec] BrowserContext BrowserContext.overridePermissions should fail when bad permission is given",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["firefox", "webDriverBiDi"],
"expectations": ["PASS"]
},
{
"testIdPattern": "[browsercontext.spec] BrowserContext BrowserContext.overridePermissions should grant permission when listed",
"platforms": ["darwin", "linux", "win32"],
Expand Down Expand Up @@ -1572,12 +1560,6 @@
"parameters": ["cdp", "firefox"],
"expectations": ["SKIP"]
},
{
"testIdPattern": "[idle_override.spec] Emulate idle state changing idle state emulation causes change of the IdleDetector state",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["chrome", "webDriverBiDi"],
"expectations": ["FAIL"]
},
{
"testIdPattern": "[ignorehttpserrors.spec] ignoreHTTPSErrors Response.securityDetails Network redirects should report SecurityDetails",
"platforms": ["darwin", "linux", "win32"],
Expand Down Expand Up @@ -2937,6 +2919,12 @@
"parameters": ["cdp", "firefox"],
"expectations": ["FAIL"]
},
{
"testIdPattern": "[page.spec] Page Page.setGeolocation should work",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["firefox", "webDriverBiDi"],
"expectations": ["FAIL"]
},
{
"testIdPattern": "[page.spec] Page Page.setGeolocation should work",
"platforms": ["darwin", "linux", "win32"],
Expand Down

0 comments on commit 3a467c3

Please sign in to comment.