feat(network): introduce Request.isNavigationRequest() method (#2633)

This patch introduces `Request.isNavigationRequest()` method.

Fixes #2627, #1132.
This commit is contained in:
Andrey Lushnikov 2018-05-31 17:38:30 -07:00 committed by GitHub
parent f6356683cd
commit 724fa512cf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 61 additions and 7 deletions

View File

@ -231,6 +231,7 @@
* [request.failure()](#requestfailure)
* [request.frame()](#requestframe)
* [request.headers()](#requestheaders)
* [request.isNavigationRequest()](#requestisnavigationrequest)
* [request.method()](#requestmethod)
* [request.postData()](#requestpostdata)
* [request.redirectChain()](#requestredirectchain)
@ -2649,6 +2650,11 @@ page.on('requestfailed', request => {
#### request.headers()
- returns: <[Object]> An object with HTTP headers associated with the request. All header names are lower-case.
#### request.isNavigationRequest()
- returns: <[boolean]>
Whether this request is driving frame's navigation.
#### request.method()
- returns: <[string]> Request's method (GET, POST, etc.)

View File

@ -155,7 +155,7 @@ class NetworkManager extends EventEmitter {
const request = this._interceptionIdToRequest.get(event.interceptionId);
if (request) {
this._handleRequestRedirect(request, event.responseStatusCode, event.responseHeaders, false /* fromDiskCache */, false /* fromServiceWorker */, null /* securityDetails */);
this._handleRequestStart(request._requestId, event.interceptionId, event.redirectUrl, event.resourceType, event.request, event.frameId, request._redirectChain);
this._handleRequestStart(request._requestId, event.interceptionId, event.redirectUrl, event.isNavigationRequest, event.resourceType, event.request, event.frameId, request._redirectChain);
}
return;
}
@ -163,10 +163,10 @@ class NetworkManager extends EventEmitter {
const requestId = this._requestHashToRequestIds.firstValue(requestHash);
if (requestId) {
this._requestHashToRequestIds.delete(requestHash, requestId);
this._handleRequestStart(requestId, event.interceptionId, event.request.url, event.resourceType, event.request, event.frameId, []);
this._handleRequestStart(requestId, event.interceptionId, event.request.url, event.isNavigationRequest, event.resourceType, event.request, event.frameId, []);
} else {
this._requestHashToInterceptionIds.set(requestHash, event.interceptionId);
this._handleRequestStart(null, event.interceptionId, event.request.url, event.resourceType, event.request, event.frameId, []);
this._handleRequestStart(null, event.interceptionId, event.request.url, event.isNavigationRequest, event.resourceType, event.request, event.frameId, []);
}
}
@ -203,16 +203,17 @@ class NetworkManager extends EventEmitter {
* @param {?string} requestId
* @param {?string} interceptionId
* @param {string} url
* @param {boolean} isNavigationRequest
* @param {string} resourceType
* @param {!Protocol.Network.Request} requestPayload
* @param {?string} frameId
* @param {!Array<!Request>} redirectChain
*/
_handleRequestStart(requestId, interceptionId, url, resourceType, requestPayload, frameId, redirectChain) {
_handleRequestStart(requestId, interceptionId, url, isNavigationRequest, resourceType, requestPayload, frameId, redirectChain) {
let frame = null;
if (frameId)
frame = this._frameManager.frame(frameId);
const request = new Request(this._client, requestId, interceptionId, this._userRequestInterceptionEnabled, url, resourceType, requestPayload, frame, redirectChain);
const request = new Request(this._client, requestId, interceptionId, isNavigationRequest, this._userRequestInterceptionEnabled, url, resourceType, requestPayload, frame, redirectChain);
if (requestId)
this._requestIdToRequest.set(requestId, request);
if (interceptionId)
@ -249,7 +250,8 @@ class NetworkManager extends EventEmitter {
redirectChain = request._redirectChain;
}
}
this._handleRequestStart(event.requestId, null, event.request.url, event.type, event.request, event.frameId, redirectChain);
const isNavigationRequest = event.requestId === event.loaderId && event.type === 'Document';
this._handleRequestStart(event.requestId, null, event.request.url, isNavigationRequest, event.type, event.request, event.frameId, redirectChain);
}
/**
@ -307,6 +309,7 @@ class Request {
* @param {!Puppeteer.CDPSession} client
* @param {?string} requestId
* @param {string} interceptionId
* @param {boolean} isNavigationRequest
* @param {boolean} allowInterception
* @param {string} url
* @param {string} resourceType
@ -314,9 +317,10 @@ class Request {
* @param {?Puppeteer.Frame} frame
* @param {!Array<!Request>} redirectChain
*/
constructor(client, requestId, interceptionId, allowInterception, url, resourceType, payload, frame, redirectChain) {
constructor(client, requestId, interceptionId, isNavigationRequest, allowInterception, url, resourceType, payload, frame, redirectChain) {
this._client = client;
this._requestId = requestId;
this._isNavigationRequest = isNavigationRequest;
this._interceptionId = interceptionId;
this._allowInterception = allowInterception;
this._interceptionHandled = false;
@ -385,6 +389,13 @@ class Request {
return this._frame;
}
/**
* @return {boolean}
*/
isNavigationRequest() {
return this._isNavigationRequest;
}
/**
* @return {!Array<!Request>}
*/

View File

@ -199,6 +199,41 @@ module.exports.addTests = function({testRunner, expect}) {
});
});
describe('Request.isNavigationRequest', () => {
it('should work', async({page, server}) => {
const requests = new Map();
page.on('request', request => requests.set(request.url().split('/').pop(), request));
server.setRedirect('/rrredirect', '/frames/one-frame.html');
await page.goto(server.PREFIX + '/rrredirect');
expect(requests.get('rrredirect').isNavigationRequest()).toBe(true);
expect(requests.get('one-frame.html').isNavigationRequest()).toBe(true);
expect(requests.get('frame.html').isNavigationRequest()).toBe(true);
expect(requests.get('script.js').isNavigationRequest()).toBe(false);
expect(requests.get('style.css').isNavigationRequest()).toBe(false);
});
it('should work with request interception', async({page, server}) => {
const requests = new Map();
page.on('request', request => {
requests.set(request.url().split('/').pop(), request);
request.continue();
});
await page.setRequestInterception(true);
server.setRedirect('/rrredirect', '/frames/one-frame.html');
await page.goto(server.PREFIX + '/rrredirect');
expect(requests.get('rrredirect').isNavigationRequest()).toBe(true);
expect(requests.get('one-frame.html').isNavigationRequest()).toBe(true);
expect(requests.get('frame.html').isNavigationRequest()).toBe(true);
expect(requests.get('script.js').isNavigationRequest()).toBe(false);
expect(requests.get('style.css').isNavigationRequest()).toBe(false);
});
it('should work when navigating to image', async({page, server}) => {
const requests = [];
page.on('request', request => requests.push(request));
await page.goto(server.PREFIX + '/pptr.png');
expect(requests[0].isNavigationRequest()).toBe(true);
});
});
describe('Page.setRequestInterception', function() {
it('should intercept', async({page, server}) => {
await page.setRequestInterception(true);
@ -207,6 +242,7 @@ module.exports.addTests = function({testRunner, expect}) {
expect(request.headers()['user-agent']).toBeTruthy();
expect(request.method()).toBe('GET');
expect(request.postData()).toBe(undefined);
expect(request.isNavigationRequest()).toBe(true);
expect(request.resourceType()).toBe('document');
expect(request.frame() === page.mainFrame()).toBe(true);
expect(request.frame().url()).toBe('about:blank');
@ -327,6 +363,7 @@ module.exports.addTests = function({testRunner, expect}) {
expect(redirectChain[2].url()).toContain('/non-existing-page-3.html');
for (let i = 0; i < redirectChain.length; ++i) {
const request = redirectChain[i];
expect(request.isNavigationRequest()).toBe(true);
expect(request.redirectChain().indexOf(request)).toBe(i);
}
});