fix(trace): include method into "Fetch" action title (#36350)

This commit is contained in:
Dmitry Gozman 2025-06-18 13:59:09 +01:00 committed by GitHub
parent 2973b0b0c0
commit f050c3fc61
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 28 additions and 25 deletions

View File

@ -17,7 +17,7 @@
// This file is generated by generate_channels.js, do not edit manually.
export const methodMetainfo = new Map<string, { internal?: boolean, title?: string, slowMo?: boolean, snapshot?: boolean, pausesBeforeInput?: boolean }>([
['APIRequestContext.fetch', { title: 'Fetch "{url}"', }],
['APIRequestContext.fetch', { title: '{method} "{url}"', }],
['APIRequestContext.fetchResponseBody', { internal: true, }],
['APIRequestContext.fetchLog', { internal: true, }],
['APIRequestContext.storageState', { internal: true, }],

View File

@ -366,7 +366,7 @@ APIRequestContext:
commands:
fetch:
title: Fetch "{url}"
title: '{method} "{url}"'
parameters:
url: string
encodedParams: string?

View File

@ -164,6 +164,9 @@ export function renderTitleForCall(action: ActionTraceEvent): { elements: React.
title.push(chunk);
const param = formatProtocolParam(action.params, quotedText);
if (match.index === 0)
elements.push(param);
else
elements.push(<span className='action-title-param'>{param}</span>);
title.push(param);
currentIndex = match.index + fullMatch.length;

View File

@ -1056,16 +1056,16 @@ test('should open two trace files', async ({ context, page, request, server, sho
const traceViewer = await showTraceViewer([contextTrace, apiTrace]);
await traceViewer.selectAction('FETCH', 0);
await traceViewer.selectAction('FETCH', 1);
await traceViewer.selectAction('FETCH', 2);
await traceViewer.selectAction('GET');
await traceViewer.selectAction('HEAD');
await traceViewer.selectAction('POST');
await expect(traceViewer.actionTitles).toHaveText([
/Fetch "\/simple\.json"/,
/GET "\/simple\.json"/,
/Navigate to "\/input\/button\.html"/,
/Fetch "\/simplezip\.json"/,
/HEAD "\/simplezip\.json"/,
/Click.*locator\('button'\)/,
/Click.*locator\('button'\)/,
/Fetch "\/one-style\.css"/,
/POST "\/one-style\.css"/,
]);
await traceViewer.page.getByRole('tab', { name: 'Metadata' }).click();

View File

@ -165,7 +165,7 @@ test('should include context API requests', async ({ context, page, server }, te
await page.request.post(server.PREFIX + '/simple.json', { data: { foo: 'bar' } });
await context.tracing.stop({ path: testInfo.outputPath('trace.zip') });
const { events, actions } = await parseTraceRaw(testInfo.outputPath('trace.zip'));
expect(actions).toContain('Fetch "/simple.json"');
expect(actions).toContain('POST "/simple.json"');
const harEntry = events.find(e => e.type === 'resource-snapshot');
expect(harEntry).toBeTruthy();
expect(harEntry.snapshot.request.url).toBe(server.PREFIX + '/simple.json');

View File

@ -98,7 +98,7 @@ test('should record api trace', async ({ runInlineTest, server }, testInfo) => {
' Fixture "page"',
' Create page',
'Navigate to "about:blank"',
'Fetch "/empty.html"',
'GET "/empty.html"',
'After Hooks',
' Fixture "page"',
' Fixture "context"',
@ -108,7 +108,7 @@ test('should record api trace', async ({ runInlineTest, server }, testInfo) => {
expect(trace2.actionTree).toEqual([
'Before Hooks',
'Create request context',
'Fetch "/empty.html"',
'GET "/empty.html"',
'After Hooks',
]);
const trace3 = await parseTrace(testInfo.outputPath('test-results', 'a-fail', 'trace.zip'));
@ -121,7 +121,7 @@ test('should record api trace', async ({ runInlineTest, server }, testInfo) => {
' Fixture "page"',
' Create page',
'Navigate to "about:blank"',
'Fetch "/empty.html"',
'GET "/empty.html"',
'Expect "toBe"',
'After Hooks',
' Fixture "page"',
@ -328,7 +328,7 @@ test('should not override trace file in afterAll', async ({ runInlineTest, serve
' afterAll hook',
' Fixture "request"',
' Create request context',
' Fetch "/empty.html"',
' GET "/empty.html"',
' Fixture "request"',
'Worker Cleanup',
' Fixture "browser"',
@ -488,7 +488,7 @@ test(`trace:retain-on-failure should create trace if request context is disposed
}, { trace: 'retain-on-failure' });
const tracePath = test.info().outputPath('test-results', 'a-passing-test', 'trace.zip');
const trace = await parseTrace(tracePath);
expect(trace.titles).toContain('Fetch "/empty.html"');
expect(trace.titles).toContain('GET "/empty.html"');
expect(result.failed).toBe(1);
});
@ -1137,7 +1137,7 @@ test('trace:retain-on-first-failure should create trace if request context is di
}, { trace: 'retain-on-first-failure' });
const tracePath = test.info().outputPath('test-results', 'a-fail', 'trace.zip');
const trace = await parseTrace(tracePath);
expect(trace.titles).toContain('Fetch "/empty.html"');
expect(trace.titles).toContain('GET "/empty.html"');
expect(result.failed).toBe(1);
});
@ -1243,7 +1243,7 @@ test('should not nest top level expect into unfinished api calls ', {
' Fixture "page"',
' Create page',
'Navigate to "/index"',
'Fetch "/hang"',
'GET "/hang"',
'Expect "toBeVisible"',
'After Hooks',
' Fixture "page"',

View File

@ -637,7 +637,7 @@ for (const useIntermediateMergeReport of [true, false] as const) {
await page.click('text=Source');
await expect(page.locator('.source-line-running')).toContainText('page.evaluate');
await page.click('.action-title >> text=FETCH');
await page.click('.action-title >> text=GET');
await page.click('text=Source');
await expect(page.locator('.source-line-running')).toContainText('request.get');
});
@ -668,10 +668,10 @@ for (const useIntermediateMergeReport of [true, false] as const) {
await page.getByRole('link', { name: 'View Trace' }).click();
// Trace viewer should not hang here when displaying parallal requests.
await expect(page.getByTestId('actions-tree')).toContainText('Fetch');
await page.getByText('Fetch').nth(2).click();
await page.getByText('Fetch').nth(1).click();
await page.getByText('Fetch').nth(0).click();
await expect(page.getByTestId('actions-tree')).toContainText('GET');
await page.getByText('GET').nth(2).click();
await page.getByText('GET').nth(1).click();
await page.getByText('GET').nth(0).click();
});
test('should warn user when viewing via file:// protocol', async ({ runInlineTest, page, showReport }, testInfo) => {

View File

@ -1222,9 +1222,9 @@ pw:api |Wait for navigation @ a.test.ts:5
pw:api |Navigate to "data:" @ a.test.ts:6
pw:api |Click locator('button') @ a.test.ts:8
pw:api |Click getByRole('button') @ a.test.ts:9
pw:api |Fetch "/empty.html" @ a.test.ts:10
pw:api |GET "/empty.html" @ a.test.ts:10
pw:api | error: <error message>
pw:api |Fetch "/empty.html" @ a.test.ts:11
pw:api |GET "/empty.html" @ a.test.ts:11
pw:api | error: <error message>
hook |After Hooks
fixture | request
@ -1519,7 +1519,7 @@ fixture | page
pw:api | Create page
test.step |custom step @ a.test.ts:4
pw:api | Navigate to "/empty.html" @ a.test.ts:12
pw:api | Fetch "/empty.html" @ a.test.ts:6
pw:api | GET "/empty.html" @ a.test.ts:6
expect | toBe @ a.test.ts:8
hook |After Hooks
fixture | page