fix: continue requests without network instrumentation (#10046)

This commit is contained in:
Alex Rudenko 2023-04-20 14:28:56 +02:00 committed by GitHub
parent 57c5727424
commit 8283823cb8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 79 additions and 16 deletions

View File

@ -10,10 +10,10 @@ The initiator of the request.
```typescript ```typescript
class HTTPRequest { class HTTPRequest {
initiator(): Protocol.Network.Initiator; initiator(): Protocol.Network.Initiator | undefined;
} }
``` ```
**Returns:** **Returns:**
Protocol.Network.Initiator Protocol.Network.Initiator \| undefined

View File

@ -197,8 +197,8 @@ version of Chrome or Chromium, pass in the executable's path when creating a
const browser = await puppeteer.launch({executablePath: '/path/to/Chrome'}); const browser = await puppeteer.launch({executablePath: '/path/to/Chrome'});
``` ```
You can also use Puppeteer with Firefox Nightly (experimental support). See You can also use Puppeteer with Firefox. See
[`Puppeteer.launch`](https://pptr.dev/api/puppeteer.puppeteernode.launch) for [status of cross-browser support](https://pptr.dev/faq/#q-what-is-the-status-of-cross-browser-support) for
more information. more information.
See See

View File

@ -272,7 +272,7 @@ export class HTTPRequest {
/** /**
* The initiator of the request. * The initiator of the request.
*/ */
initiator(): Protocol.Network.Initiator { initiator(): Protocol.Network.Initiator | undefined {
throw new Error('Not implemented'); throw new Error('Not implemented');
} }

View File

@ -63,7 +63,7 @@ export class HTTPRequest extends BaseHTTPRequest {
action: InterceptResolutionAction.None, action: InterceptResolutionAction.None,
}; };
#interceptHandlers: Array<() => void | PromiseLike<any>>; #interceptHandlers: Array<() => void | PromiseLike<any>>;
#initiator: Protocol.Network.Initiator; #initiator?: Protocol.Network.Initiator;
override get client(): CDPSession { override get client(): CDPSession {
return this.#client; return this.#client;
@ -74,27 +74,52 @@ export class HTTPRequest extends BaseHTTPRequest {
frame: Frame | null, frame: Frame | null,
interceptionId: string | undefined, interceptionId: string | undefined,
allowInterception: boolean, allowInterception: boolean,
event: Protocol.Network.RequestWillBeSentEvent, data: {
/**
* Request identifier.
*/
requestId: Protocol.Network.RequestId;
/**
* Loader identifier. Empty string if the request is fetched from worker.
*/
loaderId?: Protocol.Network.LoaderId;
/**
* URL of the document this request is loaded for.
*/
documentURL?: string;
/**
* Request data.
*/
request: Protocol.Network.Request;
/**
* Request initiator.
*/
initiator?: Protocol.Network.Initiator;
/**
* Type of this resource.
*/
type?: Protocol.Network.ResourceType;
},
redirectChain: HTTPRequest[] redirectChain: HTTPRequest[]
) { ) {
super(); super();
this.#client = client; this.#client = client;
this._requestId = event.requestId; this._requestId = data.requestId;
this.#isNavigationRequest = this.#isNavigationRequest =
event.requestId === event.loaderId && event.type === 'Document'; data.requestId === data.loaderId && data.type === 'Document';
this._interceptionId = interceptionId; this._interceptionId = interceptionId;
this.#allowInterception = allowInterception; this.#allowInterception = allowInterception;
this.#url = event.request.url; this.#url = data.request.url;
this.#resourceType = (event.type || 'other').toLowerCase() as ResourceType; this.#resourceType = (data.type || 'other').toLowerCase() as ResourceType;
this.#method = event.request.method; this.#method = data.request.method;
this.#postData = event.request.postData; this.#postData = data.request.postData;
this.#frame = frame; this.#frame = frame;
this._redirectChain = redirectChain; this._redirectChain = redirectChain;
this.#continueRequestOverrides = {}; this.#continueRequestOverrides = {};
this.#interceptHandlers = []; this.#interceptHandlers = [];
this.#initiator = event.initiator; this.#initiator = data.initiator;
for (const [key, value] of Object.entries(event.request.headers)) { for (const [key, value] of Object.entries(data.request.headers)) {
this.#headers[key.toLowerCase()] = value; this.#headers[key.toLowerCase()] = value;
} }
} }
@ -184,7 +209,7 @@ export class HTTPRequest extends BaseHTTPRequest {
return this.#isNavigationRequest; return this.#isNavigationRequest;
} }
override initiator(): Protocol.Network.Initiator { override initiator(): Protocol.Network.Initiator | undefined {
return this.#initiator; return this.#initiator;
} }

View File

@ -336,6 +336,7 @@ export class NetworkManager extends EventEmitter {
const {networkId: networkRequestId, requestId: fetchRequestId} = event; const {networkId: networkRequestId, requestId: fetchRequestId} = event;
if (!networkRequestId) { if (!networkRequestId) {
this.#onRequestWithoutNetworkInstrumentation(event);
return; return;
} }
@ -374,6 +375,27 @@ export class NetworkManager extends EventEmitter {
}; };
} }
#onRequestWithoutNetworkInstrumentation(
event: Protocol.Fetch.RequestPausedEvent
): void {
// If an event has no networkId it should not have any network events. We
// still want to dispatch it for the interception by the user.
const frame = event.frameId
? this.#frameManager.frame(event.frameId)
: null;
const request = new HTTPRequest(
this.#client,
frame,
event.requestId,
this.#userRequestInterceptionEnabled,
event,
[]
);
this.emit(NetworkManagerEmittedEvents.Request, request);
request.finalizeInterceptions();
}
#onRequest( #onRequest(
event: Protocol.Network.RequestWillBeSentEvent, event: Protocol.Network.RequestWillBeSentEvent,
fetchRequestId?: FetchRequestId fetchRequestId?: FetchRequestId

View File

@ -127,6 +127,22 @@ describe('request interception', function () {
expect(requests[1]!.url()).toContain('/one-style.css'); expect(requests[1]!.url()).toContain('/one-style.css');
expect(requests[1]!.headers()['referer']).toContain('/one-style.html'); expect(requests[1]!.headers()['referer']).toContain('/one-style.html');
}); });
it('should work with requests without networkId', async () => {
const {page, server} = getTestState();
await page.goto(server.EMPTY_PAGE);
await page.setRequestInterception(true);
const cdp = await page.target().createCDPSession();
await cdp.send('DOM.enable');
const urls: string[] = [];
page.on('request', request => {
urls.push(request.url());
return request.continue();
});
// This causes network requests without networkId.
await cdp.send('CSS.enable');
expect(urls).toStrictEqual([server.EMPTY_PAGE]);
});
it('should properly return navigation response when URL has cookies', async () => { it('should properly return navigation response when URL has cookies', async () => {
const {page, server} = getTestState(); const {page, server} = getTestState();