mirror of
https://github.com/microsoft/playwright.git
synced 2025-06-26 21:40:17 +00:00
fix: ignore timing data when request served from memory cache (#17595)
`Response.timing` contains stale data when the request is served from memory cache, in that we should ignore it and return -1 where we don't know the value. Fixes https://github.com/microsoft/playwright-java/issues/1080
This commit is contained in:
parent
b9e126b3e6
commit
72a24973f3
@ -126,8 +126,7 @@ export class BrowserContext extends ChannelOwner<channels.BrowserContextChannel>
|
|||||||
|
|
||||||
private _onRequestFailed(request: network.Request, responseEndTiming: number, failureText: string | undefined, page: Page | null) {
|
private _onRequestFailed(request: network.Request, responseEndTiming: number, failureText: string | undefined, page: Page | null) {
|
||||||
request._failureText = failureText || null;
|
request._failureText = failureText || null;
|
||||||
if (request._timing)
|
request._setResponseEndTiming(responseEndTiming);
|
||||||
request._timing.responseEnd = responseEndTiming;
|
|
||||||
this.emit(Events.BrowserContext.RequestFailed, request);
|
this.emit(Events.BrowserContext.RequestFailed, request);
|
||||||
if (page)
|
if (page)
|
||||||
page.emit(Events.Page.RequestFailed, request);
|
page.emit(Events.Page.RequestFailed, request);
|
||||||
@ -138,8 +137,7 @@ export class BrowserContext extends ChannelOwner<channels.BrowserContextChannel>
|
|||||||
const request = network.Request.from(params.request);
|
const request = network.Request.from(params.request);
|
||||||
const response = network.Response.fromNullable(params.response);
|
const response = network.Response.fromNullable(params.response);
|
||||||
const page = Page.fromNullable(params.page);
|
const page = Page.fromNullable(params.page);
|
||||||
if (request._timing)
|
request._setResponseEndTiming(responseEndTiming);
|
||||||
request._timing.responseEnd = responseEndTiming;
|
|
||||||
this.emit(Events.BrowserContext.RequestFinished, request);
|
this.emit(Events.BrowserContext.RequestFinished, request);
|
||||||
if (page)
|
if (page)
|
||||||
page.emit(Events.Page.RequestFinished, request);
|
page.emit(Events.Page.RequestFinished, request);
|
||||||
|
|||||||
@ -240,6 +240,12 @@ export class Request extends ChannelOwner<channels.RequestChannel> implements ap
|
|||||||
return (await response._channel.sizes()).sizes;
|
return (await response._channel.sizes()).sizes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_setResponseEndTiming(responseEndTiming: number) {
|
||||||
|
this._timing.responseEnd = responseEndTiming;
|
||||||
|
if (this._timing.responseStart === -1)
|
||||||
|
this._timing.responseStart = responseEndTiming;
|
||||||
|
}
|
||||||
|
|
||||||
_finalRequest(): Request {
|
_finalRequest(): Request {
|
||||||
return this._redirectedTo ? this._redirectedTo._finalRequest() : this;
|
return this._redirectedTo ? this._redirectedTo._finalRequest() : this;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -303,7 +303,7 @@ export class CRNetworkManager {
|
|||||||
};
|
};
|
||||||
const timingPayload = responsePayload.timing!;
|
const timingPayload = responsePayload.timing!;
|
||||||
let timing: network.ResourceTiming;
|
let timing: network.ResourceTiming;
|
||||||
if (timingPayload) {
|
if (timingPayload && !this._responseExtraInfoTracker.servedFromCache(request._requestId)) {
|
||||||
timing = {
|
timing = {
|
||||||
startTime: (timingPayload.requestTime - request._timestamp + request._wallTime) * 1000,
|
startTime: (timingPayload.requestTime - request._timestamp + request._wallTime) * 1000,
|
||||||
domainLookupStart: timingPayload.dnsStart,
|
domainLookupStart: timingPayload.dnsStart,
|
||||||
@ -638,6 +638,11 @@ class ResponseExtraInfoTracker {
|
|||||||
info.servedFromCache = true;
|
info.servedFromCache = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
servedFromCache(requestId: string): boolean {
|
||||||
|
const info = this._requests.get(requestId);
|
||||||
|
return !!info?.servedFromCache;
|
||||||
|
}
|
||||||
|
|
||||||
responseReceivedExtraInfo(event: Protocol.Network.responseReceivedExtraInfoPayload) {
|
responseReceivedExtraInfo(event: Protocol.Network.responseReceivedExtraInfoPayload) {
|
||||||
const info = this._getOrCreateEntry(event.requestId);
|
const info = this._getOrCreateEntry(event.requestId);
|
||||||
info.responseReceivedExtraInfo.push(event);
|
info.responseReceivedExtraInfo.push(event);
|
||||||
|
|||||||
@ -415,6 +415,9 @@ export class Response extends SdkObject {
|
|||||||
|
|
||||||
_requestFinished(responseEndTiming: number) {
|
_requestFinished(responseEndTiming: number) {
|
||||||
this._request._responseEndTiming = Math.max(responseEndTiming, this._timing.responseStart);
|
this._request._responseEndTiming = Math.max(responseEndTiming, this._timing.responseStart);
|
||||||
|
// Set start time equal to end when request is served from memory cache.
|
||||||
|
if (this._timing.requestStart === -1)
|
||||||
|
this._timing.requestStart = this._request._responseEndTiming;
|
||||||
this._finishedPromise.resolve();
|
this._finishedPromise.resolve();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -96,6 +96,34 @@ it('should work for redirect', async ({ contextFactory, browserName, server }) =
|
|||||||
await context.close();
|
await context.close();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should work when serving from memory cache', async ({ contextFactory, server, browserName }) => {
|
||||||
|
it.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright-java/issues/1080' });
|
||||||
|
it.fixme(browserName === 'firefox', 'Response event is not fired in Firefox');
|
||||||
|
server.setRoute('/one-style.css', (req, res) => {
|
||||||
|
res.writeHead(200, {
|
||||||
|
'Content-Type': 'text/css',
|
||||||
|
'Cache-Control': 'public, max-age=10031518'
|
||||||
|
});
|
||||||
|
res.end(`body { background: red }`);
|
||||||
|
});
|
||||||
|
|
||||||
|
const context = await contextFactory();
|
||||||
|
const page = await context.newPage();
|
||||||
|
await page.goto(server.PREFIX + '/one-style.html');
|
||||||
|
const [response] = await Promise.all([
|
||||||
|
page.waitForResponse('**/one-style.css'),
|
||||||
|
page.reload()
|
||||||
|
]);
|
||||||
|
await response.finished();
|
||||||
|
|
||||||
|
const timing = response.request().timing();
|
||||||
|
verifyConnectionTimingConsistency(timing);
|
||||||
|
|
||||||
|
expect(timing.responseStart).toBe(timing.responseEnd);
|
||||||
|
expect(timing.responseEnd).toBeLessThan(1000);
|
||||||
|
await context.close();
|
||||||
|
});
|
||||||
|
|
||||||
function verifyTimingValue(value: number, previous: number) {
|
function verifyTimingValue(value: number, previous: number) {
|
||||||
expect(value === -1 || value > 0 && value >= previous);
|
expect(value === -1 || value > 0 && value >= previous);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user