fix(permissions): manage permissions on the proxy level in webkit (#1451)

This commit is contained in:
Pavel Feldman 2020-03-20 19:45:35 -07:00 коммит произвёл GitHub
Родитель 96c9c81581
Коммит 5a42cbd491
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
6 изменённых файлов: 42 добавлений и 13 удалений

Просмотреть файл

@ -10,7 +10,7 @@
"playwright": {
"chromium_revision": "751710",
"firefox_revision": "1045",
"webkit_revision": "1180"
"webkit_revision": "1182"
},
"scripts": {
"ctest": "cross-env BROWSER=chromium node test/test.js",

Просмотреть файл

@ -70,7 +70,7 @@ export abstract class BrowserContextBase extends platform.EventEmitter implement
_closed = false;
private readonly _closePromise: Promise<Error>;
private _closePromiseFulfill: ((error: Error) => void) | undefined;
private _permissions = new Map<string, string[]>();
readonly _permissions = new Map<string, string[]>();
constructor(options: BrowserContextOptions) {
super();

Просмотреть файл

@ -263,20 +263,11 @@ export class WKBrowserContext extends BrowserContextBase {
}
async _doGrantPermissions(origin: string, permissions: string[]) {
const webPermissionToProtocol = new Map<string, string>([
['geolocation', 'geolocation'],
]);
const filtered = permissions.map(permission => {
const protocolPermission = webPermissionToProtocol.get(permission);
if (!protocolPermission)
throw new Error('Unknown permission: ' + permission);
return protocolPermission;
});
await this._browser._browserSession.send('Playwright.grantPermissions', { origin, browserContextId: this._browserContextId, permissions: filtered });
await Promise.all(this.pages().map(page => (page._delegate as WKPage)._grantPermissions(origin, permissions)));
}
async _doClearPermissions() {
await this._browser._browserSession.send('Playwright.resetPermissions', { browserContextId: this._browserContextId });
await Promise.all(this.pages().map(page => (page._delegate as WKPage)._clearPermissions()));
}
async setGeolocation(geolocation: types.Geolocation | null): Promise<void> {

Просмотреть файл

@ -98,6 +98,10 @@ export class WKPage implements PageDelegate {
if (this._page._state.viewportSize || contextOptions.viewport)
promises.push(this._updateViewport());
promises.push(this.updateHttpCredentials());
if (this._browserContext._permissions.size) {
for (const [key, value] of this._browserContext._permissions)
this._grantPermissions(key, value);
}
await Promise.all(promises);
}
@ -820,6 +824,23 @@ export class WKPage implements PageDelegate {
request.request._setFailureText(event.errorText);
this._page._frameManager.requestFailed(request.request, event.errorText.includes('cancelled'));
}
async _grantPermissions(origin: string, permissions: string[]) {
const webPermissionToProtocol = new Map<string, string>([
['geolocation', 'geolocation'],
]);
const filtered = permissions.map(permission => {
const protocolPermission = webPermissionToProtocol.get(permission);
if (!protocolPermission)
throw new Error('Unknown permission: ' + permission);
return protocolPermission;
});
await this._pageProxySession.send('Emulation.grantPermissions', { origin, permissions: filtered });
}
async _clearPermissions() {
await this._pageProxySession.send('Emulation.resetPermissions', {});
}
}
function toRemoteObject(handle: dom.ElementHandle): Protocol.Runtime.RemoteObject {

Просмотреть файл

@ -0,0 +1,7 @@
<script>
window.geolocationPromise = new Promise(resolve => {
navigator.geolocation.getCurrentPosition(position => {
resolve({latitude: position.coords.latitude, longitude: position.coords.longitude});
});
});
</script>

Просмотреть файл

@ -112,5 +112,15 @@ module.exports.describe = function ({ testRunner, expect, FFOX, WEBKIT }) {
expect(allMessages).toContain('lat=20 lng=30');
expect(allMessages).toContain('lat=40 lng=50');
});
it.fail(FFOX)('should use context options for popup', async({page, context, server}) => {
await context.grantPermissions(['geolocation']);
await context.setGeolocation({ longitude: 10, latitude: 10 });
const [popup] = await Promise.all([
page.waitForEvent('popup'),
page.evaluate(url => window._popup = window.open(url), server.PREFIX + '/geolocation.html'),
]);
const geolocation = await popup.evaluate(() => window.geolocationPromise);
expect(geolocation).toEqual({ longitude: 10, latitude: 10 });
});
});
};