fix: fulfill intercepted response with empty body (#8151)
This commit is contained in:
parent
f434c41523
commit
59df541de5
|
|
@ -265,7 +265,7 @@ export class Route extends ChannelOwner<channels.RouteChannel, channels.RouteIni
|
||||||
|
|
||||||
async fulfill(options: { status?: number, headers?: Headers, contentType?: string, body?: string | Buffer, path?: string } = {}) {
|
async fulfill(options: { status?: number, headers?: Headers, contentType?: string, body?: string | Buffer, path?: string } = {}) {
|
||||||
return this._wrapApiCall(async (channel: channels.RouteChannel) => {
|
return this._wrapApiCall(async (channel: channels.RouteChannel) => {
|
||||||
let body = '';
|
let body = undefined;
|
||||||
let isBase64 = false;
|
let isBase64 = false;
|
||||||
let length = 0;
|
let length = 0;
|
||||||
if (options.path) {
|
if (options.path) {
|
||||||
|
|
|
||||||
|
|
@ -179,15 +179,25 @@ const internalCauseToResourceType: {[key: string]: string} = {
|
||||||
class InterceptableRequest {
|
class InterceptableRequest {
|
||||||
readonly request: network.Request;
|
readonly request: network.Request;
|
||||||
readonly _id: string;
|
readonly _id: string;
|
||||||
|
private _redirectedTo: InterceptableRequest | undefined;
|
||||||
|
|
||||||
constructor(frame: frames.Frame, redirectedFrom: InterceptableRequest | null, payload: Protocol.Network.requestWillBeSentPayload) {
|
constructor(frame: frames.Frame, redirectedFrom: InterceptableRequest | null, payload: Protocol.Network.requestWillBeSentPayload) {
|
||||||
this._id = payload.requestId;
|
this._id = payload.requestId;
|
||||||
|
if (redirectedFrom)
|
||||||
|
redirectedFrom._redirectedTo = this;
|
||||||
let postDataBuffer = null;
|
let postDataBuffer = null;
|
||||||
if (payload.postData)
|
if (payload.postData)
|
||||||
postDataBuffer = Buffer.from(payload.postData, 'base64');
|
postDataBuffer = Buffer.from(payload.postData, 'base64');
|
||||||
this.request = new network.Request(frame, redirectedFrom ? redirectedFrom.request : null, payload.navigationId,
|
this.request = new network.Request(frame, redirectedFrom ? redirectedFrom.request : null, payload.navigationId,
|
||||||
payload.url, internalCauseToResourceType[payload.internalCause] || causeToResourceType[payload.cause] || 'other', payload.method, postDataBuffer, payload.headers);
|
payload.url, internalCauseToResourceType[payload.internalCause] || causeToResourceType[payload.cause] || 'other', payload.method, postDataBuffer, payload.headers);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_finalRequest(): InterceptableRequest {
|
||||||
|
let request: InterceptableRequest = this;
|
||||||
|
while (request._redirectedTo)
|
||||||
|
request = request._redirectedTo;
|
||||||
|
return request;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class FFRouteImpl implements network.RouteDelegate {
|
class FFRouteImpl implements network.RouteDelegate {
|
||||||
|
|
@ -199,12 +209,9 @@ class FFRouteImpl implements network.RouteDelegate {
|
||||||
this._request = request;
|
this._request = request;
|
||||||
}
|
}
|
||||||
|
|
||||||
async responseBody(forFulfill: boolean): Promise<Buffer> {
|
async responseBody(): Promise<Buffer> {
|
||||||
// Empty buffer will result in the response being used.
|
|
||||||
if (forFulfill)
|
|
||||||
return Buffer.from('');
|
|
||||||
const response = await this._session.send('Network.getResponseBody', {
|
const response = await this._session.send('Network.getResponseBody', {
|
||||||
requestId: this._request._id
|
requestId: this._request._finalRequest()._id
|
||||||
});
|
});
|
||||||
return Buffer.from(response.base64body, 'base64');
|
return Buffer.from(response.base64body, 'base64');
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -222,9 +222,9 @@ export class Route extends SdkObject {
|
||||||
this._handled = true;
|
this._handled = true;
|
||||||
let body = overrides.body;
|
let body = overrides.body;
|
||||||
let isBase64 = overrides.isBase64 || false;
|
let isBase64 = overrides.isBase64 || false;
|
||||||
if (!body) {
|
if (body === undefined) {
|
||||||
if (this._response) {
|
if (this._response) {
|
||||||
body = (await this._delegate.responseBody(true)).toString('utf8');
|
body = (await this._delegate.responseBody()).toString('utf8');
|
||||||
isBase64 = false;
|
isBase64 = false;
|
||||||
} else {
|
} else {
|
||||||
body = '';
|
body = '';
|
||||||
|
|
@ -254,7 +254,7 @@ export class Route extends SdkObject {
|
||||||
|
|
||||||
async responseBody(): Promise<Buffer> {
|
async responseBody(): Promise<Buffer> {
|
||||||
assert(!this._handled, 'Route is already handled!');
|
assert(!this._handled, 'Route is already handled!');
|
||||||
return this._delegate.responseBody(false);
|
return this._delegate.responseBody();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -474,7 +474,7 @@ export interface RouteDelegate {
|
||||||
abort(errorCode: string): Promise<void>;
|
abort(errorCode: string): Promise<void>;
|
||||||
fulfill(response: types.NormalizedFulfillResponse): Promise<void>;
|
fulfill(response: types.NormalizedFulfillResponse): Promise<void>;
|
||||||
continue(request: Request, overrides: types.NormalizedContinueOverrides): Promise<InterceptedResponse|null>;
|
continue(request: Request, overrides: types.NormalizedContinueOverrides): Promise<InterceptedResponse|null>;
|
||||||
responseBody(forFulfill: boolean): Promise<Buffer>;
|
responseBody(): Promise<Buffer>;
|
||||||
}
|
}
|
||||||
|
|
||||||
// List taken from https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml with extra 306 and 418 codes.
|
// List taken from https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml with extra 306 and 418 codes.
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,21 @@ it('should fulfill intercepted response', async ({page, server, browserName}) =>
|
||||||
expect(await page.evaluate(() => document.body.textContent)).toBe('Yo, page!');
|
expect(await page.evaluate(() => document.body.textContent)).toBe('Yo, page!');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should fulfill response with empty body', async ({page, server, browserName}) => {
|
||||||
|
it.fail(browserName === 'firefox');
|
||||||
|
await page.route('**/*', async route => {
|
||||||
|
// @ts-expect-error
|
||||||
|
await route._intercept({});
|
||||||
|
await route.fulfill({
|
||||||
|
status: 201,
|
||||||
|
body: ''
|
||||||
|
});
|
||||||
|
});
|
||||||
|
const response = await page.goto(server.PREFIX + '/title.html');
|
||||||
|
expect(response.status()).toBe(201);
|
||||||
|
expect(await response.text()).toBe('');
|
||||||
|
});
|
||||||
|
|
||||||
it('should throw on continue after intercept', async ({page, server, browserName}) => {
|
it('should throw on continue after intercept', async ({page, server, browserName}) => {
|
||||||
let routeCallback;
|
let routeCallback;
|
||||||
const routePromise = new Promise<Route>(f => routeCallback = f);
|
const routePromise = new Promise<Route>(f => routeCallback = f);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue