From 5a42cbd49116af70b5818241fb12b4b40bbc4005 Mon Sep 17 00:00:00 2001 From: Pavel Feldman Date: Fri, 20 Mar 2020 19:45:35 -0700 Subject: [PATCH] fix(permissions): manage permissions on the proxy level in webkit (#1451) --- package.json | 2 +- src/browserContext.ts | 2 +- src/webkit/wkBrowser.ts | 13 ++----------- src/webkit/wkPage.ts | 21 +++++++++++++++++++++ test/assets/geolocation.html | 7 +++++++ test/geolocation.spec.js | 10 ++++++++++ 6 files changed, 42 insertions(+), 13 deletions(-) create mode 100644 test/assets/geolocation.html diff --git a/package.json b/package.json index 769ac69bcc..64e44ac5a7 100644 --- a/package.json +++ b/package.json @@ -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", diff --git a/src/browserContext.ts b/src/browserContext.ts index 39ba1da672..568cd179fc 100644 --- a/src/browserContext.ts +++ b/src/browserContext.ts @@ -70,7 +70,7 @@ export abstract class BrowserContextBase extends platform.EventEmitter implement _closed = false; private readonly _closePromise: Promise; private _closePromiseFulfill: ((error: Error) => void) | undefined; - private _permissions = new Map(); + readonly _permissions = new Map(); constructor(options: BrowserContextOptions) { super(); diff --git a/src/webkit/wkBrowser.ts b/src/webkit/wkBrowser.ts index c46240097f..48c864053a 100644 --- a/src/webkit/wkBrowser.ts +++ b/src/webkit/wkBrowser.ts @@ -263,20 +263,11 @@ export class WKBrowserContext extends BrowserContextBase { } async _doGrantPermissions(origin: string, permissions: string[]) { - const webPermissionToProtocol = new Map([ - ['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 { diff --git a/src/webkit/wkPage.ts b/src/webkit/wkPage.ts index 045ab33bbf..fbe5924fbb 100644 --- a/src/webkit/wkPage.ts +++ b/src/webkit/wkPage.ts @@ -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([ + ['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 { diff --git a/test/assets/geolocation.html b/test/assets/geolocation.html new file mode 100644 index 0000000000..3d44c3f7f5 --- /dev/null +++ b/test/assets/geolocation.html @@ -0,0 +1,7 @@ + diff --git a/test/geolocation.spec.js b/test/geolocation.spec.js index 45ff04746f..0e6f2b0ba2 100644 --- a/test/geolocation.spec.js +++ b/test/geolocation.spec.js @@ -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 }); + }); }); };