fix(har): do not hang on cached resources (#11556)

This commit is contained in:
Yury Semikhatsky 2022-01-21 16:31:00 -08:00 committed by GitHub
parent 066b6734d0
commit 295d0a65c3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 37 additions and 4 deletions

View file

@ -53,6 +53,7 @@ export class CRNetworkManager {
eventsHelper.addEventListener(session, 'Fetch.authRequired', this._onAuthRequired.bind(this)), eventsHelper.addEventListener(session, 'Fetch.authRequired', this._onAuthRequired.bind(this)),
eventsHelper.addEventListener(session, 'Network.requestWillBeSent', this._onRequestWillBeSent.bind(this, workerFrame)), eventsHelper.addEventListener(session, 'Network.requestWillBeSent', this._onRequestWillBeSent.bind(this, workerFrame)),
eventsHelper.addEventListener(session, 'Network.requestWillBeSentExtraInfo', this._onRequestWillBeSentExtraInfo.bind(this)), eventsHelper.addEventListener(session, 'Network.requestWillBeSentExtraInfo', this._onRequestWillBeSentExtraInfo.bind(this)),
eventsHelper.addEventListener(session, 'Network.requestServedFromCache', this._onRequestServedFromCache.bind(this)),
eventsHelper.addEventListener(session, 'Network.responseReceived', this._onResponseReceived.bind(this)), eventsHelper.addEventListener(session, 'Network.responseReceived', this._onResponseReceived.bind(this)),
eventsHelper.addEventListener(session, 'Network.responseReceivedExtraInfo', this._onResponseReceivedExtraInfo.bind(this)), eventsHelper.addEventListener(session, 'Network.responseReceivedExtraInfo', this._onResponseReceivedExtraInfo.bind(this)),
eventsHelper.addEventListener(session, 'Network.loadingFinished', this._onLoadingFinished.bind(this)), eventsHelper.addEventListener(session, 'Network.loadingFinished', this._onLoadingFinished.bind(this)),
@ -134,6 +135,10 @@ export class CRNetworkManager {
} }
} }
_onRequestServedFromCache(event: Protocol.Network.requestServedFromCachePayload) {
this._responseExtraInfoTracker.requestServedFromCache(event);
}
_onRequestWillBeSentExtraInfo(event: Protocol.Network.requestWillBeSentExtraInfoPayload) { _onRequestWillBeSentExtraInfo(event: Protocol.Network.requestWillBeSentExtraInfoPayload) {
this._responseExtraInfoTracker.requestWillBeSentExtraInfo(event); this._responseExtraInfoTracker.requestWillBeSentExtraInfo(event);
} }
@ -556,6 +561,7 @@ type RequestInfo = {
loadingFinished?: Protocol.Network.loadingFinishedPayload, loadingFinished?: Protocol.Network.loadingFinishedPayload,
loadingFailed?: Protocol.Network.loadingFailedPayload, loadingFailed?: Protocol.Network.loadingFailedPayload,
sawResponseWithoutConnectionId: boolean sawResponseWithoutConnectionId: boolean
requestServedFromCache: boolean;
}; };
// This class aligns responses with response headers from extra info: // This class aligns responses with response headers from extra info:
@ -585,12 +591,15 @@ class ResponseExtraInfoTracker {
requestWillBeSentExtraInfo(event: Protocol.Network.requestWillBeSentExtraInfoPayload) { requestWillBeSentExtraInfo(event: Protocol.Network.requestWillBeSentExtraInfoPayload) {
const info = this._getOrCreateEntry(event.requestId); const info = this._getOrCreateEntry(event.requestId);
if (!info)
return;
info.requestWillBeSentExtraInfo.push(event); info.requestWillBeSentExtraInfo.push(event);
this._patchHeaders(info, info.requestWillBeSentExtraInfo.length - 1); this._patchHeaders(info, info.requestWillBeSentExtraInfo.length - 1);
} }
requestServedFromCache(event: Protocol.Network.requestServedFromCachePayload) {
const info = this._getOrCreateEntry(event.requestId);
info.requestServedFromCache = true;
}
responseReceived(event: Protocol.Network.responseReceivedPayload) { responseReceived(event: Protocol.Network.responseReceivedPayload) {
const info = this._requests.get(event.requestId); const info = this._requests.get(event.requestId);
if (!info) if (!info)
@ -630,7 +639,8 @@ class ResponseExtraInfoTracker {
const info = this._requests.get(requestId); const info = this._requests.get(requestId);
if (!info || info.sawResponseWithoutConnectionId) if (!info || info.sawResponseWithoutConnectionId)
return; return;
response.setWillReceiveExtraHeaders(); if (!info.requestServedFromCache)
response.setWillReceiveExtraHeaders();
info.responses.push(response); info.responses.push(response);
this._patchHeaders(info, info.responses.length - 1); this._patchHeaders(info, info.responses.length - 1);
} }
@ -659,7 +669,8 @@ class ResponseExtraInfoTracker {
requestWillBeSentExtraInfo: [], requestWillBeSentExtraInfo: [],
responseReceivedExtraInfo: [], responseReceivedExtraInfo: [],
responses: [], responses: [],
sawResponseWithoutConnectionId: false sawResponseWithoutConnectionId: false,
requestServedFromCache: false
}; };
this._requests.set(requestId, info); this._requests.set(requestId, info);
} }

View file

@ -134,6 +134,7 @@ export class HarTracer {
promise promise
]) as Promise<void>; ]) as Promise<void>;
this._barrierPromises.add(race); this._barrierPromises.add(race);
race.then(() => this._barrierPromises.delete(race));
} }
private _onAPIRequest(event: APIRequestEvent) { private _onAPIRequest(event: APIRequestEvent) {

View file

@ -674,3 +674,24 @@ it('should include API request', async ({ contextFactory, server }, testInfo) =>
expect(entry.response.content.text).toBe(responseBody.toString('base64')); expect(entry.response.content.text).toBe(responseBody.toString('base64'));
}); });
it('should not hang on resources served from cache', async ({ contextFactory, server, browserName }, testInfo) => {
it.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/11435' });
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 { page, getLog } = await pageWithHar(contextFactory, testInfo);
await page.goto(server.PREFIX + '/har.html');
await page.goto(server.PREFIX + '/har.html');
const log = await getLog();
const entries = log.entries.filter(e => e.request.url.endsWith('one-style.css'));
// In firefox no request events are fired for cached resources.
if (browserName === 'firefox')
expect(entries.length).toBe(1);
else
expect(entries.length).toBe(2);
});