BrowserContext.ts (4064B)
1 /** 2 * @license 3 * Copyright 2024 Google Inc. 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7 import { 8 WEB_PERMISSION_TO_PROTOCOL_PERMISSION, 9 type Permission, 10 } from '../api/Browser.js'; 11 import {BrowserContext} from '../api/BrowserContext.js'; 12 import type {Page} from '../api/Page.js'; 13 import type {Cookie, CookieData} from '../common/Cookie.js'; 14 import type {DownloadBehavior} from '../common/DownloadBehavior.js'; 15 import {assert} from '../util/assert.js'; 16 17 import type {CdpBrowser} from './Browser.js'; 18 import type {Connection} from './Connection.js'; 19 import {convertCookiesPartitionKeyFromPuppeteerToCdp} from './Page.js'; 20 import type {CdpTarget} from './Target.js'; 21 22 /** 23 * @internal 24 */ 25 export class CdpBrowserContext extends BrowserContext { 26 #connection: Connection; 27 #browser: CdpBrowser; 28 #id?: string; 29 30 constructor(connection: Connection, browser: CdpBrowser, contextId?: string) { 31 super(); 32 this.#connection = connection; 33 this.#browser = browser; 34 this.#id = contextId; 35 } 36 37 override get id(): string | undefined { 38 return this.#id; 39 } 40 41 override targets(): CdpTarget[] { 42 return this.#browser.targets().filter(target => { 43 return target.browserContext() === this; 44 }); 45 } 46 47 override async pages(): Promise<Page[]> { 48 const pages = await Promise.all( 49 this.targets() 50 .filter(target => { 51 return ( 52 target.type() === 'page' || 53 (target.type() === 'other' && 54 this.#browser._getIsPageTargetCallback()?.(target)) 55 ); 56 }) 57 .map(target => { 58 return target.page(); 59 }), 60 ); 61 return pages.filter((page): page is Page => { 62 return !!page; 63 }); 64 } 65 66 override async overridePermissions( 67 origin: string, 68 permissions: Permission[], 69 ): Promise<void> { 70 const protocolPermissions = permissions.map(permission => { 71 const protocolPermission = 72 WEB_PERMISSION_TO_PROTOCOL_PERMISSION.get(permission); 73 if (!protocolPermission) { 74 throw new Error('Unknown permission: ' + permission); 75 } 76 return protocolPermission; 77 }); 78 await this.#connection.send('Browser.grantPermissions', { 79 origin, 80 browserContextId: this.#id || undefined, 81 permissions: protocolPermissions, 82 }); 83 } 84 85 override async clearPermissionOverrides(): Promise<void> { 86 await this.#connection.send('Browser.resetPermissions', { 87 browserContextId: this.#id || undefined, 88 }); 89 } 90 91 override async newPage(): Promise<Page> { 92 using _guard = await this.waitForScreenshotOperations(); 93 return await this.#browser._createPageInContext(this.#id); 94 } 95 96 override browser(): CdpBrowser { 97 return this.#browser; 98 } 99 100 override async close(): Promise<void> { 101 assert(this.#id, 'Default BrowserContext cannot be closed!'); 102 await this.#browser._disposeContext(this.#id); 103 } 104 105 override async cookies(): Promise<Cookie[]> { 106 const {cookies} = await this.#connection.send('Storage.getCookies', { 107 browserContextId: this.#id, 108 }); 109 return cookies.map(cookie => { 110 return { 111 ...cookie, 112 partitionKey: cookie.partitionKey 113 ? { 114 sourceOrigin: cookie.partitionKey.topLevelSite, 115 hasCrossSiteAncestor: cookie.partitionKey.hasCrossSiteAncestor, 116 } 117 : undefined, 118 }; 119 }); 120 } 121 122 override async setCookie(...cookies: CookieData[]): Promise<void> { 123 return await this.#connection.send('Storage.setCookies', { 124 browserContextId: this.#id, 125 cookies: cookies.map(cookie => { 126 return { 127 ...cookie, 128 partitionKey: convertCookiesPartitionKeyFromPuppeteerToCdp( 129 cookie.partitionKey, 130 ), 131 }; 132 }), 133 }); 134 } 135 136 public async setDownloadBehavior( 137 downloadBehavior: DownloadBehavior, 138 ): Promise<void> { 139 await this.#connection.send('Browser.setDownloadBehavior', { 140 behavior: downloadBehavior.policy, 141 downloadPath: downloadBehavior.downloadPath, 142 browserContextId: this.#id, 143 }); 144 } 145 }