Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 47 additions & 42 deletions docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,14 +53,16 @@
* [event: 'targetcreated'](#event-targetcreated-1)
* [event: 'targetdestroyed'](#event-targetdestroyed-1)
* [browserContext.browser()](#browsercontextbrowser)
* [browserContext.clearPermissionOverrides()](#browsercontextclearpermissionoverrides)
* [browserContext.close()](#browsercontextclose)
* [browserContext.isIncognito()](#browsercontextisincognito)
* [browserContext.newPage()](#browsercontextnewpage)
* [browserContext.overridePermissions(origin, permissions)](#browsercontextoverridepermissionsorigin-permissions)
* [browserContext.pages()](#browsercontextpages)
* [browserContext.permissions](#browsercontextpermissions)
* [browserContext.targets()](#browsercontexttargets)
* [browserContext.waitForTarget(predicate[, options])](#browsercontextwaitfortargetpredicate-options)
- [class: Permissions](#class-permissions)
* [permissions.clearOverrides()](#permissionsclearoverrides)
* [permissions.override(origin, permissions)](#permissionsoverrideorigin-permissions)
- [class: Page](#class-page)
* [event: 'close'](#event-close)
* [event: 'console'](#event-console)
Expand Down Expand Up @@ -832,18 +834,6 @@ Emitted when a target inside the browser context is destroyed, for example when

The browser this browser context belongs to.

#### browserContext.clearPermissionOverrides()
- returns: <[Promise]>

Clears all permission overrides for the browser context.

```js
const context = browser.defaultBrowserContext();
context.overridePermissions('https://example.com', ['clipboard-read']);
// do stuff ..
context.clearPermissionOverrides();
```

#### browserContext.close()
- returns: <[Promise]>

Expand All @@ -865,8 +855,48 @@ The default browser context is the only non-incognito browser context.

Creates a new page in the browser context.

#### browserContext.pages()
- returns: <[Promise]<[Array]<[Page]>>> Promise which resolves to an array of all open pages. Non visible pages, such as `"background_page"`, will not be listed here. You can find them using [target.page()](#targetpage).

An array of all pages inside the browser context.

#### browserContext.permissions
- returns: <[Permissions]>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Should this and other feature accessors be returns: <?[Permissions]> ?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

That's a good point, I'll apply it to everything in a separate patch.


#### browserContext.targets()

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I thought you were going to drop targets from the API, is there a reason we must keep them? For testing/automation use cases where the browser is fully controlled by a program we shouldn't need this as the program should already be aware of all targets.

Oh, on the second look it seems that this place didn't actually change and it's just a misleading diff representation, so we can discuss this separately.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Yup. Will remove later...

- returns: <[Array]<[Target]>>

An array of all active targets inside the browser context.

#### browserContext.waitForTarget(predicate[, options])
- `predicate` <[function]\([Target]\):[boolean]> A function to be run for every target
- `options` <[Object]>
- `timeout` <[number]> Maximum wait time in milliseconds. Pass `0` to disable the timeout. Defaults to 30 seconds.
- returns: <[Promise]<[Target]>> Promise which resolves to the first target found that matches the `predicate` function.

This searches for a target in this specific browser context.

An example of finding a target for a page opened via `window.open`:
```js
await page.evaluate(() => window.open('https://www.example.com/'));
const newWindowTarget = await browserContext.waitForTarget(target => target.url() === 'https://www.example.com/');
```

### class: Permissions

#### browserContext.overridePermissions(origin, permissions)
#### permissions.clearOverrides()
- returns: <[Promise]>

Clears all permission overrides for the browser context.

```js
const context = browser.defaultBrowserContext();
context.permissions.override('https://example.com', ['clipboard-read']);
// do stuff ..
context.permissions.clearOverrides();
```

#### permissions.override(origin, permissions)
- `origin` <[string]> The [origin] to grant permissions to, e.g. "https://example.com".
- `permissions` <[Array]<[string]>> An array of permissions to grant. All permissions that are not listed here will be automatically denied. Permissions can be one of the following values:
- `'geolocation'`
Expand All @@ -890,32 +920,7 @@ Creates a new page in the browser context.

```js
const context = browser.defaultBrowserContext();
await context.overridePermissions('https://html5demos.com', ['geolocation']);
```


#### browserContext.pages()
- returns: <[Promise]<[Array]<[Page]>>> Promise which resolves to an array of all open pages. Non visible pages, such as `"background_page"`, will not be listed here. You can find them using [target.page()](#targetpage).

An array of all pages inside the browser context.

#### browserContext.targets()
- returns: <[Array]<[Target]>>

An array of all active targets inside the browser context.

#### browserContext.waitForTarget(predicate[, options])
- `predicate` <[function]\([Target]\):[boolean]> A function to be run for every target
- `options` <[Object]>
- `timeout` <[number]> Maximum wait time in milliseconds. Pass `0` to disable the timeout. Defaults to 30 seconds.
- returns: <[Promise]<[Target]>> Promise which resolves to the first target found that matches the `predicate` function.

This searches for a target in this specific browser context.

An example of finding a target for a page opened via `window.open`:
```js
await page.evaluate(() => window.open('https://www.example.com/'));
const newWindowTarget = await browserContext.waitForTarget(target => target.url() === 'https://www.example.com/');
await context.permissions.override('https://html5demos.com', ['geolocation']);
```

### class: Page
Expand Down Expand Up @@ -1814,7 +1819,7 @@ Sets the page's geolocation.
await page.setGeolocation({latitude: 59.95, longitude: 30.31667});
```

> **NOTE** Consider using [browserContext.overridePermissions](#browsercontextoverridepermissionsorigin-permissions) to grant permissions for the page to read its geolocation.
> **NOTE** Consider using [browserContext.permissions.override](#permissionsoverrideorigin-permissions) to grant permissions for the page to read its geolocation.

#### page.setJavaScriptEnabled(enabled)
- `enabled` <[boolean]> Whether or not to enable JavaScript on the page.
Expand Down
4 changes: 3 additions & 1 deletion src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export = {
Mouse: require('./chromium/Input').Mouse,
PDF: require('./chromium/features/pdf').PDF,
Page: require('./chromium/Page').Page,
Permissions: require('./chromium/features/permissions').Permissions,
Playwright: require('./chromium/Playwright').Playwright,
Request: require('./chromium/NetworkManager').Request,
Response: require('./chromium/NetworkManager').Response,
Expand All @@ -45,7 +46,7 @@ export = {
Workers: require('./chromium/features/workers').Workers,
},
Firefox: {
Accessibility: require('./firefox/Accessibility').Accessibility,
Accessibility: require('./firefox/features/accessibility').Accessibility,
Browser: require('./firefox/Browser').Browser,
BrowserContext: require('./firefox/Browser').BrowserContext,
BrowserFetcher: require('./firefox/BrowserFetcher').BrowserFetcher,
Expand All @@ -60,6 +61,7 @@ export = {
Keyboard: require('./firefox/Input').Keyboard,
Mouse: require('./firefox/Input').Mouse,
Page: require('./firefox/Page').Page,
Permissions: require('./firefox/features/permissions').Permissions,
Playwright: require('./firefox/Playwright').Playwright,
Request: require('./firefox/NetworkManager').Request,
Response: require('./firefox/NetworkManager').Response,
Expand Down
39 changes: 4 additions & 35 deletions src/chromium/BrowserContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,21 @@ import { EventEmitter } from 'events';
import { assert } from '../helper';
import { Browser } from './Browser';
import { Connection } from './Connection';
import { Permissions } from './features/permissions';
import { Page } from './Page';
import { Target } from './Target';
import { Protocol } from './protocol';

export class BrowserContext extends EventEmitter {
private _connection: Connection;
readonly permissions: Permissions;

private _browser: Browser;
private _id: string;

constructor(connection: Connection, browser: Browser, contextId: string | null) {
super();
this._connection = connection;
this._browser = browser;
this._id = contextId;
this.permissions = new Permissions(connection, contextId);
}

targets(): Target[] {
Expand All @@ -56,38 +57,6 @@ export class BrowserContext extends EventEmitter {
return !!this._id;
}

async overridePermissions(origin: string, permissions: string[]) {
const webPermissionToProtocol = new Map<string, Protocol.Browser.PermissionType>([
['geolocation', 'geolocation'],
['midi', 'midi'],
['notifications', 'notifications'],
['camera', 'videoCapture'],
['microphone', 'audioCapture'],
['background-sync', 'backgroundSync'],
['ambient-light-sensor', 'sensors'],
['accelerometer', 'sensors'],
['gyroscope', 'sensors'],
['magnetometer', 'sensors'],
['accessibility-events', 'accessibilityEvents'],
['clipboard-read', 'clipboardRead'],
['clipboard-write', 'clipboardWrite'],
['payment-handler', 'paymentHandler'],
// chrome-specific permissions we have.
['midi-sysex', 'midiSysex'],
]);
const filtered = permissions.map(permission => {
const protocolPermission = webPermissionToProtocol.get(permission);
if (!protocolPermission)
throw new Error('Unknown permission: ' + permission);
return protocolPermission;
});
await this._connection.send('Browser.grantPermissions', {origin, browserContextId: this._id || undefined, permissions: filtered});
}

async clearPermissionOverrides() {
await this._connection.send('Browser.resetPermissions', {browserContextId: this._id || undefined});
}

newPage(): Promise<Page> {
return this._browser._createPageInContext(this._id);
}
Expand Down
61 changes: 61 additions & 0 deletions src/chromium/features/permissions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/**
* Copyright 2017 Google Inc. All rights reserved.
* Modifications copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import { Protocol } from '../protocol';
import { Connection } from './../Connection';

export class Permissions {
private _client: Connection;
private _browserContextId: string;

constructor(connection: Connection, browserContextId: string | null) {
this._client = connection;
this._browserContextId = browserContextId;
}

async override(origin: string, permissions: string[]) {
const webPermissionToProtocol = new Map<string, Protocol.Browser.PermissionType>([
['geolocation', 'geolocation'],
['midi', 'midi'],
['notifications', 'notifications'],
['camera', 'videoCapture'],
['microphone', 'audioCapture'],
['background-sync', 'backgroundSync'],
['ambient-light-sensor', 'sensors'],
['accelerometer', 'sensors'],
['gyroscope', 'sensors'],
['magnetometer', 'sensors'],
['accessibility-events', 'accessibilityEvents'],
['clipboard-read', 'clipboardRead'],
['clipboard-write', 'clipboardWrite'],
['payment-handler', 'paymentHandler'],
// chrome-specific permissions we have.
['midi-sysex', 'midiSysex'],
]);
const filtered = permissions.map(permission => {
const protocolPermission = webPermissionToProtocol.get(permission);
if (!protocolPermission)
throw new Error('Unknown permission: ' + permission);
return protocolPermission;
});
await this._client.send('Browser.grantPermissions', {origin, browserContextId: this._browserContextId || undefined, permissions: filtered});
}

async clearOverrides() {
await this._client.send('Browser.resetPermissions', {browserContextId: this._browserContextId || undefined});
}
}
35 changes: 8 additions & 27 deletions src/firefox/Browser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,12 @@
* limitations under the License.
*/

import {RegisteredListener, helper, assert} from '../helper';
import {Page, Viewport} from './Page';
import {EventEmitter} from 'events';
import {Connection, ConnectionEvents} from './Connection';
import {Events} from '../Events';
import { EventEmitter } from 'events';
import { Events } from '../Events';
import { assert, helper, RegisteredListener } from '../helper';
import { Connection, ConnectionEvents } from './Connection';
import { Permissions } from './features/permissions';
import { Page, Viewport } from './Page';

export class Browser extends EventEmitter {
private _connection: Connection;
Expand Down Expand Up @@ -262,36 +263,16 @@ export class BrowserContext extends EventEmitter {
_connection: Connection;
_browser: Browser;
_browserContextId: string;
readonly permissions: Permissions;

constructor(connection: Connection, browser: Browser, browserContextId: string | null) {
super();
this._connection = connection;
this._browser = browser;
this._browserContextId = browserContextId;
this.permissions = new Permissions(connection, browserContextId);
}


async overridePermissions(origin: string, permissions: Array<string>) {
const webPermissionToProtocol = new Map([
['geolocation', 'geo'],
['microphone', 'microphone'],
['camera', 'camera'],
['notifications', 'desktop-notifications'],
]);
permissions = permissions.map(permission => {
const protocolPermission = webPermissionToProtocol.get(permission);
if (!protocolPermission)
throw new Error('Unknown permission: ' + permission);
return protocolPermission;
});
await this._connection.send('Browser.grantPermissions', {origin, browserContextId: this._browserContextId || undefined, permissions});
}

async clearPermissionOverrides() {
await this._connection.send('Browser.resetPermissions', {browserContextId: this._browserContextId || undefined});
}


targets(): Array<Target> {
return this._browser.targets().filter(target => target.browserContext() === this);
}
Expand Down
10 changes: 3 additions & 7 deletions src/firefox/Page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {FrameManager, normalizeWaitUntil, FrameManagerEvents} from './FrameManag
import {NetworkManager, Request, Response, NetworkManagerEvents} from './NetworkManager';
import {TimeoutSettings} from '../TimeoutSettings';
import {NavigationWatchdog} from './NavigationWatchdog';
import {Accessibility} from './Accessibility';
import {Accessibility} from './features/accessibility';
import { Target, BrowserContext } from './Browser';
import { Events } from '../Events';

Expand All @@ -26,7 +26,7 @@ export class Page extends EventEmitter {
private _keyboard: Keyboard;
private _mouse: Mouse;
private _touchscreen: Touchscreen;
private _accessibility: Accessibility;
readonly accessibility: Accessibility;
private _closed: boolean;
private _pageBindings: Map<string, Function>;
private _networkManager: NetworkManager;
Expand Down Expand Up @@ -56,7 +56,7 @@ export class Page extends EventEmitter {
this._keyboard = new Keyboard(session);
this._mouse = new Mouse(session, this._keyboard);
this._touchscreen = new Touchscreen(session, this._keyboard, this._mouse);
this._accessibility = new Accessibility(session);
this.accessibility = new Accessibility(session);
this._closed = false;
this._pageBindings = new Map();
this._networkManager = new NetworkManager(session);
Expand Down Expand Up @@ -334,10 +334,6 @@ export class Page extends EventEmitter {
return this._frameManager.mainFrame();
}

get accessibility() {
return this._accessibility;
}

get keyboard(){
return this._keyboard;
}
Expand Down
Loading