fix(permissions): manage permissions on the proxy level in webkit (#1451)
This commit is contained in:
Родитель
96c9c81581
Коммит
5a42cbd491
|
@ -10,7 +10,7 @@
|
||||||
"playwright": {
|
"playwright": {
|
||||||
"chromium_revision": "751710",
|
"chromium_revision": "751710",
|
||||||
"firefox_revision": "1045",
|
"firefox_revision": "1045",
|
||||||
"webkit_revision": "1180"
|
"webkit_revision": "1182"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"ctest": "cross-env BROWSER=chromium node test/test.js",
|
"ctest": "cross-env BROWSER=chromium node test/test.js",
|
||||||
|
|
|
@ -70,7 +70,7 @@ export abstract class BrowserContextBase extends platform.EventEmitter implement
|
||||||
_closed = false;
|
_closed = false;
|
||||||
private readonly _closePromise: Promise<Error>;
|
private readonly _closePromise: Promise<Error>;
|
||||||
private _closePromiseFulfill: ((error: Error) => void) | undefined;
|
private _closePromiseFulfill: ((error: Error) => void) | undefined;
|
||||||
private _permissions = new Map<string, string[]>();
|
readonly _permissions = new Map<string, string[]>();
|
||||||
|
|
||||||
constructor(options: BrowserContextOptions) {
|
constructor(options: BrowserContextOptions) {
|
||||||
super();
|
super();
|
||||||
|
|
|
@ -263,20 +263,11 @@ export class WKBrowserContext extends BrowserContextBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
async _doGrantPermissions(origin: string, permissions: string[]) {
|
async _doGrantPermissions(origin: string, permissions: string[]) {
|
||||||
const webPermissionToProtocol = new Map<string, string>([
|
await Promise.all(this.pages().map(page => (page._delegate as WKPage)._grantPermissions(origin, permissions)));
|
||||||
['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 });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async _doClearPermissions() {
|
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> {
|
async setGeolocation(geolocation: types.Geolocation | null): Promise<void> {
|
||||||
|
|
|
@ -98,6 +98,10 @@ export class WKPage implements PageDelegate {
|
||||||
if (this._page._state.viewportSize || contextOptions.viewport)
|
if (this._page._state.viewportSize || contextOptions.viewport)
|
||||||
promises.push(this._updateViewport());
|
promises.push(this._updateViewport());
|
||||||
promises.push(this.updateHttpCredentials());
|
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);
|
await Promise.all(promises);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -820,6 +824,23 @@ export class WKPage implements PageDelegate {
|
||||||
request.request._setFailureText(event.errorText);
|
request.request._setFailureText(event.errorText);
|
||||||
this._page._frameManager.requestFailed(request.request, event.errorText.includes('cancelled'));
|
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 {
|
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=20 lng=30');
|
||||||
expect(allMessages).toContain('lat=40 lng=50');
|
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 });
|
||||||
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
Загрузка…
Ссылка в новой задаче