Skip to content

Commit 09e97af

Browse files
authored
feat(wk,ff): amend method & postData upon continue (#703)
Fixes #668
1 parent c35c65b commit 09e97af

File tree

7 files changed

+55
-10
lines changed

7 files changed

+55
-10
lines changed

docs/api.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2849,6 +2849,8 @@ Exception is immediately thrown if the request interception is not enabled.
28492849

28502850
#### request.continue([overrides])
28512851
- `overrides` <[Object]> Optional request overwrites, which can be one of the following:
2852+
- `method` <[string]> If set changes the request method (e.g. GET or POST)
2853+
- `postData` <[string]> If set changes the post data of request
28522854
- `headers` <[Object]> If set changes the request HTTP headers. Header values will be converted to a string.
28532855
- returns: <[Promise]>
28542856

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
"main": "index.js",
1010
"playwright": {
1111
"chromium_revision": "733125",
12-
"firefox_revision": "1018",
12+
"firefox_revision": "1019",
1313
"webkit_revision": "1119"
1414
},
1515
"scripts": {

src/chromium/crNetworkManager.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -279,10 +279,12 @@ class InterceptableRequest implements network.RequestDelegate {
279279
event.request.url, (event.type || '').toLowerCase(), event.request.method, event.request.postData, headersObject(event.request.headers));
280280
}
281281

282-
async continue(overrides: { headers?: network.Headers; } = {}) {
282+
async continue(overrides: { method?: string; headers?: network.Headers; postData?: string } = {}) {
283283
await this._client.send('Fetch.continueRequest', {
284284
requestId: this._interceptionId!,
285285
headers: overrides.headers ? headersArray(overrides.headers) : undefined,
286+
method: overrides.method,
287+
postData: overrides.postData
286288
}).catch(error => {
287289
// In certain cases, protocol will return error if the request was already canceled
288290
// or the page was closed. We should tolerate these errors.

src/firefox/ffNetworkManager.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,13 +158,17 @@ class InterceptableRequest implements network.RequestDelegate {
158158
payload.url, causeToResourceType[payload.cause] || 'other', payload.method, payload.postData, headers);
159159
}
160160

161-
async continue(overrides: { headers?: { [key: string]: string } } = {}) {
161+
async continue(overrides: { method?: string; headers?: network.Headers; postData?: string }) {
162162
const {
163+
method,
163164
headers,
165+
postData
164166
} = overrides;
165167
await this._session.send('Network.resumeInterceptedRequest', {
166168
requestId: this._id,
169+
method,
167170
headers: headers ? headersArray(headers) : undefined,
171+
postData: postData ? Buffer.from(postData).toString('base64') : undefined
168172
}).catch(error => {
169173
debugError(error);
170174
});

src/network.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ export class Request {
211211
await this._delegate!.fulfill(response);
212212
}
213213

214-
async continue(overrides: { headers?: { [key: string]: string } } = {}) {
214+
async continue(overrides: { method?: string; headers?: Headers; postData?: string } = {}) {
215215
assert(this._delegate, 'Request Interception is not enabled!');
216216
assert(!this._interceptionHandled, 'Request is already handled!');
217217
await this._delegate!.continue(overrides);
@@ -301,7 +301,7 @@ export class Response {
301301
export interface RequestDelegate {
302302
abort(errorCode: string): Promise<void>;
303303
fulfill(response: { status: number; headers: Headers; contentType: string; body: (string | platform.BufferType); }): Promise<void>;
304-
continue(overrides: { url?: string; method?: string; postData?: string; headers?: Headers; }): Promise<void>;
304+
continue(overrides: { method?: string; headers?: Headers; postData?: string; }): Promise<void>;
305305
}
306306

307307
export class WebSocket extends platform.EventEmitter {

src/webkit/wkInterceptableRequest.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -96,12 +96,14 @@ export class WKInterceptableRequest implements network.RequestDelegate {
9696
});
9797
}
9898

99-
async continue(overrides: { headers?: { [key: string]: string; }; }) {
99+
async continue(overrides: { method?: string; headers?: network.Headers; postData?: string }) {
100100
await this._interceptedPromise;
101101
await this._session.send('Network.interceptContinue', {
102102
requestId: this._requestId,
103-
...overrides
104-
}).catch(error => {
103+
method: overrides.method,
104+
headers: overrides.headers,
105+
postData: overrides.postData ? Buffer.from(overrides.postData).toString('base64') : undefined
106+
}).catch((error: Error) => {
105107
// In certain cases, protocol will return error if the request was already canceled
106108
// or the page was closed. We should tolerate these errors.
107109
debugError(error);

test/interception.spec.js

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -416,7 +416,7 @@ module.exports.describe = function({testRunner, expect, defaultBrowserOptions, p
416416
});
417417
});
418418

419-
describe('Interception.continue', function() {
419+
describe('Request.continue', function() {
420420
it('should work', async({page, server}) => {
421421
await page.setRequestInterception(true);
422422
page.on('request', request => request.continue());
@@ -436,9 +436,44 @@ module.exports.describe = function({testRunner, expect, defaultBrowserOptions, p
436436
]);
437437
expect(request.headers['foo']).toBe('bar');
438438
});
439+
it('should amend method', async({page, server}) => {
440+
const sRequest = server.waitForRequest('/sleep.zzz');
441+
await page.goto(server.EMPTY_PAGE);
442+
await page.setRequestInterception(true);
443+
page.on('request', request => {
444+
request.continue({ method: 'POST' });
445+
});
446+
const [request] = await Promise.all([
447+
server.waitForRequest('/sleep.zzz'),
448+
page.evaluate(() => fetch('/sleep.zzz'))
449+
]);
450+
expect(request.method).toBe('POST');
451+
expect((await sRequest).method).toBe('POST');
452+
});
453+
it('should amend method on main request', async({page, server}) => {
454+
const request = server.waitForRequest('/empty.html');
455+
await page.setRequestInterception(true);
456+
page.on('request', request => {
457+
request.continue({ method: 'POST' });
458+
});
459+
await page.goto(server.EMPTY_PAGE);
460+
expect((await request).method).toBe('POST');
461+
});
462+
it('should amend post data', async({page, server}) => {
463+
await page.goto(server.EMPTY_PAGE);
464+
await page.setRequestInterception(true);
465+
page.on('request', request => {
466+
request.continue({ postData: 'doggo' });
467+
});
468+
const [serverRequest] = await Promise.all([
469+
server.waitForRequest('/sleep.zzz'),
470+
page.evaluate(() => fetch('/sleep.zzz', { method: 'POST', body: 'birdy' }))
471+
]);
472+
expect(await serverRequest.postBody).toBe('doggo');
473+
});
439474
});
440475

441-
describe('interception.fulfill', function() {
476+
describe('Request.fulfill', function() {
442477
it('should work', async({page, server}) => {
443478
await page.setRequestInterception(true);
444479
page.on('request', request => {

0 commit comments

Comments
 (0)