diff --git a/docs/src/api/class-browsercontext.md b/docs/src/api/class-browsercontext.md index f9ab6694c3..3ea2180873 100644 --- a/docs/src/api/class-browsercontext.md +++ b/docs/src/api/class-browsercontext.md @@ -1044,21 +1044,22 @@ specified. - `permissions` <[Array]<[string]>> A permission or an array of permissions to grant. Permissions can be one of the following values: -* `'geolocation'` -* `'midi'` -* `'midi-sysex'` (system-exclusive midi) -* `'notifications'` -* `'camera'` -* `'microphone'` -* `'background-sync'` -* `'ambient-light-sensor'` * `'accelerometer'` -* `'gyroscope'` -* `'magnetometer'` * `'accessibility-events'` +* `'ambient-light-sensor'` +* `'background-sync'` +* `'camera'` * `'clipboard-read'` * `'clipboard-write'` +* `'geolocation'` +* `'gyroscope'` +* `'magnetometer'` +* `'microphone'` +* `'midi-sysex'` (system-exclusive midi) +* `'midi'` +* `'notifications'` * `'payment-handler'` +* `'storage-access'` ### option: BrowserContext.grantPermissions.origin * since: v1.8 diff --git a/packages/playwright-core/src/server/chromium/crBrowser.ts b/packages/playwright-core/src/server/chromium/crBrowser.ts index 530906c0b2..09a24c1d1b 100644 --- a/packages/playwright-core/src/server/chromium/crBrowser.ts +++ b/packages/playwright-core/src/server/chromium/crBrowser.ts @@ -433,6 +433,7 @@ export class CRBrowserContext extends BrowserContext { ['payment-handler', 'paymentHandler'], // chrome-specific permissions we have. ['midi-sysex', 'midiSysex'], + ['storage-access', 'storageAccess'], ]); const filtered = permissions.map(permission => { const protocolPermission = webPermissionToProtocol.get(permission); diff --git a/packages/playwright-core/types/types.d.ts b/packages/playwright-core/types/types.d.ts index 3753d59986..10dd00f198 100644 --- a/packages/playwright-core/types/types.d.ts +++ b/packages/playwright-core/types/types.d.ts @@ -8516,21 +8516,22 @@ export interface BrowserContext { * Grants specified permissions to the browser context. Only grants corresponding permissions to the given origin if * specified. * @param permissions A permission or an array of permissions to grant. Permissions can be one of the following values: - * - `'geolocation'` - * - `'midi'` - * - `'midi-sysex'` (system-exclusive midi) - * - `'notifications'` - * - `'camera'` - * - `'microphone'` - * - `'background-sync'` - * - `'ambient-light-sensor'` * - `'accelerometer'` - * - `'gyroscope'` - * - `'magnetometer'` * - `'accessibility-events'` + * - `'ambient-light-sensor'` + * - `'background-sync'` + * - `'camera'` * - `'clipboard-read'` * - `'clipboard-write'` + * - `'geolocation'` + * - `'gyroscope'` + * - `'magnetometer'` + * - `'microphone'` + * - `'midi-sysex'` (system-exclusive midi) + * - `'midi'` + * - `'notifications'` * - `'payment-handler'` + * - `'storage-access'` * @param options */ grantPermissions(permissions: ReadonlyArray, options?: { diff --git a/tests/library/permissions.spec.ts b/tests/library/permissions.spec.ts index db0b92a53b..ac2ec7a0b5 100644 --- a/tests/library/permissions.spec.ts +++ b/tests/library/permissions.spec.ts @@ -172,3 +172,29 @@ it('should support clipboard read', async ({ page, context, server, browserName, await page.evaluate(() => navigator.clipboard.writeText('test content')); expect(await page.evaluate(() => navigator.clipboard.readText())).toBe('test content'); }); + +it('storage access', { + annotation: { type: 'issue', description: 'https://github.com/microsoft/playwright/issues/31227' } +}, async ({ page, context, server, browserName }) => { + it.fixme(browserName !== 'chromium'); + await context.grantPermissions(['storage-access']); + expect(await getPermission(page, 'storage-access')).toBe('granted'); + server.setRoute('/set-cookie.html', (req, res) => { + res.setHeader('Set-Cookie', 'name=value; Path=/; SameSite=Strict; Secure'); + res.end(); + }); + server.setRoute('/my-frame.html', (req, res) => { + res.setHeader('Content-type', 'text/html'); + res.end(``); + }); + + // Navigate once to the domain as top level. + await page.goto(server.CROSS_PROCESS_PREFIX + '/set-cookie.html'); + await page.goto(server.PREFIX + '/my-frame.html'); + + const frame = page.frames()[1]; + expect(await getPermission(frame, 'storage-access')).toBe('granted'); + const access = await frame.evaluate(() => document.requestStorageAccess().then(() => true, () => false)); + expect(access).toBe(true); + expect(await frame.evaluate(() => document.hasStorageAccess())).toBe(true); +});