From 3dbf4b3d7ac4fb52fc6f6a4dd009dec34c4f983b Mon Sep 17 00:00:00 2001 From: Simon Knott Date: Fri, 25 Oct 2024 16:33:34 +0200 Subject: [PATCH] implement --- .../src/utils/isomorphic/codegen.ts | 70 ++++++++++++++++--- tests/playwright-test/codegen.spec.ts | 33 +++++++-- 2 files changed, 87 insertions(+), 16 deletions(-) diff --git a/packages/playwright-core/src/utils/isomorphic/codegen.ts b/packages/playwright-core/src/utils/isomorphic/codegen.ts index f56a25380b..a3caeaf9b0 100644 --- a/packages/playwright-core/src/utils/isomorphic/codegen.ts +++ b/packages/playwright-core/src/utils/isomorphic/codegen.ts @@ -17,17 +17,65 @@ import type * as har from '@trace/har'; export function generatePlaywrightRequestCall(request: har.Request, body: string | undefined): string { - const method = request.method; - const headers = request.headers.map(header => { - const name = JSON.stringify(header.name); - const value = JSON.stringify(header.value); - return ` ${name}: ${value}`; - }).join(',\n'); - + let method = request.method.toLowerCase(); const url = new URL(request.url); const urlParam = `${url.origin}${url.pathname}`; - let result = `await page.request.${method}(${JSON.stringify(urlParam)}, {\n`; - result += ` headers: {\n${headers}\n },\n`; - result += `);`; - return result; + const options: any = {}; + if (!['delete', 'get', 'head', 'post', 'put', 'patch'].includes(method)) { + options.method = method; + method = 'fetch'; + } + if (url.searchParams.size) + options.params = Object.fromEntries(url.searchParams.entries()); + if (body) + options.data = body; + if (request.headers.length) + options.headers = Object.fromEntries(request.headers.map(header => [header.name, header.value])); + return `await page.request.${method}('${urlParam}', ${prettyPrintObject(options)});`; +} + +function prettyPrintObject(obj: any, indent = 2, level = 0): string { + // Handle null and undefined + if (obj === null) + return 'null'; + if (obj === undefined) + return 'undefined'; + + // Handle primitive types + if (typeof obj !== 'object') { + if (typeof obj === 'string') + return `'${obj}'`; + return String(obj); + } + + // Handle arrays + if (Array.isArray(obj)) { + if (obj.length === 0) + return '[]'; + const spaces = ' '.repeat(level * indent); + const nextSpaces = ' '.repeat((level + 1) * indent); + + const items = obj.map(item => + `${nextSpaces}${prettyPrintObject(item, indent, level + 1)}` + ).join(',\n'); + + return `[\n${items}\n${spaces}]`; + } + + // Handle regular objects + if (Object.keys(obj).length === 0) + return '{}'; + const spaces = ' '.repeat(level * indent); + const nextSpaces = ' '.repeat((level + 1) * indent); + + const entries = Object.entries(obj).map(([key, value]) => { + const formattedValue = prettyPrintObject(value, indent, level + 1); + // Handle keys that need quotes + const formattedKey = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(key) ? + key : + `'${key}'`; + return `${nextSpaces}${formattedKey}: ${formattedValue}`; + }).join(',\n'); + + return `{\n${entries}\n${spaces}}`; } diff --git a/tests/playwright-test/codegen.spec.ts b/tests/playwright-test/codegen.spec.ts index f3dc2935fa..3d4355b3b3 100644 --- a/tests/playwright-test/codegen.spec.ts +++ b/tests/playwright-test/codegen.spec.ts @@ -21,7 +21,7 @@ test('generatePlaywrightRequestCall', () => { expect(generatePlaywrightRequestCall({ url: 'http://example.com/foo?bar=baz', method: 'GET', - headers: [{ name: 'User-Agent', value: 'Mozilla/5.0' }], + headers: [{ name: 'User-Agent', value: 'Mozilla/5.0' }, { name: 'Date', value: '2021-01-01' }], httpVersion: '1.1', cookies: [], queryString: [], @@ -29,9 +29,32 @@ test('generatePlaywrightRequestCall', () => { bodySize: 0, comment: '', }, 'foo')).toEqual(` -await page.request.GET("http://example.com/foo", { - headers: { - "User-Agent": "Mozilla/5.0" +await page.request.get('http://example.com/foo', { + params: { + bar: 'baz' }, -);`.trim()); + data: 'foo', + headers: { + 'User-Agent': 'Mozilla/5.0', + Date: '2021-01-01' + } +});`.trim()); + + expect(generatePlaywrightRequestCall({ + url: 'http://example.com/foo?bar=baz', + method: 'OPTIONS', + headers: [], + httpVersion: '1.1', + cookies: [], + queryString: [], + headersSize: 0, + bodySize: 0, + comment: '', + }, undefined)).toEqual(` +await page.request.fetch('http://example.com/foo', { + method: 'options', + params: { + bar: 'baz' + } +});`.trim()); }); \ No newline at end of file