diff --git a/docs/src/api/class-browsertype.md b/docs/src/api/class-browsertype.md index 176f696e1d..0d41bb1aa7 100644 --- a/docs/src/api/class-browsertype.md +++ b/docs/src/api/class-browsertype.md @@ -343,6 +343,9 @@ use a temporary directory instead. ### option: BrowserType.launchPersistentContext.firefoxUserPrefs2 = %%-csharp-java-browser-option-firefoxuserprefs-%% * since: v1.40 +### option: BrowserType.launchPersistentContext.clientCertificates = %%-context-option-clientCertificates-%% +* since: 1.46 + ## async method: BrowserType.launchServer * since: v1.8 * langs: js diff --git a/packages/playwright-core/src/server/browser.ts b/packages/playwright-core/src/server/browser.ts index 1693c6eae4..d37d7d7335 100644 --- a/packages/playwright-core/src/server/browser.ts +++ b/packages/playwright-core/src/server/browser.ts @@ -89,6 +89,7 @@ export abstract class Browser extends SdkObject { if (options.clientCertificates?.length) { clientCertificatesProxy = new ClientCertificatesProxy(options); options.proxy = { server: await clientCertificatesProxy.listen() }; + options.ignoreHTTPSErrors = true; } const context = await this.doCreateNewContext(options); context._clientCertificatesProxy = clientCertificatesProxy; diff --git a/packages/playwright-core/src/server/browserContext.ts b/packages/playwright-core/src/server/browserContext.ts index 44d0efcafa..f553532790 100644 --- a/packages/playwright-core/src/server/browserContext.ts +++ b/packages/playwright-core/src/server/browserContext.ts @@ -693,8 +693,6 @@ export function validateBrowserContextOptions(options: channels.BrowserNewContex throw new Error('Cannot specify both proxy and clientCertificates'); options.proxy = normalizeProxySettings(options.proxy); } - if (options.clientCertificates?.length) - options.ignoreHTTPSErrors = true; verifyGeolocation(options.geolocation); verifyClientCertificates(options.clientCertificates); } diff --git a/packages/playwright-core/types/types.d.ts b/packages/playwright-core/types/types.d.ts index 293cf36b97..1c14e0d021 100644 --- a/packages/playwright-core/types/types.d.ts +++ b/packages/playwright-core/types/types.d.ts @@ -13221,6 +13221,47 @@ export interface BrowserType { */ chromiumSandbox?: boolean; + /** + * An array of client certificates to be used. Each certificate object must have `cert` and `key` or `pfx` to load the + * client certificate. Optionally, `passphrase` property should be provided if the private key is encrypted. If the + * certificate is issued by a custom certificate authority, the `ignoreHTTPSErrors` needs to be set. If the + * certificate is valid only for specific URLs, the `url` property should be provided with a glob pattern to match the + * URLs that the certificate is valid for. + * + * **NOTE** Using Client Certificates in combination with Proxy Servers is not supported. + */ + clientCertificates?: Array<{ + /** + * Glob pattern to match the URLs that the certificate is valid for. + */ + url: string; + + /** + * List of client certificates to be used. + */ + certs: Array<{ + /** + * Path to the file with the certificate in PEM format. + */ + cert?: string; + + /** + * Path to the file with the private key in PEM format. + */ + key?: string; + + /** + * Passphrase for the private key (PEM or PFX). + */ + passphrase?: string; + + /** + * Path to the PFX or PKCS12 encoded private key and certificate chain. + */ + pfx?: string; + }>; + }>; + /** * Emulates `'prefers-colors-scheme'` media feature, supported values are `'light'`, `'dark'`, `'no-preference'`. See * [page.emulateMedia([options])](https://playwright.dev/docs/api/class-page#page-emulate-media) for more details. diff --git a/tests/library/client-certificates.spec.ts b/tests/library/client-certificates.spec.ts index f0814df023..28516d3e76 100644 --- a/tests/library/client-certificates.spec.ts +++ b/tests/library/client-certificates.spec.ts @@ -228,7 +228,7 @@ test.describe('browser', () => { await page.close(); }); - test('should fail with untrusted client certs', async ({ browser, serverURLRewrittenToLocalhost, asset }) => { + test('should throw with a untrusted CA', async ({ browser, serverURLRewrittenToLocalhost, asset }) => { const page = await browser.newPage({ clientCertificates: [{ url: serverURLRewrittenToLocalhost,