mirror of
https://github.com/microsoft/playwright.git
synced 2025-06-26 21:40:17 +00:00
feat(fetch): introduce failOnStatusCode (#8896)
This commit is contained in:
parent
bb33b8923e
commit
b79be5d98d
@ -41,6 +41,12 @@ Allows to set post data of the fetch.
|
||||
|
||||
Request timeout in milliseconds.
|
||||
|
||||
### option: FetchRequest.fetch.failOnStatusCode
|
||||
- `failOnStatusCode` <[boolean]>
|
||||
|
||||
Whether to throw on response codes other than 2xx and 3xx. By default response object is returned
|
||||
for all status codes.
|
||||
|
||||
## async method: FetchRequest.get
|
||||
- returns: <[FetchResponse]>
|
||||
|
||||
@ -67,6 +73,12 @@ Allows to set HTTP headers.
|
||||
|
||||
Request timeout in milliseconds.
|
||||
|
||||
### option: FetchRequest.get.failOnStatusCode
|
||||
- `failOnStatusCode` <[boolean]>
|
||||
|
||||
Whether to throw on response codes other than 2xx and 3xx. By default response object is returned
|
||||
for all status codes.
|
||||
|
||||
## async method: FetchRequest.post
|
||||
- returns: <[FetchResponse]>
|
||||
|
||||
@ -97,3 +109,9 @@ Allows to set post data of the fetch.
|
||||
- `timeout` <[float]>
|
||||
|
||||
Request timeout in milliseconds.
|
||||
|
||||
### option: FetchRequest.post.failOnStatusCode
|
||||
- `failOnStatusCode` <[boolean]>
|
||||
|
||||
Whether to throw on response codes other than 2xx and 3xx. By default response object is returned
|
||||
for all status codes.
|
||||
|
||||
@ -28,7 +28,8 @@ export type FetchOptions = {
|
||||
method?: string,
|
||||
headers?: Headers,
|
||||
data?: string | Buffer,
|
||||
timeout?: number
|
||||
timeout?: number,
|
||||
failOnStatusCode?: boolean,
|
||||
};
|
||||
|
||||
export class FetchRequest implements api.FetchRequest {
|
||||
@ -44,6 +45,7 @@ export class FetchRequest implements api.FetchRequest {
|
||||
params?: { [key: string]: string; };
|
||||
headers?: { [key: string]: string; };
|
||||
timeout?: number;
|
||||
failOnStatusCode?: boolean;
|
||||
}): Promise<FetchResponse> {
|
||||
return this.fetch(urlOrRequest, {
|
||||
...options,
|
||||
@ -58,6 +60,7 @@ export class FetchRequest implements api.FetchRequest {
|
||||
headers?: { [key: string]: string; };
|
||||
data?: string | Buffer;
|
||||
timeout?: number;
|
||||
failOnStatusCode?: boolean;
|
||||
}): Promise<FetchResponse> {
|
||||
return this.fetch(urlOrRequest, {
|
||||
...options,
|
||||
@ -86,6 +89,7 @@ export class FetchRequest implements api.FetchRequest {
|
||||
headers,
|
||||
postData,
|
||||
timeout: options.timeout,
|
||||
failOnStatusCode: options.failOnStatusCode,
|
||||
});
|
||||
if (result.error)
|
||||
throw new Error(`Request failed: ${result.error}`);
|
||||
|
||||
@ -115,6 +115,7 @@ export class BrowserContextDispatcher extends Dispatcher<BrowserContext, channel
|
||||
headers: params.headers ? headersArrayToObject(params.headers, false) : undefined,
|
||||
postData: params.postData ? Buffer.from(params.postData, 'base64') : undefined,
|
||||
timeout: params.timeout,
|
||||
failOnStatusCode: params.failOnStatusCode,
|
||||
});
|
||||
let response;
|
||||
if (fetchResponse) {
|
||||
|
||||
@ -862,6 +862,7 @@ export type BrowserContextFetchParams = {
|
||||
headers?: NameValue[],
|
||||
postData?: Binary,
|
||||
timeout?: number,
|
||||
failOnStatusCode?: boolean,
|
||||
};
|
||||
export type BrowserContextFetchOptions = {
|
||||
params?: NameValue[],
|
||||
@ -869,6 +870,7 @@ export type BrowserContextFetchOptions = {
|
||||
headers?: NameValue[],
|
||||
postData?: Binary,
|
||||
timeout?: number,
|
||||
failOnStatusCode?: boolean,
|
||||
};
|
||||
export type BrowserContextFetchResult = {
|
||||
response?: FetchResponse,
|
||||
|
||||
@ -625,6 +625,7 @@ BrowserContext:
|
||||
items: NameValue
|
||||
postData: binary?
|
||||
timeout: number?
|
||||
failOnStatusCode: boolean?
|
||||
returns:
|
||||
response: FetchResponse?
|
||||
error: string?
|
||||
|
||||
@ -399,6 +399,7 @@ export function createScheme(tChannel: (name: string) => Validator): Scheme {
|
||||
headers: tOptional(tArray(tType('NameValue'))),
|
||||
postData: tOptional(tBinary),
|
||||
timeout: tOptional(tNumber),
|
||||
failOnStatusCode: tOptional(tBoolean),
|
||||
});
|
||||
scheme.BrowserContextFetchResponseBodyParams = tObject({
|
||||
fetchUid: tString,
|
||||
|
||||
@ -74,6 +74,8 @@ export async function playwrightFetch(context: BrowserContext, params: types.Fet
|
||||
|
||||
const fetchResponse = await sendRequest(context, requestUrl, options, params.postData);
|
||||
const fetchUid = context.storeFetchResponseBody(fetchResponse.body);
|
||||
if (params.failOnStatusCode && (fetchResponse.status < 200 || fetchResponse.status >= 400))
|
||||
return { error: `${fetchResponse.status} ${fetchResponse.statusText}` };
|
||||
return { fetchResponse: { ...fetchResponse, fetchUid } };
|
||||
} catch (e) {
|
||||
return { error: String(e) };
|
||||
|
||||
@ -379,6 +379,7 @@ export type FetchOptions = {
|
||||
headers?: { [name: string]: string },
|
||||
postData?: Buffer,
|
||||
timeout?: number,
|
||||
failOnStatusCode?: boolean,
|
||||
};
|
||||
|
||||
export type FetchResponse = {
|
||||
|
||||
@ -128,13 +128,16 @@ it('should add session cookies to request', async ({context, server}) => {
|
||||
expect(req.headers.cookie).toEqual('username=John Doe');
|
||||
});
|
||||
|
||||
it('should support queryParams', async ({context, server}) => {
|
||||
let request;
|
||||
server.setRoute('/empty.html', (req, res) => {
|
||||
request = req;
|
||||
server.serveFile(req, res);
|
||||
});
|
||||
for (const method of ['get', 'post', 'fetch']) {
|
||||
for (const method of ['get', 'post', 'fetch']) {
|
||||
it(`${method} should support queryParams`, async ({context, server}) => {
|
||||
let request;
|
||||
const url = new URL(server.EMPTY_PAGE);
|
||||
url.searchParams.set('p1', 'v1');
|
||||
url.searchParams.set('парам2', 'знач2');
|
||||
server.setRoute(url.pathname + url.search, (req, res) => {
|
||||
request = req;
|
||||
server.serveFile(req, res);
|
||||
});
|
||||
await context.request[method](server.EMPTY_PAGE + '?p1=foo', {
|
||||
params: {
|
||||
'p1': 'v1',
|
||||
@ -144,8 +147,15 @@ it('should support queryParams', async ({context, server}) => {
|
||||
const params = new URLSearchParams(request.url.substr(request.url.indexOf('?')));
|
||||
expect(params.get('p1')).toEqual('v1');
|
||||
expect(params.get('парам2')).toEqual('знач2');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it(`${method} should support failOnStatusCode`, async ({context, server}) => {
|
||||
const error = await context.request[method](server.PREFIX + '/does-not-exist.html', {
|
||||
failOnStatusCode: true
|
||||
}).catch(e => e);
|
||||
expect(error.message).toContain('Request failed: 404 Not Found');
|
||||
});
|
||||
}
|
||||
|
||||
it('should not add context cookie if cookie header passed as a parameter', async ({context, server}) => {
|
||||
await context.addCookies([{
|
||||
|
||||
15
types/types.d.ts
vendored
15
types/types.d.ts
vendored
@ -12636,6 +12636,11 @@ export interface FetchRequest {
|
||||
*/
|
||||
data?: string|Buffer;
|
||||
|
||||
/**
|
||||
* Whether to throw on response codes other than 2xx and 3xx. By default response object is returned for all status codes.
|
||||
*/
|
||||
failOnStatusCode?: boolean;
|
||||
|
||||
/**
|
||||
* Allows to set HTTP headers.
|
||||
*/
|
||||
@ -12664,6 +12669,11 @@ export interface FetchRequest {
|
||||
* @param options
|
||||
*/
|
||||
get(urlOrRequest: string|Request, options?: {
|
||||
/**
|
||||
* Whether to throw on response codes other than 2xx and 3xx. By default response object is returned for all status codes.
|
||||
*/
|
||||
failOnStatusCode?: boolean;
|
||||
|
||||
/**
|
||||
* Allows to set HTTP headers.
|
||||
*/
|
||||
@ -12692,6 +12702,11 @@ export interface FetchRequest {
|
||||
*/
|
||||
data?: string|Buffer;
|
||||
|
||||
/**
|
||||
* Whether to throw on response codes other than 2xx and 3xx. By default response object is returned for all status codes.
|
||||
*/
|
||||
failOnStatusCode?: boolean;
|
||||
|
||||
/**
|
||||
* Allows to set HTTP headers.
|
||||
*/
|
||||
|
||||
@ -238,10 +238,10 @@ class TestServer {
|
||||
request.on('data', chunk => body = Buffer.concat([body, chunk]));
|
||||
request.on('end', () => resolve(body));
|
||||
});
|
||||
const pathName = url.parse(request.url).pathname;
|
||||
this.debugServer(`request ${request.method} ${pathName}`);
|
||||
if (this._auths.has(pathName)) {
|
||||
const auth = this._auths.get(pathName);
|
||||
const path = url.parse(request.url).path;
|
||||
this.debugServer(`request ${request.method} ${path}`);
|
||||
if (this._auths.has(path)) {
|
||||
const auth = this._auths.get(path);
|
||||
const credentials = Buffer.from((request.headers.authorization || '').split(' ')[1] || '', 'base64').toString();
|
||||
this.debugServer(`request credentials ${credentials}`);
|
||||
this.debugServer(`actual credentials ${auth.username}:${auth.password}`);
|
||||
@ -253,11 +253,11 @@ class TestServer {
|
||||
}
|
||||
}
|
||||
// Notify request subscriber.
|
||||
if (this._requestSubscribers.has(pathName)) {
|
||||
this._requestSubscribers.get(pathName)[fulfillSymbol].call(null, request);
|
||||
this._requestSubscribers.delete(pathName);
|
||||
if (this._requestSubscribers.has(path)) {
|
||||
this._requestSubscribers.get(path)[fulfillSymbol].call(null, request);
|
||||
this._requestSubscribers.delete(path);
|
||||
}
|
||||
const handler = this._routes.get(pathName);
|
||||
const handler = this._routes.get(path);
|
||||
if (handler) {
|
||||
handler.call(null, request, response);
|
||||
} else {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user