mirror of
https://github.com/microsoft/playwright.git
synced 2025-01-07 11:46:42 +03:00
fix(chromium): race between loadingFailed and requestPaused (#10289)
This commit is contained in:
parent
119a2e8f1b
commit
6a46711347
@ -56,7 +56,7 @@ export class CRNetworkManager {
|
||||
eventsHelper.addEventListener(session, 'Network.responseReceived', this._onResponseReceived.bind(this)),
|
||||
eventsHelper.addEventListener(session, 'Network.responseReceivedExtraInfo', this._onResponseReceivedExtraInfo.bind(this)),
|
||||
eventsHelper.addEventListener(session, 'Network.loadingFinished', this._onLoadingFinished.bind(this)),
|
||||
eventsHelper.addEventListener(session, 'Network.loadingFailed', this._onLoadingFailed.bind(this)),
|
||||
eventsHelper.addEventListener(session, 'Network.loadingFailed', this._onLoadingFailed.bind(this, workerFrame)),
|
||||
eventsHelper.addEventListener(session, 'Network.webSocketCreated', e => this._page._frameManager.onWebSocketCreated(e.requestId, e.url)),
|
||||
eventsHelper.addEventListener(session, 'Network.webSocketWillSendHandshakeRequest', e => this._page._frameManager.onWebSocketRequest(e.requestId)),
|
||||
eventsHelper.addEventListener(session, 'Network.webSocketHandshakeResponseReceived', e => this._page._frameManager.onWebSocketResponse(e.requestId, e.response.status, e.response.statusText)),
|
||||
@ -368,12 +368,25 @@ export class CRNetworkManager {
|
||||
this._page._frameManager.reportRequestFinished(request.request, response);
|
||||
}
|
||||
|
||||
_onLoadingFailed(event: Protocol.Network.loadingFailedPayload) {
|
||||
_onLoadingFailed(workerFrame: frames.Frame | undefined, event: Protocol.Network.loadingFailedPayload) {
|
||||
this._responseExtraInfoTracker.loadingFailed(event);
|
||||
|
||||
let request = this._requestIdToRequest.get(event.requestId);
|
||||
if (!request)
|
||||
request = this._maybeAdoptMainRequest(event.requestId);
|
||||
|
||||
if (!request) {
|
||||
const requestWillBeSentEvent = this._requestIdToRequestWillBeSentEvent.get(event.requestId);
|
||||
if (requestWillBeSentEvent) {
|
||||
// This is a case where request has failed before we had a chance to intercept it.
|
||||
// We stop waiting for Fetch.requestPaused (it might never come), and dispatch request event
|
||||
// right away, followed by requestfailed event.
|
||||
this._requestIdToRequestWillBeSentEvent.delete(event.requestId);
|
||||
this._onRequest(workerFrame, requestWillBeSentEvent, null);
|
||||
request = this._requestIdToRequest.get(event.requestId);
|
||||
}
|
||||
}
|
||||
|
||||
// For certain requestIds we never receive requestWillBeSent event.
|
||||
// @see https://crbug.com/750469
|
||||
if (!request)
|
||||
|
@ -69,3 +69,56 @@ it('should return response body when Cross-Origin-Opener-Policy is set', async (
|
||||
expect(response.request().failure()).toBeNull();
|
||||
expect(await response.text()).toBe('Hello there!');
|
||||
});
|
||||
|
||||
it('should fire requestfailed when intercepting race', async ({ page, server, browserName }) => {
|
||||
const promsie = new Promise<void>(resolve => {
|
||||
let counter = 0;
|
||||
const failures = new Set();
|
||||
const alive = new Set();
|
||||
page.on('request', request => {
|
||||
expect(alive.has(request)).toBe(false);
|
||||
expect(failures.has(request)).toBe(false);
|
||||
alive.add(request);
|
||||
});
|
||||
page.on('requestfailed', request => {
|
||||
expect(failures.has(request)).toBe(false);
|
||||
expect(alive.has(request)).toBe(true);
|
||||
alive.delete(request);
|
||||
failures.add(request);
|
||||
if (++counter === 10)
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
|
||||
// Stall requests to make sure we don't get requestfinished.
|
||||
await page.route('**', route => {});
|
||||
|
||||
const runFunc = {
|
||||
chromium: 'abortAll()', // Fast in chromium to expose the race.
|
||||
webkit: 'setTimeout(abortAll, 0)', // Async in webkit to let it issue requests.
|
||||
firefox: 'setTimeout(abortAll, 1000)', // Slow in firefox to give it enough time to issue requests.
|
||||
}[browserName];
|
||||
|
||||
await page.setContent(`
|
||||
<iframe src="${server.EMPTY_PAGE}"></iframe>
|
||||
<iframe src="${server.EMPTY_PAGE}"></iframe>
|
||||
<iframe src="${server.EMPTY_PAGE}"></iframe>
|
||||
<iframe src="${server.EMPTY_PAGE}"></iframe>
|
||||
<iframe src="${server.EMPTY_PAGE}"></iframe>
|
||||
<iframe src="${server.EMPTY_PAGE}"></iframe>
|
||||
<iframe src="${server.EMPTY_PAGE}"></iframe>
|
||||
<iframe src="${server.EMPTY_PAGE}"></iframe>
|
||||
<iframe src="${server.EMPTY_PAGE}"></iframe>
|
||||
<iframe src="${server.EMPTY_PAGE}"></iframe>
|
||||
<script>
|
||||
function abortAll() {
|
||||
const frames = document.querySelectorAll("iframe");
|
||||
for (const frame of frames)
|
||||
frame.src = "about:blank";
|
||||
}
|
||||
${runFunc}
|
||||
</script>
|
||||
`);
|
||||
|
||||
await promsie;
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user