diff --git a/packages/playwright-core/src/utils/isomorphic/codegen.ts b/packages/playwright-core/src/utils/isomorphic/codegen.ts new file mode 100644 index 0000000000..f56a25380b --- /dev/null +++ b/packages/playwright-core/src/utils/isomorphic/codegen.ts @@ -0,0 +1,33 @@ +/** + * Copyright (c) Microsoft Corporation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +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'); + + 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; +} diff --git a/packages/trace-viewer/src/third_party/devtools.ts b/packages/trace-viewer/src/third_party/devtools.ts index 27c520cbce..ad56d9402d 100644 --- a/packages/trace-viewer/src/third_party/devtools.ts +++ b/packages/trace-viewer/src/third_party/devtools.ts @@ -280,6 +280,6 @@ export async function generateFetchCall(resource: Entry, style: FetchStyle = Fet return `fetch(${url}, ${options});`; } -async function fetchRequestPostData(resource: Entry) { +export async function fetchRequestPostData(resource: Entry) { return resource.request.postData?._sha1 ? await fetch(`sha1/${resource.request.postData._sha1}`).then(r => r.text()) : resource.request.postData?.text; } \ No newline at end of file diff --git a/packages/trace-viewer/src/ui/networkResourceDetails.tsx b/packages/trace-viewer/src/ui/networkResourceDetails.tsx index 7fe5c7f732..d4dc22a044 100644 --- a/packages/trace-viewer/src/ui/networkResourceDetails.tsx +++ b/packages/trace-viewer/src/ui/networkResourceDetails.tsx @@ -20,8 +20,9 @@ import './networkResourceDetails.css'; import { TabbedPane } from '@web/components/tabbedPane'; import { CodeMirrorWrapper } from '@web/components/codeMirrorWrapper'; import { ToolbarButton } from '@web/components/toolbarButton'; -import { generateCurlCommand, generateFetchCall } from '../third_party/devtools'; +import { fetchRequestPostData, generateCurlCommand, generateFetchCall } from '../third_party/devtools'; import { CopyToClipboardTextButton } from './copyToClipboard'; +import { generatePlaywrightRequestCall } from '@isomorphic/codegen'; export const NetworkResourceDetails: React.FunctionComponent<{ resource: ResourceSnapshot; @@ -58,6 +59,8 @@ const RequestTab: React.FunctionComponent<{ }> = ({ resource }) => { const [requestBody, setRequestBody] = React.useState<{ text: string, mimeType?: string } | null>(null); + const isJavascript = true; // TODO + React.useEffect(() => { const readResources = async () => { if (resource.request.postData) { @@ -96,6 +99,7 @@ const RequestTab: React.FunctionComponent<{
generateCurlCommand(resource)} /> generateFetchCall(resource)} /> + {isJavascript && generatePlaywrightRequestCall(resource.request, requestBody?.text)} />}
{requestBody &&
Request Body
} diff --git a/tests/playwright-test/codegen.spec.ts b/tests/playwright-test/codegen.spec.ts new file mode 100644 index 0000000000..f3dc2935fa --- /dev/null +++ b/tests/playwright-test/codegen.spec.ts @@ -0,0 +1,37 @@ +/** + * Copyright (c) Microsoft Corporation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { test, expect } from './playwright-test-fixtures'; +import { generatePlaywrightRequestCall } from '../../packages/playwright-core/src/utils/isomorphic/codegen'; + +test('generatePlaywrightRequestCall', () => { + expect(generatePlaywrightRequestCall({ + url: 'http://example.com/foo?bar=baz', + method: 'GET', + headers: [{ name: 'User-Agent', value: 'Mozilla/5.0' }], + httpVersion: '1.1', + cookies: [], + queryString: [], + headersSize: 0, + bodySize: 0, + comment: '', + }, 'foo')).toEqual(` +await page.request.GET("http://example.com/foo", { + headers: { + "User-Agent": "Mozilla/5.0" + }, +);`.trim()); +}); \ No newline at end of file