diff --git a/docs/src/api/params.md b/docs/src/api/params.md index f301a5f880..4e2d554ed1 100644 --- a/docs/src/api/params.md +++ b/docs/src/api/params.md @@ -531,7 +531,6 @@ Using Client Certificates in combination with Proxy Servers is not supported. :::note When using WebKit on macOS, accessing `localhost` will not pick up client certificates. You can make it work by replacing `localhost` with `local.playwright`. -Instead, use `playwright.local` as the hostname. ::: ## context-option-useragent diff --git a/packages/playwright-core/src/server/browser.ts b/packages/playwright-core/src/server/browser.ts index 5f7b85fa13..c37325b485 100644 --- a/packages/playwright-core/src/server/browser.ts +++ b/packages/playwright-core/src/server/browser.ts @@ -85,7 +85,13 @@ export abstract class Browser extends SdkObject { async newContext(metadata: CallMetadata, options: channels.BrowserNewContextParams): Promise { validateBrowserContextOptions(options, this.options); const clientCertificatesProxy = await createClientCertificatesProxyIfNeeded(options, this.options); - const context = await this.doCreateNewContext(options); + let context; + try { + context = await this.doCreateNewContext(options); + } catch (error) { + await clientCertificatesProxy?.close(); + throw error; + } context._clientCertificatesProxy = clientCertificatesProxy; if (options.storageState) await context.setStorageState(metadata, options.storageState); diff --git a/packages/playwright-core/src/server/browserContext.ts b/packages/playwright-core/src/server/browserContext.ts index 49283b7aa9..735adec11e 100644 --- a/packages/playwright-core/src/server/browserContext.ts +++ b/packages/playwright-core/src/server/browserContext.ts @@ -659,6 +659,7 @@ export async function createClientCertificatesProxyIfNeeded(options: channels.Br return; if (options.proxy?.server || browserOptions?.proxy?.server) throw new Error('Cannot specify both proxy and clientCertificates'); + verifyClientCertificates(options.clientCertificates); const clientCertificatesProxy = new ClientCertificatesProxy(options); options.proxy = { server: await clientCertificatesProxy.listen() }; options.ignoreHTTPSErrors = true; @@ -702,7 +703,6 @@ export function validateBrowserContextOptions(options: channels.BrowserNewContex options.proxy = normalizeProxySettings(options.proxy); } verifyGeolocation(options.geolocation); - verifyClientCertificates(options.clientCertificates); } export function verifyGeolocation(geolocation?: types.Geolocation) { diff --git a/packages/playwright-core/src/server/browserType.ts b/packages/playwright-core/src/server/browserType.ts index b06ef52a2b..24a057ebf9 100644 --- a/packages/playwright-core/src/server/browserType.ts +++ b/packages/playwright-core/src/server/browserType.ts @@ -79,18 +79,16 @@ export abstract class BrowserType extends SdkObject { const controller = new ProgressController(metadata, this); const persistent: channels.BrowserNewContextParams = { ...options }; controller.setLogName('browser'); - - // Note: Any initial TLS requests will fail since we rely on the Page/Frames initialize which sets ignoreHTTPSErrors. - const clientCertificatesProxy = await createClientCertificatesProxyIfNeeded(persistent); - if (clientCertificatesProxy) - options.proxy = persistent.proxy; - - const browser = await controller.run(progress => { + const browser = await controller.run(async progress => { + // Note: Any initial TLS requests will fail since we rely on the Page/Frames initialize which sets ignoreHTTPSErrors. + const clientCertificatesProxy = await createClientCertificatesProxyIfNeeded(persistent); + if (clientCertificatesProxy) + options.proxy = persistent.proxy; progress.cleanupWhenAborted(() => clientCertificatesProxy?.close()); - return this._innerLaunchWithRetries(progress, options, persistent, helper.debugProtocolLogger(), userDataDir).catch(e => { throw this._rewriteStartupLog(e); }); + const browser = await this._innerLaunchWithRetries(progress, options, persistent, helper.debugProtocolLogger(), userDataDir).catch(e => { throw this._rewriteStartupLog(e); }); + browser._defaultContext!._clientCertificatesProxy = clientCertificatesProxy; + return browser; }, TimeoutSettings.launchTimeout(options)); - browser._defaultContext!._clientCertificatesProxy = clientCertificatesProxy; - return browser._defaultContext!; } diff --git a/packages/playwright-core/types/types.d.ts b/packages/playwright-core/types/types.d.ts index 2164aa12a3..f9e25c8c40 100644 --- a/packages/playwright-core/types/types.d.ts +++ b/packages/playwright-core/types/types.d.ts @@ -13230,7 +13230,7 @@ export interface BrowserType { * **NOTE** Using Client Certificates in combination with Proxy Servers is not supported. * * **NOTE** When using WebKit on macOS, accessing `localhost` will not pick up client certificates. You can make it - * work by replacing `localhost` with `local.playwright`. Instead, use `playwright.local` as the hostname. + * work by replacing `localhost` with `local.playwright`. */ clientCertificates?: Array<{ /** @@ -15642,7 +15642,7 @@ export interface APIRequest { * **NOTE** Using Client Certificates in combination with Proxy Servers is not supported. * * **NOTE** When using WebKit on macOS, accessing `localhost` will not pick up client certificates. You can make it - * work by replacing `localhost` with `local.playwright`. Instead, use `playwright.local` as the hostname. + * work by replacing `localhost` with `local.playwright`. */ clientCertificates?: Array<{ /** @@ -16836,7 +16836,7 @@ export interface Browser extends EventEmitter { * **NOTE** Using Client Certificates in combination with Proxy Servers is not supported. * * **NOTE** When using WebKit on macOS, accessing `localhost` will not pick up client certificates. You can make it - * work by replacing `localhost` with `local.playwright`. Instead, use `playwright.local` as the hostname. + * work by replacing `localhost` with `local.playwright`. */ clientCertificates?: Array<{ /** @@ -20311,7 +20311,7 @@ export interface BrowserContextOptions { * **NOTE** Using Client Certificates in combination with Proxy Servers is not supported. * * **NOTE** When using WebKit on macOS, accessing `localhost` will not pick up client certificates. You can make it - * work by replacing `localhost` with `local.playwright`. Instead, use `playwright.local` as the hostname. + * work by replacing `localhost` with `local.playwright`. */ clientCertificates?: Array<{ /** diff --git a/packages/playwright/types/test.d.ts b/packages/playwright/types/test.d.ts index 7725121d12..b5cc9aec8f 100644 --- a/packages/playwright/types/test.d.ts +++ b/packages/playwright/types/test.d.ts @@ -5210,7 +5210,7 @@ export interface PlaywrightTestOptions { * **NOTE** Using Client Certificates in combination with Proxy Servers is not supported. * * **NOTE** When using WebKit on macOS, accessing `localhost` will not pick up client certificates. You can make it - * work by replacing `localhost` with `local.playwright`. Instead, use `playwright.local` as the hostname. + * work by replacing `localhost` with `local.playwright`. * * **Usage** *