Skip to content

Commit c23fe70

Browse files
dgozmanSkn0tt
andauthored
cherry-pick(#39930): fix: trace request should show bodies from resource (#39951)
Co-authored-by: Simon Knott <info@simonknott.de>
1 parent 8423bb2 commit c23fe70

File tree

3 files changed

+44
-2
lines changed

3 files changed

+44
-2
lines changed

packages/playwright-core/src/tools/trace/traceRequests.ts

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
/* eslint-disable no-console */
1818

19+
import path from 'path';
1920
import { loadTrace } from './traceUtils';
2021
import { msToString } from '../../utils/isomorphic/formatUtils';
2122

@@ -115,8 +116,10 @@ export async function traceRequest(requestId: string) {
115116
// Request body
116117
if (r.request.postData) {
117118
console.log('\n Request body');
118-
console.log(` type: ${r.request.postData.mimeType}`);
119-
if (r.request.postData.text) {
119+
const resource = r.request.postData._sha1 ?? r.request.postData._file;
120+
if (resource) {
121+
console.log(` ${path.relative(process.cwd(), path.join(trace.model.traceUri, 'resources', resource))}`);
122+
} else {
120123
const text = r.request.postData.text.length > 2000
121124
? r.request.postData.text.substring(0, 2000) + '...'
122125
: r.request.postData.text;
@@ -131,6 +134,21 @@ export async function traceRequest(requestId: string) {
131134
console.log(` ${h.name}: ${h.value}`);
132135
}
133136

137+
// Response body
138+
if (r.response.bodySize > 0) {
139+
const resource = r.response.content._sha1 ?? r.response.content._file;
140+
if (resource) {
141+
console.log('\n Response body');
142+
console.log(` ${path.relative(process.cwd(), path.join(trace.model.traceUri, 'resources', resource))}`);
143+
} else if (r.response.content.text) {
144+
const text = r.response.content.text.length > 2000
145+
? r.response.content.text.substring(0, 2000) + '...'
146+
: r.response.content.text;
147+
console.log('\n Response body');
148+
console.log(` ${text}`);
149+
}
150+
}
151+
134152
// Security
135153
if (r._securityDetails) {
136154
console.log('\n Security');

tests/mcp/trace-cli-fixtures.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ export const test = baseTest
6161
</html>
6262
`, 'text/html');
6363

64+
server.setContent('/feedback', JSON.stringify({ received: true }), 'application/json');
65+
6466
// Navigate
6567
await page.goto(server.PREFIX);
6668

@@ -77,6 +79,9 @@ export const test = baseTest
7779
console.error('error message');
7880
});
7981

82+
// Fetch
83+
await page.evaluate(() => fetch('/feedback', { method: 'POST', body: 'What a great product!' }).then(res => res.text()));
84+
8085
// Navigate to another page
8186
await page.locator('a').click();
8287
await page.waitForURL('**/page2');

tests/mcp/trace-cli.spec.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import fs from 'fs';
1818

1919
import { test, expect } from './trace-cli-fixtures';
20+
import path from 'path';
2021

2122
test.skip(({ mcpBrowser }) => mcpBrowser !== 'chrome', 'Chrome-only');
2223

@@ -108,6 +109,24 @@ test('trace request shows details', async ({ runTraceCli }) => {
108109
expect(stdout).toContain('Response headers');
109110
});
110111

112+
test('trace request shows request and response body', async ({ traceCwd, runTraceCli }) => {
113+
const { stdout, exitCode } = await runTraceCli(['requests', '--grep', 'feedback']);
114+
expect(exitCode).toBe(0);
115+
expect(stdout).toContain('feedback');
116+
const ordinal = stdout.match(/^\s+(\d+)\.\s/m)![1];
117+
const { stdout: requestOutput, exitCode: requestExitCode } = await runTraceCli(['request', ordinal]);
118+
expect(requestExitCode).toBe(0);
119+
expect(requestOutput).toContain('Request body');
120+
const requestBodyPath = path.join('.playwright-cli', 'trace', 'resources', '60e4c013c41de11280ed8ba99dd94144124a0c35.txt');
121+
expect(requestOutput).toContain(' ' + requestBodyPath);
122+
expect(fs.readFileSync(path.join(traceCwd, requestBodyPath), 'utf-8')).toEqual('What a great product!');
123+
expect(requestOutput).toContain('Response body');
124+
expect(requestOutput).toContain('application/json');
125+
const responseBodyPath = path.join('.playwright-cli', 'trace', 'resources', '030b61c2fb7042fb4fc0ef4287a4ae3c0d98ed68.json');
126+
expect(requestOutput).toContain(' ' + responseBodyPath);
127+
expect(fs.readFileSync(path.join(traceCwd, responseBodyPath), 'utf-8')).toEqual(JSON.stringify({ received: true }));
128+
});
129+
111130
test('trace request with invalid ID', async ({ runTraceCli }) => {
112131
const { stderr, exitCode } = await runTraceCli(['request', '999999']);
113132
expect(exitCode).toBe(1);

0 commit comments

Comments
 (0)