chore(bidi): implement permissions API (#35662)

Limitations due to current Bidi protocol:

- Cannot revert to the browser default permission (before override). So when the client calls clearPermissions
 we always set the permission to `prompt` which is not necessarily what the browser had before the override.
- `*` pattern is not supported. Most clients don't want to do fine grained permission control in their tests.
This commit is contained in:
Yury Semikhatsky 2025-04-17 13:00:45 -07:00 committed by GitHub
parent 3032513e92
commit 303901d7a5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 2547 additions and 2462 deletions

View File

@ -205,6 +205,7 @@ export class BidiBrowser extends Browser {
export class BidiBrowserContext extends BrowserContext {
declare readonly _browser: BidiBrowser;
private _initScriptIds: bidi.Script.PreloadScript[] = [];
private _originToPermissions = new Map<string, string[]>();
constructor(browser: BidiBrowser, browserContextId: string | undefined, options: types.BrowserContextOptions) {
super(browser, options, browserContextId);
@ -308,9 +309,28 @@ export class BidiBrowserContext extends BrowserContext {
}
async doGrantPermissions(origin: string, permissions: string[]) {
const currentPermissions = this._originToPermissions.get(origin) || [];
const toGrant = permissions.filter(permission => !currentPermissions.includes(permission));
this._originToPermissions.set(origin, [...currentPermissions, ...toGrant]);
await Promise.all(toGrant.map(permission => this._setPermission(origin, permission, bidi.Permissions.PermissionState.Granted)));
}
async doClearPermissions() {
const currentPermissions = [...this._originToPermissions.entries()];
this._originToPermissions = new Map();
await Promise.all(currentPermissions.map(([origin, permissions]) => permissions.map(
p => this._setPermission(origin, p, bidi.Permissions.PermissionState.Prompt))));
}
private async _setPermission(origin: string, permission: string, state: bidi.Permissions.PermissionState) {
await this._browser._browserSession.send('permissions.setPermission', {
descriptor: {
name: permission,
},
state,
origin,
userContext: this._browserContextId || 'default',
});
}
async setGeolocation(geolocation?: types.Geolocation): Promise<void> {

View File

@ -7,7 +7,7 @@
// Copied from upstream: https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/bidi/core/Connection.ts
import * as Bidi from './bidiProtocol';
import type * as Bidi from './bidiProtocol';
export interface Commands {
'script.evaluate': {
@ -118,6 +118,11 @@ export interface Commands {
returnType: Bidi.EmptyResult;
};
'permissions.setPermission': {
params: Bidi.Permissions.SetPermissionParameters;
returnType: Bidi.EmptyResult;
};
'session.end': {
params: Bidi.EmptyParams;
returnType: Bidi.EmptyResult;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,42 @@
/**
* @license
* Copyright 2024 Google Inc.
* Modifications copyright (c) Microsoft Corporation.
* SPDX-License-Identifier: Apache-2.0
*/
// Copied from upstream: https://github.com/GoogleChromeLabs/chromium-bidi/blob/main/src/protocol/generated/webdriver-bidi-permissions.ts
/**
* THIS FILE IS AUTOGENERATED by cddlconv 0.1.6.
* Run `node tools/generate-bidi-types.mjs` to regenerate.
* @see https://github.com/w3c/webdriver-bidi/blob/master/index.bs
*/
export type PermissionsCommand = Permissions.SetPermission;
export namespace Permissions {
export type PermissionDescriptor = {
name: string;
};
}
export namespace Permissions {
export const enum PermissionState {
Granted = 'granted',
Denied = 'denied',
Prompt = 'prompt',
}
}
export namespace Permissions {
export type SetPermission = {
method: 'permissions.setPermission';
params: Permissions.SetPermissionParameters;
};
}
export namespace Permissions {
export type SetPermissionParameters = {
descriptor: Permissions.PermissionDescriptor;
state: Permissions.PermissionState;
origin: string;
userContext?: string;
};
}