feat: add failOnStatusCode option to API request context
This commit is contained in:
parent
aeec0c0e36
commit
e3965545a4
|
|
@ -620,6 +620,12 @@ A list of permissions to grant to all pages in this context. See
|
||||||
|
|
||||||
An object containing additional HTTP headers to be sent with every request. Defaults to none.
|
An object containing additional HTTP headers to be sent with every request. Defaults to none.
|
||||||
|
|
||||||
|
## context-option-apirequest
|
||||||
|
- `apiRequest` <[Object]>
|
||||||
|
- `failOnStatusCode` <[boolean]>
|
||||||
|
|
||||||
|
An object containing an option to throw an error when API request returns status codes other than 2xx and 3xx. By default, response object is returned for all status codes.
|
||||||
|
|
||||||
## context-option-offline
|
## context-option-offline
|
||||||
- `offline` <[boolean]>
|
- `offline` <[boolean]>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -339,6 +339,9 @@ scheme.PlaywrightNewRequestParams = tObject({
|
||||||
userAgent: tOptional(tString),
|
userAgent: tOptional(tString),
|
||||||
ignoreHTTPSErrors: tOptional(tBoolean),
|
ignoreHTTPSErrors: tOptional(tBoolean),
|
||||||
extraHTTPHeaders: tOptional(tArray(tType('NameValue'))),
|
extraHTTPHeaders: tOptional(tArray(tType('NameValue'))),
|
||||||
|
apiRequest: tOptional(tObject({
|
||||||
|
failOnStatusCode: tBoolean
|
||||||
|
})),
|
||||||
clientCertificates: tOptional(tArray(tObject({
|
clientCertificates: tOptional(tArray(tObject({
|
||||||
origin: tString,
|
origin: tString,
|
||||||
cert: tOptional(tBinary),
|
cert: tOptional(tBinary),
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,9 @@ import { TLSSocket } from 'tls';
|
||||||
type FetchRequestOptions = {
|
type FetchRequestOptions = {
|
||||||
userAgent: string;
|
userAgent: string;
|
||||||
extraHTTPHeaders?: HeadersArray;
|
extraHTTPHeaders?: HeadersArray;
|
||||||
|
apiRequest?: {
|
||||||
|
failOnStatusCode: boolean;
|
||||||
|
}
|
||||||
httpCredentials?: HTTPCredentials;
|
httpCredentials?: HTTPCredentials;
|
||||||
proxy?: ProxySettings;
|
proxy?: ProxySettings;
|
||||||
timeoutSettings: TimeoutSettings;
|
timeoutSettings: TimeoutSettings;
|
||||||
|
|
@ -205,7 +208,8 @@ export abstract class APIRequestContext extends SdkObject {
|
||||||
});
|
});
|
||||||
const fetchUid = this._storeResponseBody(fetchResponse.body);
|
const fetchUid = this._storeResponseBody(fetchResponse.body);
|
||||||
this.fetchLog.set(fetchUid, controller.metadata.log);
|
this.fetchLog.set(fetchUid, controller.metadata.log);
|
||||||
if (params.failOnStatusCode && (fetchResponse.status < 200 || fetchResponse.status >= 400)) {
|
let failOnStatusCode = params.failOnStatusCode !== undefined ? params.failOnStatusCode : !!defaults.apiRequest?.failOnStatusCode;
|
||||||
|
if (failOnStatusCode && (fetchResponse.status < 200 || fetchResponse.status >= 400)) {
|
||||||
let responseText = '';
|
let responseText = '';
|
||||||
if (fetchResponse.body.byteLength) {
|
if (fetchResponse.body.byteLength) {
|
||||||
let text = fetchResponse.body.toString('utf8');
|
let text = fetchResponse.body.toString('utf8');
|
||||||
|
|
@ -661,6 +665,7 @@ export class GlobalAPIRequestContext extends APIRequestContext {
|
||||||
baseURL: options.baseURL,
|
baseURL: options.baseURL,
|
||||||
userAgent: options.userAgent || getUserAgent(),
|
userAgent: options.userAgent || getUserAgent(),
|
||||||
extraHTTPHeaders: options.extraHTTPHeaders,
|
extraHTTPHeaders: options.extraHTTPHeaders,
|
||||||
|
apiRequest: {failOnStatusCode: !!options.apiRequest?.failOnStatusCode},
|
||||||
ignoreHTTPSErrors: !!options.ignoreHTTPSErrors,
|
ignoreHTTPSErrors: !!options.ignoreHTTPSErrors,
|
||||||
httpCredentials: options.httpCredentials,
|
httpCredentials: options.httpCredentials,
|
||||||
clientCertificates: options.clientCertificates,
|
clientCertificates: options.clientCertificates,
|
||||||
|
|
|
||||||
5
packages/playwright-core/types/types.d.ts
vendored
5
packages/playwright-core/types/types.d.ts
vendored
|
|
@ -17482,6 +17482,11 @@ export interface APIRequest {
|
||||||
*/
|
*/
|
||||||
extraHTTPHeaders?: { [key: string]: string; };
|
extraHTTPHeaders?: { [key: string]: string; };
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An object containing an option to throw an error when API request returns status codes other than 2xx and 3xx.
|
||||||
|
*/
|
||||||
|
apiRequest?: {failOnStatusCode?: boolean;}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Credentials for [HTTP authentication](https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication). If no
|
* Credentials for [HTTP authentication](https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication). If no
|
||||||
* origin is specified, the username and password are sent to any servers upon unauthorized responses.
|
* origin is specified, the username and password are sent to any servers upon unauthorized responses.
|
||||||
|
|
|
||||||
3
packages/protocol/src/channels.d.ts
vendored
3
packages/protocol/src/channels.d.ts
vendored
|
|
@ -619,6 +619,9 @@ export type PlaywrightNewRequestOptions = {
|
||||||
userAgent?: string,
|
userAgent?: string,
|
||||||
ignoreHTTPSErrors?: boolean,
|
ignoreHTTPSErrors?: boolean,
|
||||||
extraHTTPHeaders?: NameValue[],
|
extraHTTPHeaders?: NameValue[],
|
||||||
|
apiRequest?: {
|
||||||
|
failOnStatusCode: boolean
|
||||||
|
},
|
||||||
clientCertificates?: {
|
clientCertificates?: {
|
||||||
origin: string,
|
origin: string,
|
||||||
cert?: Binary,
|
cert?: Binary,
|
||||||
|
|
|
||||||
|
|
@ -536,3 +536,47 @@ it('should retry ECONNRESET', {
|
||||||
expect(requestCount).toBe(4);
|
expect(requestCount).toBe(4);
|
||||||
await request.dispose();
|
await request.dispose();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should throw when failOnStatusCode is set to true', async ({ playwright, server }) => {
|
||||||
|
it.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/34204' });
|
||||||
|
const request = await playwright.request.newContext({ apiRequest: { failOnStatusCode: true } });
|
||||||
|
server.setRoute('/empty.html', (req, res) => {
|
||||||
|
res.writeHead(404, { 'Content-Length': 10, 'Content-Type': 'text/plain' });
|
||||||
|
res.end('Not found.');
|
||||||
|
});
|
||||||
|
const error = await request.fetch(server.EMPTY_PAGE).catch(e => e);
|
||||||
|
expect(error.message).toContain('404 Not Found')
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should throw when failOnStatusCode is set to true inside the fetch API call', async ({ playwright, server }) => {
|
||||||
|
it.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/34204' });
|
||||||
|
const request = await playwright.request.newContext({ apiRequest: { failOnStatusCode: false } });
|
||||||
|
server.setRoute('/empty.html', (req, res) => {
|
||||||
|
res.writeHead(404, { 'Content-Length': 10, 'Content-Type': 'text/plain' });
|
||||||
|
res.end('Not found.');
|
||||||
|
});
|
||||||
|
const error = await request.fetch(server.EMPTY_PAGE, {failOnStatusCode: true}).catch(e => e);
|
||||||
|
expect(error.message).toContain('404 Not Found')
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not throw when failOnStatusCode is set to false', async ({ playwright, server }) => {
|
||||||
|
it.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/34204' });
|
||||||
|
const request = await playwright.request.newContext({ apiRequest: { failOnStatusCode: false } });
|
||||||
|
server.setRoute('/empty.html', (req, res) => {
|
||||||
|
res.writeHead(404, { 'Content-Length': 10, 'Content-Type': 'text/plain' });
|
||||||
|
res.end('Not found.');
|
||||||
|
});
|
||||||
|
const error = await request.fetch(server.EMPTY_PAGE).catch(e => e);
|
||||||
|
expect(error.message).toBeUndefined()
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not throw when failOnStatusCode is set to false inside the fetch API call', async ({ playwright, server }) => {
|
||||||
|
it.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/34204' });
|
||||||
|
const request = await playwright.request.newContext({ apiRequest: { failOnStatusCode: true } });
|
||||||
|
server.setRoute('/empty.html', (req, res) => {
|
||||||
|
res.writeHead(404, { 'Content-Length': 10, 'Content-Type': 'text/plain' });
|
||||||
|
res.end('Not found.');
|
||||||
|
});
|
||||||
|
const error = await request.fetch(server.EMPTY_PAGE, {failOnStatusCode: false}).catch(e => e);
|
||||||
|
expect(error.message).toBeUndefined()
|
||||||
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue