feat(fetch): fetch with request parameter (#8793)
This commit is contained in:
Родитель
b11b274b0d
Коммит
5550f58284
|
@ -28,7 +28,7 @@ import { Events } from './events';
|
|||
import { TimeoutSettings } from '../utils/timeoutSettings';
|
||||
import { Waiter } from './waiter';
|
||||
import { URLMatch, Headers, WaitForEventOptions, BrowserContextOptions, StorageState, LaunchOptions } from './types';
|
||||
import { isUnderTest, headersObjectToArray, mkdirIfNeeded, isString } from '../utils/utils';
|
||||
import { isUnderTest, headersObjectToArray, mkdirIfNeeded, isString, assert } from '../utils/utils';
|
||||
import { isSafeCloseError } from '../utils/errors';
|
||||
import * as api from '../../types/types';
|
||||
import * as structs from '../../types/structs';
|
||||
|
@ -216,14 +216,26 @@ export class BrowserContext extends ChannelOwner<channels.BrowserContextChannel,
|
|||
});
|
||||
}
|
||||
|
||||
async _fetch(url: string, options: FetchOptions = {}): Promise<network.FetchResponse> {
|
||||
async _fetch(request: network.Request, options?: { timeout?: number }): Promise<network.FetchResponse>;
|
||||
async _fetch(url: string, options?: FetchOptions): Promise<network.FetchResponse>;
|
||||
async _fetch(urlOrRequest: string|network.Request, options: FetchOptions = {}): Promise<network.FetchResponse> {
|
||||
return this._wrapApiCall(async (channel: channels.BrowserContextChannel) => {
|
||||
const postDataBuffer = isString(options.postData) ? Buffer.from(options.postData, 'utf8') : options.postData;
|
||||
const request: network.Request | undefined = (urlOrRequest instanceof network.Request) ? urlOrRequest as network.Request : undefined;
|
||||
assert(request || typeof urlOrRequest === 'string', 'First argument must be either URL string or Request');
|
||||
const url = request ? request.url() : urlOrRequest as string;
|
||||
const method = request?.method() || options.method;
|
||||
// Cannot call allHeaders() here as the request may be paused inside route handler.
|
||||
const headersObj = request?.headers() || options.headers;
|
||||
const headers = headersObj ? headersObjectToArray(headersObj) : undefined;
|
||||
let postDataBuffer = request?.postDataBuffer();
|
||||
if (postDataBuffer === undefined)
|
||||
postDataBuffer = (isString(options.postData) ? Buffer.from(options.postData, 'utf8') : options.postData);
|
||||
const postData = (postDataBuffer ? postDataBuffer.toString('base64') : undefined);
|
||||
const result = await channel.fetch({
|
||||
url,
|
||||
method: options.method,
|
||||
headers: options.headers ? headersObjectToArray(options.headers) : undefined,
|
||||
postData: postDataBuffer ? postDataBuffer.toString('base64') : undefined,
|
||||
method,
|
||||
headers,
|
||||
postData,
|
||||
timeout: options.timeout,
|
||||
});
|
||||
if (result.error)
|
||||
|
|
|
@ -438,8 +438,10 @@ export class Page extends ChannelOwner<channels.PageChannel, channels.PageInitia
|
|||
return this._mainFrame.evaluate(pageFunction, arg);
|
||||
}
|
||||
|
||||
async _fetch(url: string, options: FetchOptions = {}): Promise<network.FetchResponse> {
|
||||
return await this._browserContext._fetch(url, options);
|
||||
async _fetch(request: network.Request, options?: { timeout?: number }): Promise<network.FetchResponse>;
|
||||
async _fetch(url: string, options?: FetchOptions): Promise<network.FetchResponse>;
|
||||
async _fetch(urlOrRequest: string|network.Request, options: FetchOptions = {}): Promise<network.FetchResponse> {
|
||||
return await this._browserContext._fetch(urlOrRequest as any, options);
|
||||
}
|
||||
|
||||
async addInitScript(script: Function | string | { path?: string, content?: string }, arg?: any) {
|
||||
|
|
|
@ -632,3 +632,9 @@ it('should dispose when context closes', async function({context, server}) {
|
|||
expect(error.message).toContain('Target page, context or browser has been closed');
|
||||
});
|
||||
|
||||
it('should throw on invalid first argument', async function({context, server}) {
|
||||
// @ts-expect-error
|
||||
const error = await context._fetch({}).catch(e => e);
|
||||
expect(error.message).toContain('First argument must be either URL string or Request');
|
||||
});
|
||||
|
||||
|
|
|
@ -224,3 +224,17 @@ it('should fulfill with fetch result and overrides', async ({page, server}) => {
|
|||
expect((await response.allHeaders()).foo).toEqual('bar');
|
||||
expect(await response.json()).toEqual({'foo': 'bar'});
|
||||
});
|
||||
|
||||
it('should fetch original request and fulfill', async ({page, server}) => {
|
||||
await page.route('**/*', async route => {
|
||||
// @ts-expect-error
|
||||
const response = await page._fetch(route.request());
|
||||
route.fulfill({
|
||||
// @ts-expect-error
|
||||
response,
|
||||
});
|
||||
});
|
||||
const response = await page.goto(server.PREFIX + '/title.html');
|
||||
expect(response.status()).toBe(200);
|
||||
expect(await page.title()).toEqual('Woof-Woof');
|
||||
});
|
||||
|
|
Загрузка…
Ссылка в новой задаче