From 191d912f20e6d047f3e988609ae7f4b85b3e9da7 Mon Sep 17 00:00:00 2001 From: Dmitry Gozman Date: Wed, 14 May 2025 08:38:24 +0000 Subject: [PATCH] feat(firefox): support custom policies.json (#35926) --- docs/src/api/params.md | 4 ++ packages/playwright-client/types/types.d.ts | 9 ++++ packages/playwright-core/types/types.d.ts | 9 ++++ tests/assets/client-certificates/README.md | 34 +++++++++++- .../client/localhost/localhost.csr | 27 ++++++++++ .../client/localhost/localhost.ext | 1 + .../client/localhost/localhost.key | 52 +++++++++++++++++++ .../client/localhost/localhost.pem | 29 +++++++++++ tests/config/testserver/index.ts | 8 ++- tests/library/firefox/launcher.spec.ts | 33 ++++++++++++ 10 files changed, 202 insertions(+), 4 deletions(-) create mode 100644 tests/assets/client-certificates/client/localhost/localhost.csr create mode 100644 tests/assets/client-certificates/client/localhost/localhost.ext create mode 100644 tests/assets/client-certificates/client/localhost/localhost.key create mode 100644 tests/assets/client-certificates/client/localhost/localhost.pem diff --git a/docs/src/api/params.md b/docs/src/api/params.md index 4c49370044..2e448aeb68 100644 --- a/docs/src/api/params.md +++ b/docs/src/api/params.md @@ -1071,6 +1071,8 @@ Whether to run browser in headless mode. More details for Firefox user preferences. Learn more about the Firefox user preferences at [`about:config`](https://support.mozilla.org/en-US/kb/about-config-editor-firefox). +You can also provide a path to a custom [`policies.json` file](https://mozilla.github.io/policy-templates/) via `PLAYWRIGHT_FIREFOX_POLICIES_JSON` environment variable. + ## csharp-java-browser-option-firefoxuserprefs * langs: csharp, java - `firefoxUserPrefs` <[Object]<[string], [any]>> @@ -1078,6 +1080,8 @@ Firefox user preferences. Learn more about the Firefox user preferences at Firefox user preferences. Learn more about the Firefox user preferences at [`about:config`](https://support.mozilla.org/en-US/kb/about-config-editor-firefox). +You can also provide a path to a custom [`policies.json` file](https://mozilla.github.io/policy-templates/) via `PLAYWRIGHT_FIREFOX_POLICIES_JSON` environment variable. + ## browser-option-logger * langs: js - `logger` <[Logger]> diff --git a/packages/playwright-client/types/types.d.ts b/packages/playwright-client/types/types.d.ts index f9a1e6d7fb..95b2fa6b15 100644 --- a/packages/playwright-client/types/types.d.ts +++ b/packages/playwright-client/types/types.d.ts @@ -14899,6 +14899,9 @@ export interface BrowserType { /** * Firefox user preferences. Learn more about the Firefox user preferences at * [`about:config`](https://support.mozilla.org/en-US/kb/about-config-editor-firefox). + * + * You can also provide a path to a custom [`policies.json` file](https://mozilla.github.io/policy-templates/) via + * `PLAYWRIGHT_FIREFOX_POLICIES_JSON` environment variable. */ firefoxUserPrefs?: { [key: string]: string|number|boolean; }; @@ -15323,6 +15326,9 @@ export interface BrowserType { /** * Firefox user preferences. Learn more about the Firefox user preferences at * [`about:config`](https://support.mozilla.org/en-US/kb/about-config-editor-firefox). + * + * You can also provide a path to a custom [`policies.json` file](https://mozilla.github.io/policy-templates/) via + * `PLAYWRIGHT_FIREFOX_POLICIES_JSON` environment variable. */ firefoxUserPrefs?: { [key: string]: string|number|boolean; }; @@ -21730,6 +21736,9 @@ export interface LaunchOptions { /** * Firefox user preferences. Learn more about the Firefox user preferences at * [`about:config`](https://support.mozilla.org/en-US/kb/about-config-editor-firefox). + * + * You can also provide a path to a custom [`policies.json` file](https://mozilla.github.io/policy-templates/) via + * `PLAYWRIGHT_FIREFOX_POLICIES_JSON` environment variable. */ firefoxUserPrefs?: { [key: string]: string|number|boolean; }; diff --git a/packages/playwright-core/types/types.d.ts b/packages/playwright-core/types/types.d.ts index f9a1e6d7fb..95b2fa6b15 100644 --- a/packages/playwright-core/types/types.d.ts +++ b/packages/playwright-core/types/types.d.ts @@ -14899,6 +14899,9 @@ export interface BrowserType { /** * Firefox user preferences. Learn more about the Firefox user preferences at * [`about:config`](https://support.mozilla.org/en-US/kb/about-config-editor-firefox). + * + * You can also provide a path to a custom [`policies.json` file](https://mozilla.github.io/policy-templates/) via + * `PLAYWRIGHT_FIREFOX_POLICIES_JSON` environment variable. */ firefoxUserPrefs?: { [key: string]: string|number|boolean; }; @@ -15323,6 +15326,9 @@ export interface BrowserType { /** * Firefox user preferences. Learn more about the Firefox user preferences at * [`about:config`](https://support.mozilla.org/en-US/kb/about-config-editor-firefox). + * + * You can also provide a path to a custom [`policies.json` file](https://mozilla.github.io/policy-templates/) via + * `PLAYWRIGHT_FIREFOX_POLICIES_JSON` environment variable. */ firefoxUserPrefs?: { [key: string]: string|number|boolean; }; @@ -21730,6 +21736,9 @@ export interface LaunchOptions { /** * Firefox user preferences. Learn more about the Firefox user preferences at * [`about:config`](https://support.mozilla.org/en-US/kb/about-config-editor-firefox). + * + * You can also provide a path to a custom [`policies.json` file](https://mozilla.github.io/policy-templates/) via + * `PLAYWRIGHT_FIREFOX_POLICIES_JSON` environment variable. */ firefoxUserPrefs?: { [key: string]: string|number|boolean; }; diff --git a/tests/assets/client-certificates/README.md b/tests/assets/client-certificates/README.md index 7ee690de52..8e1167b9a1 100644 --- a/tests/assets/client-certificates/README.md +++ b/tests/assets/client-certificates/README.md @@ -16,7 +16,7 @@ openssl req \ ## Trusted client-certificate (server signed/valid) -``` +```bash mkdir -p client/trusted # generate server-signed (valid) certifcate openssl req \ @@ -40,9 +40,39 @@ openssl x509 \ openssl pkcs12 -export -out client/trusted/cert.pfx -inkey client/trusted/key.pem -in client/trusted/cert.pem -passout pass:secure ``` +## Trusted certificate for localhost (server signed/valid) + +```bash +mkdir -p client/localhost + +# generate server-signed (valid) certifcate +openssl req \ + -newkey rsa:4096 \ + -keyout client/localhost/localhost.key \ + -out client/localhost/localhost.csr \ + -nodes \ + -days 365 \ + -subj "/CN=localhost" \ + -addext "subjectAltName=DNS:localhost,DNS:127.0.0.1" + +# put extensions +echo "subjectAltName=DNS:localhost,DNS:127.0.0.1" > client/localhost/localhost.ext + +# sign with server_cert.pem +openssl x509 \ + -req \ + -in client/localhost/localhost.csr \ + -CA server/server_cert.pem \ + -CAkey server/server_key.pem \ + -set_serial 01 \ + -out client/localhost/localhost.pem \ + -days 365 \ + -extfile client/localhost/localhost.ext +``` + ## Self-signed certificate (invalid) -``` +```bash mkdir -p client/self-signed openssl req \ -newkey rsa:4096 \ diff --git a/tests/assets/client-certificates/client/localhost/localhost.csr b/tests/assets/client-certificates/client/localhost/localhost.csr new file mode 100644 index 0000000000..b879a33c5b --- /dev/null +++ b/tests/assets/client-certificates/client/localhost/localhost.csr @@ -0,0 +1,27 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIEizCCAnMCAQAwFDESMBAGA1UEAwwJbG9jYWxob3N0MIICIjANBgkqhkiG9w0B +AQEFAAOCAg8AMIICCgKCAgEA3MsXKGgqi6ibh/9wSQOADbPj0rQWsA9DP3SmeOiH +w+m0e/oBKDf0Sp6wfAeYycpnDrBFDRNl6lJg8hVXkUaMwnojV5/hjD8mfAGZpUhK +/7b7EZdjMY1euJbelIJxvD+ZwdY5RNZWb5B4NtwYyrHJ985EauTkdTNM1kBMtUzj +k7CenE37MZwoxW0NQpvTX+MJMmhZynO2QYEP+MxNd51WJDcJv05J3pF0T1MbjXZn +liNTf5F7HTnMu4vMgEOTQIWtcMsP0h/4TdK714/iUaFpEPt28UcoLZPVc9Sn6iKF +rbqtUscMgMfYkqQ4Dz8+YxU8MSQ8c87Ux60MKpLCBHs5JB1R51zfceUrI//PhkXD +zacVpP90D1roAngb5ef7x6OIzxrpGNlOto0Rwa6YMLOTlTR9E9v24P+EmKEnGilT +ztSL26CGFuWAqyNyrJggem+anUDJa9ni3nZXI2YUYCYEyCORaedV8zkyPzB30/Qq +rwm48ITmXUvyEbUlVC8kU2c0q+FRsOZGKyMFFPTHGVuSFyQLftgKdARHeAdmRxfx +mMM+L7HprJNhSNvKrG+vNxnvXrY/6U4K7TyCTWaw5nG0fLZld7t/TX2vT747eE2H +4EomF3xxn8iSLM5IH7NCasKmoa+a7s1PSU+uNx6vOGuJm0vqT/G1JkiL/HVfACsI +5u0CAwEAAaAyMDAGCSqGSIb3DQEJDjEjMCEwHwYDVR0RBBgwFoIJbG9jYWxob3N0 +ggkxMjcuMC4wLjEwDQYJKoZIhvcNAQELBQADggIBAKz5LKzuOQKjT9IJA/ltZxB4 +As+G2EcA6CUTcW5OTfZLhXlSKFNtlVe/NIsvZRS95pFCkpp01OPmjN0x/hB9ti9+ +2dbOKn3dXlCGIqGKMgh7Hzf4MowY3uOt/+DYY/zeD3Dj7MQELtt3y/ZDD2kcog1G +1XUDSD77ptpl08JrXDgzzU29930j5TONcwKx0cBknUXfpDkmVACC4l3h3OIA8bTh +YGM82bgbN9n2Pj7/bfO+ZD3JhlLkHko6bef2OEeUd7KXXEbG/D1TJnkzkjFC7LXp +X6gaN5UVz33HV5cZVhMi9KIZO1IA2W4i0tbD1+dFXzN9Ei+AijleI7oxrVdYoC2i +RKPDkO8oTc1ikjwXf6S0b60g+0QqabBsKcViRMpq1h6EWi28XycNfZLFBA9X67GU +tEY5JroiWlTPJrNAdcCynVu2sAZG7Hf6AI4SLIUAScTgQEPsi0FbrkWiBzTYrNwh +faYcb/Vd0OuudGehUoBq1YyJR76CVIcIEwkPLBzJ8xvMrolWZJBoCG4MG1C+m+u6 +4815IvuMsUnOnYwgUK3pd9eCgdgZUWDMpb29OkGAj9Io3ZrrfJTqd27QcSYzqEQl +6PE5DflYqSABJRMcAV0xw6m012HKdgxKTK0QTdlLb8AP8s3G9uJ3RnQOMoJJWs5H +BiK08R0zxv88ctjSzYah +-----END CERTIFICATE REQUEST----- diff --git a/tests/assets/client-certificates/client/localhost/localhost.ext b/tests/assets/client-certificates/client/localhost/localhost.ext new file mode 100644 index 0000000000..d4d0227265 --- /dev/null +++ b/tests/assets/client-certificates/client/localhost/localhost.ext @@ -0,0 +1 @@ +subjectAltName=DNS:localhost,DNS:127.0.0.1 diff --git a/tests/assets/client-certificates/client/localhost/localhost.key b/tests/assets/client-certificates/client/localhost/localhost.key new file mode 100644 index 0000000000..607731ed32 --- /dev/null +++ b/tests/assets/client-certificates/client/localhost/localhost.key @@ -0,0 +1,52 @@ +-----BEGIN PRIVATE KEY----- +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 +eH8L0+a3Lq6SZB1iV/r/6xVQlDJn +-----END PRIVATE KEY----- diff --git a/tests/assets/client-certificates/client/localhost/localhost.pem b/tests/assets/client-certificates/client/localhost/localhost.pem new file mode 100644 index 0000000000..1f1ba9cb3e --- /dev/null +++ b/tests/assets/client-certificates/client/localhost/localhost.pem @@ -0,0 +1,29 @@ +-----BEGIN CERTIFICATE----- +MIIE6DCCAtCgAwIBAgIBATANBgkqhkiG9w0BAQsFADA2MRIwEAYDVQQDDAlsb2Nh +bGhvc3QxIDAeBgNVBAoMF0NsaWVudCBDZXJ0aWZpY2F0ZSBEZW1vMB4XDTI1MDUw +NjE4MDg0M1oXDTI2MDUwNjE4MDg0M1owFDESMBAGA1UEAwwJbG9jYWxob3N0MIIC +IjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA3MsXKGgqi6ibh/9wSQOADbPj +0rQWsA9DP3SmeOiHw+m0e/oBKDf0Sp6wfAeYycpnDrBFDRNl6lJg8hVXkUaMwnoj +V5/hjD8mfAGZpUhK/7b7EZdjMY1euJbelIJxvD+ZwdY5RNZWb5B4NtwYyrHJ985E +auTkdTNM1kBMtUzjk7CenE37MZwoxW0NQpvTX+MJMmhZynO2QYEP+MxNd51WJDcJ +v05J3pF0T1MbjXZnliNTf5F7HTnMu4vMgEOTQIWtcMsP0h/4TdK714/iUaFpEPt2 +8UcoLZPVc9Sn6iKFrbqtUscMgMfYkqQ4Dz8+YxU8MSQ8c87Ux60MKpLCBHs5JB1R +51zfceUrI//PhkXDzacVpP90D1roAngb5ef7x6OIzxrpGNlOto0Rwa6YMLOTlTR9 +E9v24P+EmKEnGilTztSL26CGFuWAqyNyrJggem+anUDJa9ni3nZXI2YUYCYEyCOR +aedV8zkyPzB30/Qqrwm48ITmXUvyEbUlVC8kU2c0q+FRsOZGKyMFFPTHGVuSFyQL +ftgKdARHeAdmRxfxmMM+L7HprJNhSNvKrG+vNxnvXrY/6U4K7TyCTWaw5nG0fLZl +d7t/TX2vT747eE2H4EomF3xxn8iSLM5IH7NCasKmoa+a7s1PSU+uNx6vOGuJm0vq +T/G1JkiL/HVfACsI5u0CAwEAAaMjMCEwHwYDVR0RBBgwFoIJbG9jYWxob3N0ggkx +MjcuMC4wLjEwDQYJKoZIhvcNAQELBQADggIBAB205rDQEWyvjjwoTMZ1xgPtwbxt +CzodNh2RPywx5APudHukTt3tHc9AJXQda8g23Dpl2Bmyli5Uyn9ufLOzyqUPmwdD ++tjk6HQvbhkVyylTA8b/HpO3hljcju+BIeHnFvBZxo9+aDhxbC1sICIIR9eJn62m +GFdweb32Ijd1tdL0ZEqTlkO+m2/27wVaNfMUhLLcA+6b31iyt1k2Pcl1l4TzMneW +Dr8BPZLbOZWSAaTLfYuFPnY2qsJ/gnX2Of06HNtNC0THFb6fWcPgc8dJb/04Ggjh +/GjbisNMZPrv18HQlG+GVZFGNq0iWqX+CPxZYxBLslLuRKixORTb0tSV4l0/qVYP ++y1FqEfm+VPxAUJCMm7TH0CpXVSejasRiF5T60rS58OXTqNgf3yHPci1jKkLwMT2 +Y7BsLjakVSY+esxpRCdVE5SlSODpIVyCcFtMYzDZR8SXy6bReb9f4KKbtOwsH7gB +qPt2yf2hUkl07VfCTx+xk4e6j/mzVcKItqsPFPb1x/FAuB+/7Buwd/sgd80QPhTk +gvi7GRW1QwtzQIidosSrHlbXMwlxseXX78tMaXxIycys8Rj6AHNjcPWD8f8VeBNS +J9ajswRkIj2sLTGUJybVRZYzUSsjuJab1Lerf/4PALnVQSrajtBfkDVJy3vg29gq +zYZHyXcanSQrccdE +-----END CERTIFICATE----- diff --git a/tests/config/testserver/index.ts b/tests/config/testserver/index.ts index b3c1a42b25..7538badf9d 100644 --- a/tests/config/testserver/index.ts +++ b/tests/config/testserver/index.ts @@ -58,7 +58,7 @@ export class TestServer { static async create(dirPath: string, port: number, loopback?: string): Promise { const server = new TestServer(dirPath, port, loopback); - await new Promise(x => server._server.once('listening', x)); + await server.waitUntilReady(); return server; } @@ -68,7 +68,7 @@ export class TestServer { cert: await fs.promises.readFile(path.join(__dirname, 'cert.pem')), passphrase: 'aaaa', }); - await new Promise(x => server._server.once('listening', x)); + await server.waitUntilReady(); return server; } @@ -121,6 +121,10 @@ export class TestServer { this.EMPTY_PAGE = `${protocol}://${same_origin}:${port}/empty.html`; } + async waitUntilReady() { + await new Promise(x => this._server.once('listening', x)); + } + _onSocket(socket: net.Socket) { // ECONNRESET and HPE_INVALID_EOF_STATE are legit errors given // that tab closing aborts outgoing connections to the server. diff --git a/tests/library/firefox/launcher.spec.ts b/tests/library/firefox/launcher.spec.ts index 0dac82ee51..1fe1de3e20 100644 --- a/tests/library/firefox/launcher.spec.ts +++ b/tests/library/firefox/launcher.spec.ts @@ -14,7 +14,9 @@ * limitations under the License. */ +import fs from 'fs'; import { playwrightTest as it, expect } from '../../config/browserTest'; +import { TestServer } from '../../config/testserver'; it('should pass firefox user preferences', async ({ browserType, mode }) => { it.skip(mode.startsWith('service')); @@ -43,3 +45,34 @@ it('should pass firefox user preferences in persistent', async ({ mode, launchPe const error = await page.goto('https://example.com').catch(e => e); expect(error.message).toContain('NS_ERROR_PROXY_CONNECTION_REFUSED'); }); + +it('should support custom firefox policies', async ({ browserType, mode, asset, loopback }, testInfo) => { + it.skip(mode.startsWith('service')); + + const policies = { + 'policies': { + 'Certificates': { + 'Install': [asset('client-certificates/server/server_cert.pem')], + }, + }, + }; + const policiesPath = testInfo.outputPath('policies.json'); + await fs.promises.writeFile(policiesPath, JSON.stringify(policies)); + + const port = 48112; + const server = new TestServer(asset(''), port, loopback, { + key: await fs.promises.readFile(asset('client-certificates/client/localhost/localhost.key')), + cert: await fs.promises.readFile(asset('client-certificates/client/localhost/localhost.pem')), + }); + await server.waitUntilReady(); + + const browser = await browserType.launch({ + env: { ...process.env, 'PLAYWRIGHT_FIREFOX_POLICIES_JSON': policiesPath }, + }); + + const page = await browser.newPage(); + await page.goto(server.PREFIX + '/frames/frame.html'); + await expect(page.locator('body')).toHaveText(`Hi, I'm frame`); + await browser.close(); + await server.stop(); +});