feat(route): support URL overrides in continue (#4438)

This commit is contained in:
Yury Semikhatsky 2020-11-16 09:59:00 -08:00 коммит произвёл GitHub
Родитель dd3d49339d
Коммит dfe3552b59
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
14 изменённых файлов: 56 добавлений и 2 удалений

Просмотреть файл

@ -8,7 +8,7 @@
},
{
"name": "firefox",
"revision": "1206",
"revision": "1208",
"download": true
},
{

Просмотреть файл

@ -4159,6 +4159,7 @@ Aborts the route's request.
#### route.continue([overrides])
- `overrides` <[Object]> Optional request overrides, can override following properties:
- `url` <[string]> If set changes the request URL. New URL must have same protocol as original one.
- `method` <[string]> If set changes the request method (e.g. GET or POST)
- `postData` <[string]|[Buffer]> If set changes the post data of request
- `headers` <[Object]<[string], [string]>> If set changes the request HTTP headers. Header values will be converted to a string.

Просмотреть файл

@ -221,9 +221,10 @@ export class Route extends ChannelOwner<channels.RouteChannel, channels.RouteIni
});
}
async continue(overrides: { method?: string, headers?: Headers, postData?: string | Buffer } = {}) {
async continue(overrides: { url?: string, method?: string, headers?: Headers, postData?: string | Buffer } = {}) {
const postDataBuffer = isString(overrides.postData) ? Buffer.from(overrides.postData, 'utf8') : overrides.postData;
await this._channel.continue({
url: overrides.url,
method: overrides.method,
headers: overrides.headers ? headersObjectToArray(overrides.headers) : undefined,
postData: postDataBuffer ? postDataBuffer.toString('base64') : undefined,

Просмотреть файл

@ -84,6 +84,7 @@ export class RouteDispatcher extends Dispatcher<Route, channels.RouteInitializer
async continue(params: channels.RouteContinueParams): Promise<void> {
await this._object.continue({
url: params.url,
method: params.method,
headers: params.headers,
postData: params.postData ? Buffer.from(params.postData, 'base64') : undefined,

Просмотреть файл

@ -2139,11 +2139,13 @@ export type RouteAbortOptions = {
};
export type RouteAbortResult = void;
export type RouteContinueParams = {
url?: string,
method?: string,
headers?: NameValue[],
postData?: Binary,
};
export type RouteContinueOptions = {
url?: string,
method?: string,
headers?: NameValue[],
postData?: Binary,

Просмотреть файл

@ -1810,6 +1810,7 @@ Route:
continue:
parameters:
url: string?
method: string?
headers:
type: array?

Просмотреть файл

@ -845,6 +845,7 @@ export function createScheme(tChannel: (name: string) => Validator): Scheme {
errorCode: tOptional(tString),
});
scheme.RouteContinueParams = tObject({
url: tOptional(tString),
method: tOptional(tString),
headers: tOptional(tArray(tType('NameValue'))),
postData: tOptional(tBinary),

Просмотреть файл

@ -410,6 +410,7 @@ class InterceptableRequest implements network.RouteDelegate {
// or the page was closed. We should tolerate these errors.
await this._client._sendMayFail('Fetch.continueRequest', {
requestId: this._interceptionId!,
url: overrides.url,
headers: overrides.headers,
method: overrides.method,
postData: overrides.postData ? overrides.postData.toString('base64') : undefined

Просмотреть файл

@ -175,6 +175,7 @@ class InterceptableRequest implements network.RouteDelegate {
async continue(overrides: types.NormalizedContinueOverrides) {
await this._session.sendMayFail('Network.resumeInterceptedRequest', {
requestId: this._id,
url: overrides.url,
method: overrides.method,
headers: overrides.headers,
postData: overrides.postData ? Buffer.from(overrides.postData).toString('base64') : undefined

Просмотреть файл

@ -885,6 +885,7 @@ export module Protocol {
export type abortInterceptedRequestReturnValue = void;
export type resumeInterceptedRequestParameters = {
requestId: string;
url?: string;
method?: string;
headers?: {
name: string;

Просмотреть файл

@ -224,6 +224,12 @@ export class Route {
async continue(overrides: types.NormalizedContinueOverrides = {}) {
assert(!this._handled, 'Route is already handled!');
if (overrides.url) {
const newUrl = new URL(overrides.url);
const oldUrl = new URL(this._request.url());
if (oldUrl.protocol !== newUrl.protocol)
throw new Error('New URL must have same protocol as overriden URL');
}
await this._delegate.continue(overrides);
}
}

Просмотреть файл

@ -191,6 +191,7 @@ export type NormalizedFulfillResponse = {
};
export type NormalizedContinueOverrides = {
url?: string,
method?: string,
headers?: HeadersArray,
postData?: Buffer,

Просмотреть файл

@ -100,6 +100,7 @@ export class WKInterceptableRequest implements network.RouteDelegate {
// or the page was closed. We should tolerate these errors.
await this._session.sendMayFail('Network.interceptWithRequest', {
requestId: this._requestId,
url: overrides.url,
method: overrides.method,
headers: overrides.headers ? headersArrayToObject(overrides.headers, false /* lowerCase */) : undefined,
postData: overrides.postData ? Buffer.from(overrides.postData).toString('base64') : undefined

Просмотреть файл

@ -49,6 +49,42 @@ it('should amend method', async ({page, server}) => {
expect((await sRequest).method).toBe('POST');
});
it('should override request url', async ({page, server}) => {
const request = server.waitForRequest('/empty.html');
await page.route('**/foo', route => {
route.continue({ url: server.EMPTY_PAGE });
});
await page.goto(server.PREFIX + '/foo');
expect((await request).method).toBe('GET');
});
it('should not allow changing protocol when overriding url', async ({page, server}) => {
let error: Error | undefined;
await page.route('**/*', async route => {
try {
await route.continue({ url: 'file:///tmp/foo' });
} catch (e) {
error = e;
await route.continue();
}
});
await page.goto(server.EMPTY_PAGE);
expect(error).toBeTruthy();
expect(error.message).toContain('New URL must have same protocol as overriden URL');
});
it('should override method along with url', async ({page, server}) => {
const request = server.waitForRequest('/empty.html');
await page.route('**/foo', route => {
route.continue({
url: server.EMPTY_PAGE,
method: 'POST'
});
});
await page.goto(server.PREFIX + '/foo');
expect((await request).method).toBe('POST');
});
it('should amend method on main request', async ({page, server}) => {
const request = server.waitForRequest('/empty.html');
await page.route('**/*', route => route.continue({ method: 'POST' }));