From 10952a3964623e45d4d24c7cf9e3564346727515 Mon Sep 17 00:00:00 2001 From: Erik Eide Date: Wed, 11 Sep 2024 15:31:08 +1000 Subject: [PATCH] feat(api): add method OPTIONS to request --- docs/src/api/class-apirequestcontext.md | 59 ++++++++++++++ packages/playwright-core/src/client/fetch.ts | 7 ++ packages/playwright-core/types/types.d.ts | 86 ++++++++++++++++++++ tests/library/browsercontext-fetch.spec.ts | 13 +++ 4 files changed, 165 insertions(+) diff --git a/docs/src/api/class-apirequestcontext.md b/docs/src/api/class-apirequestcontext.md index a6333d6b0a..85f80fdb4a 100644 --- a/docs/src/api/class-apirequestcontext.md +++ b/docs/src/api/class-apirequestcontext.md @@ -522,6 +522,65 @@ context cookies from the response. The method will automatically follow redirect ### option: APIRequestContext.head.maxRetries = %%-js-python-csharp-fetch-option-maxretries-%% * since: v1.46 +## async method: APIRequestContext.options +* since: v1.48 +- returns: <[APIResponse]> + +Sends HTTP(S) [OPTIONS](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/OPTIONS) request and returns its response. +The method will populate request cookies from the context and update +context cookies from the response. The method will automatically follow redirects. + +### param: APIRequestContext.options.url = %%-fetch-param-url-%% +* since: v1.16 + +### option: APIRequestContext.options.params = %%-js-fetch-option-params-%% +* since: v1.16 + +### param: APIRequestContext.options.params = %%-java-csharp-fetch-params-%% +* since: v1.18 + +### option: APIRequestContext.options.params = %%-python-fetch-option-params-%% +* since: v1.16 + +### option: APIRequestContext.options.params = %%-csharp-fetch-option-params-%% +* since: v1.16 + +### option: APIRequestContext.options.headers = %%-js-python-csharp-fetch-option-headers-%% +* since: v1.16 + +### option: APIRequestContext.options.data = %%-js-python-csharp-fetch-option-data-%% +* since: v1.26 + +### option: APIRequestContext.options.form = %%-js-python-fetch-option-form-%% +* since: v1.26 + +### option: APIRequestContext.options.form = %%-csharp-fetch-option-form-%% +* since: v1.26 + +### option: APIRequestContext.options.multipart = %%-js-fetch-option-multipart-%% +* since: v1.26 + +### option: APIRequestContext.options.multipart = %%-python-fetch-option-multipart-%% +* since: v1.26 + +### option: APIRequestContext.options.multipart = %%-csharp-fetch-option-multipart-%% +* since: v1.26 + +### option: APIRequestContext.options.timeout = %%-js-python-csharp-fetch-option-timeout-%% +* since: v1.16 + +### option: APIRequestContext.options.failOnStatusCode = %%-js-python-csharp-fetch-option-failonstatuscode-%% +* since: v1.16 + +### option: APIRequestContext.options.ignoreHTTPSErrors = %%-js-python-csharp-fetch-option-ignorehttpserrors-%% +* since: v1.16 + +### option: APIRequestContext.options.maxRedirects = %%-js-python-csharp-fetch-option-maxredirects-%% +* since: v1.26 + +### option: APIRequestContext.options.maxRetries = %%-js-python-csharp-fetch-option-maxretries-%% +* since: v1.46 + ## async method: APIRequestContext.patch * since: v1.16 - returns: <[APIResponse]> diff --git a/packages/playwright-core/src/client/fetch.ts b/packages/playwright-core/src/client/fetch.ts index 7aaa5069c2..548e418510 100644 --- a/packages/playwright-core/src/client/fetch.ts +++ b/packages/playwright-core/src/client/fetch.ts @@ -139,6 +139,13 @@ export class APIRequestContext extends ChannelOwner { + return await this.fetch(url, { + ...options, + method: 'OPTIONS', + }); + } + async patch(url: string, options?: RequestWithBodyOptions): Promise { return await this.fetch(url, { ...options, diff --git a/packages/playwright-core/types/types.d.ts b/packages/playwright-core/types/types.d.ts index 765c84c36e..4a8503a3a5 100644 --- a/packages/playwright-core/types/types.d.ts +++ b/packages/playwright-core/types/types.d.ts @@ -16953,6 +16953,92 @@ export interface APIRequestContext { timeout?: number; }): Promise; + /** + * Sends HTTP(S) [OPTIONS](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/OPTIONS) request and returns its + * response. The method will populate request cookies from the context and update context cookies from the response. + * The method will automatically follow redirects. + * @param url Target URL. + * @param options + */ + options(url: string, options?: { + /** + * Allows to set post data of the request. If the data parameter is an object, it will be serialized to json string + * and `content-type` header will be set to `application/json` if not explicitly set. Otherwise the `content-type` + * header will be set to `application/octet-stream` if not explicitly set. + */ + data?: string|Buffer|Serializable; + + /** + * Whether to throw on response codes other than 2xx and 3xx. By default response object is returned for all status + * codes. + */ + failOnStatusCode?: boolean; + + /** + * Provides an object that will be serialized as html form using `application/x-www-form-urlencoded` encoding and sent + * as this request body. If this parameter is specified `content-type` header will be set to + * `application/x-www-form-urlencoded` unless explicitly provided. + */ + form?: { [key: string]: string|number|boolean; }; + + /** + * Allows to set HTTP headers. These headers will apply to the fetched request as well as any redirects initiated by + * it. + */ + headers?: { [key: string]: string; }; + + /** + * Whether to ignore HTTPS errors when sending network requests. Defaults to `false`. + */ + ignoreHTTPSErrors?: boolean; + + /** + * Maximum number of request redirects that will be followed automatically. An error will be thrown if the number is + * exceeded. Defaults to `20`. Pass `0` to not follow redirects. + */ + maxRedirects?: number; + + /** + * Maximum number of times network errors should be retried. Currently only `ECONNRESET` error is retried. Does not + * retry based on HTTP response codes. An error will be thrown if the limit is exceeded. Defaults to `0` - no retries. + */ + maxRetries?: number; + + /** + * Provides an object that will be serialized as html form using `multipart/form-data` encoding and sent as this + * request body. If this parameter is specified `content-type` header will be set to `multipart/form-data` unless + * explicitly provided. File values can be passed either as + * [`fs.ReadStream`](https://nodejs.org/api/fs.html#fs_class_fs_readstream) or as file-like object containing file + * name, mime-type and its content. + */ + multipart?: FormData|{ [key: string]: string|number|boolean|ReadStream|{ + /** + * File name + */ + name: string; + + /** + * File type + */ + mimeType: string; + + /** + * File content + */ + buffer: Buffer; + }; }; + + /** + * Query parameters to be sent with the URL. + */ + params?: { [key: string]: string|number|boolean; }|URLSearchParams|string; + + /** + * Request timeout in milliseconds. Defaults to `30000` (30 seconds). Pass `0` to disable timeout. + */ + timeout?: number; + }): Promise; + /** * Sends HTTP(S) [PATCH](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/PATCH) request and returns its * response. The method will populate request cookies from the context and update context cookies from the response. diff --git a/tests/library/browsercontext-fetch.spec.ts b/tests/library/browsercontext-fetch.spec.ts index 51a98dec4a..431562785b 100644 --- a/tests/library/browsercontext-fetch.spec.ts +++ b/tests/library/browsercontext-fetch.spec.ts @@ -570,6 +570,19 @@ it('head should support post data', async ({ context, server }) => { expect(request.url).toBe('/simple.json'); }); +it('options should support post data', async ({ context, server }) => { + const [request, response] = await Promise.all([ + server.waitForRequest('/simple.json'), + context.request.options(`${server.PREFIX}/simple.json`, { + data: 'My request' + }) + ]); + expect(request.method).toBe('OPTIONS'); + expect((await request.postBody).toString()).toBe('My request'); + expect(response.status()).toBe(200); + expect(request.url).toBe('/simple.json'); +}); + it('patch should support post data', async ({ context, server }) => { const [request, response] = await Promise.all([ server.waitForRequest('/simple.json'),