From e9ac3cb3a03bb8f96386a16c1d07527cea8b5f5c Mon Sep 17 00:00:00 2001 From: emilioalvap Date: Mon, 9 Sep 2024 18:01:47 +0200 Subject: [PATCH] feat: add support for in-memory client certificates --- __tests__/options.test.ts | 19 ++++++++++++++++- package-lock.json | 28 ++++++++++++------------- package.json | 6 +++--- src/config.ts | 1 + src/formatter/javascript.ts | 4 ++-- src/options.ts | 41 +++++++++++++++++++++++++++++++++++-- 6 files changed, 77 insertions(+), 22 deletions(-) diff --git a/__tests__/options.test.ts b/__tests__/options.test.ts index 283a7556..ada63834 100644 --- a/__tests__/options.test.ts +++ b/__tests__/options.test.ts @@ -24,7 +24,7 @@ */ import { CliArgs } from '../src/common_types'; -import { normalizeOptions } from '../src/options'; +import { normalizeOptions, parsePlaywrightOptions } from '../src/options'; import { join } from 'path'; describe('options', () => { @@ -148,4 +148,21 @@ describe('options', () => { }, }); }); + + it('cli parses playwrightOptions.clientCertificates correctly', async () => { + const test = { + clientCertificates: [ + { + key: Buffer.from('This should be revived'), + cert: Buffer.from('This should be revived'), + pass: Buffer.from('This should not be revived'), + }, + ], + }; + const result = parsePlaywrightOptions(JSON.stringify(test)); + + expect(Buffer.isBuffer(result?.clientCertificates[0].cert)).toBeTruthy(); + expect(Buffer.isBuffer(result?.clientCertificates[0].key)).toBeTruthy(); + expect(Buffer.isBuffer(result?.clientCertificates[0].pass)).toBeFalsy(); + }); }); diff --git a/package-lock.json b/package-lock.json index 0bdc0390..d052b432 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,9 +19,9 @@ "kleur": "^4.1.5", "micromatch": "^4.0.7", "pirates": "^4.0.5", - "playwright": "=1.45.1", - "playwright-chromium": "=1.45.1", - "playwright-core": "=1.45.1", + "playwright": "=1.47.0", + "playwright-chromium": "=1.47.0", + "playwright-core": "=1.47.0", "semver": "^7.5.4", "sharp": "^0.33.5", "snakecase-keys": "^4.0.1", @@ -13825,11 +13825,11 @@ } }, "node_modules/playwright": { - "version": "1.45.1", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.45.1.tgz", - "integrity": "sha512-Hjrgae4kpSQBr98nhCj3IScxVeVUixqj+5oyif8TdIn2opTCPEzqAqNMeK42i3cWDCVu9MI+ZsGWw+gVR4ISBg==", + "version": "1.47.0", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.47.0.tgz", + "integrity": "sha512-jOWiRq2pdNAX/mwLiwFYnPHpEZ4rM+fRSQpRHwEwZlP2PUANvL3+aJOF/bvISMhFD30rqMxUB4RJx9aQbfh4Ww==", "dependencies": { - "playwright-core": "1.45.1" + "playwright-core": "1.47.0" }, "bin": { "playwright": "cli.js" @@ -13842,12 +13842,12 @@ } }, "node_modules/playwright-chromium": { - "version": "1.45.1", - "resolved": "https://registry.npmjs.org/playwright-chromium/-/playwright-chromium-1.45.1.tgz", - "integrity": "sha512-BlYo+kuMg4Jo40Nems2GGVMWdKI2GeHL85D7pkwEW3aq6iEDW3XL7udmoNLOIfluSCKzVRJMB0ta1mt67B3tGA==", + "version": "1.47.0", + "resolved": "https://registry.npmjs.org/playwright-chromium/-/playwright-chromium-1.47.0.tgz", + "integrity": "sha512-S/9ShSLRK6gZZCuon2K0OcEi/t7vmUmx7vqqcpI9/zzKPMWm/+XKKuOHahKXsZLp3DfmRLv7h/PflC19nXZVhA==", "hasInstallScript": true, "dependencies": { - "playwright-core": "1.45.1" + "playwright-core": "1.47.0" }, "bin": { "playwright": "cli.js" @@ -13857,9 +13857,9 @@ } }, "node_modules/playwright-core": { - "version": "1.45.1", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.45.1.tgz", - "integrity": "sha512-LF4CUUtrUu2TCpDw4mcrAIuYrEjVDfT1cHbJMfwnE2+1b8PZcFzPNgvZCvq2JfQ4aTjRCCHw5EJ2tmr2NSzdPg==", + "version": "1.47.0", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.47.0.tgz", + "integrity": "sha512-1DyHT8OqkcfCkYUD9zzUTfg7EfTd+6a8MkD/NWOvjo0u/SCNd5YmY/lJwFvUZOxJbWNds+ei7ic2+R/cRz/PDg==", "bin": { "playwright-core": "cli.js" }, diff --git a/package.json b/package.json index 4440d13c..aa3a2dda 100644 --- a/package.json +++ b/package.json @@ -61,9 +61,9 @@ "kleur": "^4.1.5", "micromatch": "^4.0.7", "pirates": "^4.0.5", - "playwright": "=1.45.1", - "playwright-chromium": "=1.45.1", - "playwright-core": "=1.45.1", + "playwright": "=1.47.0", + "playwright-chromium": "=1.47.0", + "playwright-core": "=1.47.0", "semver": "^7.5.4", "sharp": "^0.33.5", "snakecase-keys": "^4.0.1", diff --git a/src/config.ts b/src/config.ts index 64c8b0e8..c9982eab 100644 --- a/src/config.ts +++ b/src/config.ts @@ -59,6 +59,7 @@ export async function readConfig( options = await optionsPromise; } } + return options; } diff --git a/src/formatter/javascript.ts b/src/formatter/javascript.ts index 2b8af6a3..6a9d8bf5 100644 --- a/src/formatter/javascript.ts +++ b/src/formatter/javascript.ts @@ -26,7 +26,7 @@ import { JavaScriptLanguageGenerator, JavaScriptFormatter, -} from 'playwright-core/lib/server/recorder/javascript'; +} from 'playwright-core/lib/server/codegen/javascript'; export type Step = { actions: ActionInContext[]; @@ -272,7 +272,7 @@ export class SyntheticsGenerator extends JavaScriptLanguageGenerator { if (isAssert && action.command) { formatter.add(toAssertCall(pageAlias, action)); } else { - formatter.add(super._generateActionCall(subject, action)); + formatter.add(super._generateActionCall(subject, actionInContext)); } if (signals.popup) diff --git a/src/options.ts b/src/options.ts index d2be3737..31fb1151 100644 --- a/src/options.ts +++ b/src/options.ts @@ -77,7 +77,15 @@ export async function normalizeOptions( */ const playwrightOpts = merge( config.playwrightOptions, - cliArgs.playwrightOptions || {} + cliArgs.playwrightOptions || {}, + { + arrayMerge(target, source) { + if (source && source.length > 0) { + return [...new Set(source)]; + } + return target; + }, + } ); options.playwrightOptions = { ...playwrightOpts, @@ -195,7 +203,7 @@ export function getCommonCommandOpts() { const playwrightOpts = createOption( '--playwright-options ', 'JSON object to pass in custom Playwright options for the agent. Options passed will be merged with Playwright options defined in your synthetics.config.js file.' - ).argParser(JSON.parse); + ).argParser(parsePlaywrightOptions); const pattern = createOption( '--pattern ', @@ -237,3 +245,32 @@ export function getCommonCommandOpts() { match, }; } + +export function parsePlaywrightOptions(playwrightOpts: string) { + return JSON.parse(playwrightOpts, (key, value) => { + if (key !== 'clientCertificates') { + return value; + } + + // Revive serialized clientCertificates buffer objects + return (value ?? []).map(item => { + const revived = { ...item }; + if (item.cert && !Buffer.isBuffer(item.cert)) { + revived.cert = parseAsBuffer(item.cert); + } + if (item.key && !Buffer.isBuffer(item.key)) { + revived.key = parseAsBuffer(item.key); + } + + return revived; + }); + }); +} + +function parseAsBuffer(value: any): Buffer { + try { + return Buffer.from(value); + } catch (e) { + return value; + } +}