fix(trace): ensure har entry _monotonicTime is always start time (#31385)

* Revert harTracer change from
aeba083da0
to make sure that har.Entry._monotonicTime always represents request
start time. The issue from the corresponding report was due to HEAD and
GET request sent for the same URL, that use case is still addressed as
we match by url + method
* Adjust resources monotonic time as well when several contexts are
shown in the trace viewer.

Fixes https://github.com/microsoft/playwright/issues/31133
This commit is contained in:
Yury Semikhatsky 2024-06-19 15:06:20 -07:00 committed by GitHub
parent 94f0cadea3
commit a2b116aa39
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 39 additions and 6 deletions

View File

@ -434,12 +434,6 @@ export class HarTracer {
const pageEntry = this._createPageEntryIfNeeded(page);
const request = response.request();
// Prefer "response received" time over "request sent" time
// for the purpose of matching requests that were used in a particular snapshot.
// Note that both snapshot time and request time are taken here in the Node process.
if (this._options.includeTraceInfo)
harEntry._monotonicTime = monotonicTime();
harEntry.response = {
status: response.status(),
statusText: response.statusText(),

View File

@ -285,6 +285,10 @@ function adjustMonotonicTime(contexts: ContextEntry[], monotonicTimeDelta: numbe
for (const frame of page.screencastFrames)
frame.timestamp += monotonicTimeDelta;
}
for (const resource of context.resources) {
if (resource._monotonicTime)
resource._monotonicTime += monotonicTimeDelta;
}
}
}

View File

@ -1236,3 +1236,38 @@ test('should open snapshot in new browser context', async ({ browser, page, runA
await expect(newPage.getByText('hello')).toBeVisible();
await newPage.close();
});
function parseMillis(s: string): number {
const matchMs = s.match(/(\d+)ms/);
if (matchMs)
return +matchMs[1];
const matchSeconds = s.match(/([\d.]+)s/);
if (!matchSeconds)
throw new Error('Failed to parse to millis: ' + s);
return (+matchSeconds[1]) * 1000;
}
test('should show correct request start time', {
annotation: { type: 'issue', description: 'https://github.com/microsoft/playwright/issues/31133' },
}, async ({ page, runAndTrace, server }) => {
server.setRoute('/api', (req, res) => {
setTimeout(() => {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('done');
}, 1100);
});
const traceViewer = await runAndTrace(async () => {
await page.goto(server.EMPTY_PAGE);
await page.evaluate(() => {
return fetch('/api').then(r => r.text());
});
});
await traceViewer.selectAction('page.evaluate');
await traceViewer.showNetworkTab();
await expect(traceViewer.networkRequests).toContainText([/apiGET200text/]);
const line = traceViewer.networkRequests.getByText(/apiGET200text/);
const start = await line.locator('.grid-view-column-start').textContent();
const duration = await line.locator('.grid-view-column-duration').textContent();
expect(parseMillis(duration)).toBeGreaterThan(1000);
expect(parseMillis(start)).toBeLessThan(1000);
});