api: alias Fetch as ApiRequest (#9330)

This commit is contained in:
Pavel Feldman 2021-10-05 17:53:19 -08:00 committed by GitHub
parent 0a7b54abc3
commit e8fdbbfa03
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
17 changed files with 611 additions and 586 deletions

View file

@ -0,0 +1,53 @@
# class: ApiRequest
* langs: js
Exposes API that can be used for the Web API testing.
## async method: ApiRequest.newContext
* langs: js
- returns: <[ApiRequestContext]>
**experimental** Creates new instances of [ApiRequestContext].
### option: ApiRequest.newContext.useragent = %%-context-option-useragent-%%
### option: ApiRequest.newContext.extraHTTPHeaders = %%-context-option-extrahttpheaders-%%
### option: ApiRequest.newContext.httpCredentials = %%-context-option-httpcredentials-%%
### option: ApiRequest.newContext.proxy = %%-browser-option-proxy-%%
### option: ApiRequest.newContext.ignoreHTTPSErrors = %%-context-option-ignorehttpserrors-%%
### option: ApiRequest.newContext.timeout
- `timeout` <[float]>
Maximum time in milliseconds to wait for the response. Defaults to
`30000` (30 seconds). Pass `0` to disable timeout.
### option: ApiRequest.newContext.baseURL
- `baseURL` <[string]>
When using [`method: ApiRequestContext.get`], [`method: ApiRequestContext.post`], [`method: ApiRequestContext.fetch`] it takes the base URL in consideration by using the [`URL()`](https://developer.mozilla.org/en-US/docs/Web/API/URL/URL) constructor for building the corresponding URL. Examples:
* baseURL: `http://localhost:3000` and sending rquest to `/bar.html` results in `http://localhost:3000/bar.html`
* baseURL: `http://localhost:3000/foo/` and sending rquest to `./bar.html` results in `http://localhost:3000/foo/bar.html`
### option: ApiRequest.newContext.storageState
- `storageState` <[path]|[Object]>
- `cookies` <[Array]<[Object]>>
- `name` <[string]>
- `value` <[string]>
- `domain` <[string]>
- `path` <[string]>
- `expires` <[float]> Unix time in seconds.
- `httpOnly` <[boolean]>
- `secure` <[boolean]>
- `sameSite` <[SameSiteAttribute]<"Strict"|"Lax"|"None">>
- `origins` <[Array]<[Object]>>
- `origin` <[string]>
- `localStorage` <[Array]<[Object]>>
- `name` <[string]>
- `value` <[string]>
Populates context with given storage state. This option can be used to initialize context with logged-in information
obtained via [`method: BrowserContext.storageState`] or [`method: ApiRequestContext.storageState`]. Either a path to the
file with saved storage, or the value returned by one of [`method: BrowserContext.storageState`] or
[`method: ApiRequestContext.storageState`] methods.

View file

@ -1,137 +1,136 @@
# class: FetchRequest # class: ApiRequestContext
* langs: js * langs: js
This API is used for Web API testing. You can use it to trigger API endpoints, configure micro-services, prepare This API is used for the Web API testing. You can use it to trigger API endpoints, configure micro-services, prepare
environment or the service to your e2e test. When used on [Page] or a [BrowserContext], this API will automatically use environment or the service to your e2e test. When used on [Page] or a [BrowserContext], this API will automatically use
the cookies from the corresponding [BrowserContext]. This means that if you log in using this API, your e2e test the cookies from the corresponding [BrowserContext]. This means that if you log in using this API, your e2e test
will be logged in and vice versa. will be logged in and vice versa.
## async method: FetchRequest.dispose ## async method: ApiRequestContext.dispose
All responses received through [`method: FetchRequest.fetch`], [`method: FetchRequest.get`], [`method: FetchRequest.post`] All responses received through [`method: ApiRequestContext.fetch`], [`method: ApiRequestContext.get`], [`method: ApiRequestContext.post`]
and other methods are stored in the memory, so that you can later call [`method: FetchResponse.body`]. This method and other methods are stored in the memory, so that you can later call [`method: ApiResponse.body`]. This method
discards all stored responses, and makes [`method: FetchResponse.body`] throw "Response disposed" error. discards all stored responses, and makes [`method: ApiResponse.body`] throw "Response disposed" error.
## async method: FetchRequest.fetch ## async method: ApiRequestContext.fetch
- returns: <[FetchResponse]> - returns: <[ApiResponse]>
Sends HTTP(S) fetch and returns its response. The method will populate fetch cookies from the context and update Sends HTTP(S) fetch and returns its response. The method will populate fetch cookies from the context and update
context cookies from the response. The method will automatically follow redirects. context cookies from the response. The method will automatically follow redirects.
### param: FetchRequest.fetch.urlOrRequest ### param: ApiRequestContext.fetch.urlOrRequest
- `urlOrRequest` <[string]|[Request]> - `urlOrRequest` <[string]|[Request]>
Target URL or Request to get all fetch parameters from. Target URL or Request to get all fetch parameters from.
### option: FetchRequest.fetch.params ### option: ApiRequestContext.fetch.params
- `params` <[Object]<[string], [string]>> - `params` <[Object]<[string], [string]>>
Query parameters to be send with the URL. Query parameters to be send with the URL.
### option: FetchRequest.fetch.method ### option: ApiRequestContext.fetch.method
- `method` <[string]> - `method` <[string]>
If set changes the fetch method (e.g. PUT or POST). If not specified, GET method is used. If set changes the fetch method (e.g. PUT or POST). If not specified, GET method is used.
### option: FetchRequest.fetch.headers ### option: ApiRequestContext.fetch.headers
- `headers` <[Object]<[string], [string]>> - `headers` <[Object]<[string], [string]>>
Allows to set HTTP headers. Allows to set HTTP headers.
### option: FetchRequest.fetch.data = %%-fetch-option-data-%% ### option: ApiRequestContext.fetch.data = %%-fetch-option-data-%%
### option: ApiRequestContext.fetch.form = %%-fetch-option-form-%%
### option: ApiRequestContext.fetch.multipart = %%-fetch-option-multipart-%%
### option: FetchRequest.fetch.form = %%-fetch-option-form-%% ### option: ApiRequestContext.fetch.timeout
### option: FetchRequest.fetch.multipart = %%-fetch-option-multipart-%%
### option: FetchRequest.fetch.timeout
- `timeout` <[float]> - `timeout` <[float]>
Request timeout in milliseconds. Request timeout in milliseconds.
### option: FetchRequest.fetch.failOnStatusCode ### option: ApiRequestContext.fetch.failOnStatusCode
- `failOnStatusCode` <[boolean]> - `failOnStatusCode` <[boolean]>
Whether to throw on response codes other than 2xx and 3xx. By default response object is returned Whether to throw on response codes other than 2xx and 3xx. By default response object is returned
for all status codes. for all status codes.
### option: FetchRequest.fetch.ignoreHTTPSErrors = %%-context-option-ignorehttpserrors-%% ### option: ApiRequestContext.fetch.ignoreHTTPSErrors = %%-context-option-ignorehttpserrors-%%
## async method: FetchRequest.get
- returns: <[FetchResponse]> ## async method: ApiRequestContext.get
- returns: <[ApiResponse]>
Sends HTTP(S) GET request and returns its response. The method will populate fetch cookies from the context and update Sends HTTP(S) GET request and returns its response. The method will populate fetch cookies from the context and update
context cookies from the response. The method will automatically follow redirects. context cookies from the response. The method will automatically follow redirects.
### param: FetchRequest.get.url ### param: ApiRequestContext.get.url
- `url` <[string]> - `url` <[string]>
Target URL. Target URL.
### option: FetchRequest.get.params ### option: ApiRequestContext.get.params
- `params` <[Object]<[string], [string]>> - `params` <[Object]<[string], [string]>>
Query parameters to be send with the URL. Query parameters to be send with the URL.
### option: FetchRequest.get.headers ### option: ApiRequestContext.get.headers
- `headers` <[Object]<[string], [string]>> - `headers` <[Object]<[string], [string]>>
Allows to set HTTP headers. Allows to set HTTP headers.
### option: FetchRequest.get.timeout ### option: ApiRequestContext.get.timeout
- `timeout` <[float]> - `timeout` <[float]>
Request timeout in milliseconds. Request timeout in milliseconds.
### option: FetchRequest.get.failOnStatusCode ### option: ApiRequestContext.get.failOnStatusCode
- `failOnStatusCode` <[boolean]> - `failOnStatusCode` <[boolean]>
Whether to throw on response codes other than 2xx and 3xx. By default response object is returned Whether to throw on response codes other than 2xx and 3xx. By default response object is returned
for all status codes. for all status codes.
### option: FetchRequest.get.ignoreHTTPSErrors = %%-context-option-ignorehttpserrors-%% ### option: ApiRequestContext.get.ignoreHTTPSErrors = %%-context-option-ignorehttpserrors-%%
## async method: FetchRequest.post ## async method: ApiRequestContext.post
- returns: <[FetchResponse]> - returns: <[ApiResponse]>
Sends HTTP(S) fetch and returns its response. The method will populate fetch cookies from the context and update Sends HTTP(S) fetch and returns its response. The method will populate fetch cookies from the context and update
context cookies from the response. The method will automatically follow redirects. context cookies from the response. The method will automatically follow redirects.
### param: FetchRequest.post.url ### param: ApiRequestContext.post.url
- `url` <[string]> - `url` <[string]>
Target URL. Target URL.
### option: FetchRequest.post.params ### option: ApiRequestContext.post.params
- `params` <[Object]<[string], [string]>> - `params` <[Object]<[string], [string]>>
Query parameters to be send with the URL. Query parameters to be send with the URL.
### option: FetchRequest.post.headers ### option: ApiRequestContext.post.headers
- `headers` <[Object]<[string], [string]>> - `headers` <[Object]<[string], [string]>>
Allows to set HTTP headers. Allows to set HTTP headers.
### option: FetchRequest.post.data = %%-fetch-option-data-%% ### option: ApiRequestContext.post.data = %%-fetch-option-data-%%
### option: FetchRequest.post.form = %%-fetch-option-form-%% ### option: ApiRequestContext.post.form = %%-fetch-option-form-%%
### option: FetchRequest.post.multipart = %%-fetch-option-multipart-%% ### option: ApiRequestContext.post.multipart = %%-fetch-option-multipart-%%
### option: FetchRequest.post.timeout ### option: ApiRequestContext.post.timeout
- `timeout` <[float]> - `timeout` <[float]>
Request timeout in milliseconds. Request timeout in milliseconds.
### option: FetchRequest.post.failOnStatusCode ### option: ApiRequestContext.post.failOnStatusCode
- `failOnStatusCode` <[boolean]> - `failOnStatusCode` <[boolean]>
Whether to throw on response codes other than 2xx and 3xx. By default response object is returned Whether to throw on response codes other than 2xx and 3xx. By default response object is returned
for all status codes. for all status codes.
### option: FetchRequest.post.ignoreHTTPSErrors = %%-context-option-ignorehttpserrors-%% ### option: ApiRequestContext.post.ignoreHTTPSErrors = %%-context-option-ignorehttpserrors-%%
## async method: FetchRequest.storageState ## async method: ApiRequestContext.storageState
- returns: <[Object]> - returns: <[Object]>
- `cookies` <[Array]<[Object]>> - `cookies` <[Array]<[Object]>>
- `name` <[string]> - `name` <[string]>
@ -150,4 +149,4 @@ for all status codes.
Returns storage state for this request context, contains current cookies and local storage snapshot if it was passed to the constructor. Returns storage state for this request context, contains current cookies and local storage snapshot if it was passed to the constructor.
### option: FetchRequest.storageState.path = %%-storagestate-option-path-%% ### option: ApiRequestContext.storageState.path = %%-storagestate-option-path-%%

View file

@ -1,23 +1,23 @@
# class: FetchResponse # class: ApiResponse
* langs: js * langs: js
[FetchResponse] class represents responses received from [`method: FetchRequest.fetch`]. [ApiResponse] class represents responses received from [`method: ApiRequestContext.fetch`].
## async method: FetchResponse.body ## async method: ApiResponse.body
- returns: <[Buffer]> - returns: <[Buffer]>
Returns the buffer with response body. Returns the buffer with response body.
## async method: FetchResponse.dispose ## async method: ApiResponse.dispose
Disposes the body of this response. If not called then the body will stay in memory until the context closes. Disposes the body of this response. If not called then the body will stay in memory until the context closes.
## method: FetchResponse.headers ## method: ApiResponse.headers
- returns: <[Object]<[string], [string]>> - returns: <[Object]<[string], [string]>>
An object with all the response HTTP headers associated with this response. An object with all the response HTTP headers associated with this response.
## method: FetchResponse.headersArray ## method: ApiResponse.headersArray
- returns: <[Array]<[Object]>> - returns: <[Array]<[Object]>>
- `name` <[string]> Name of the header. - `name` <[string]> Name of the header.
- `value` <[string]> Value of the header. - `value` <[string]> Value of the header.
@ -25,7 +25,7 @@ An object with all the response HTTP headers associated with this response.
An array with all the request HTTP headers associated with this response. Header names are not lower-cased. An array with all the request HTTP headers associated with this response. Header names are not lower-cased.
Headers with multiple entries, such as `Set-Cookie`, appear in the array multiple times. Headers with multiple entries, such as `Set-Cookie`, appear in the array multiple times.
## async method: FetchResponse.json ## async method: ApiResponse.json
* langs: js, python * langs: js, python
- returns: <[Serializable]> - returns: <[Serializable]>
@ -33,7 +33,7 @@ Returns the JSON representation of response body.
This method will throw if the response body is not parsable via `JSON.parse`. This method will throw if the response body is not parsable via `JSON.parse`.
## async method: FetchResponse.json ## async method: ApiResponse.json
* langs: csharp * langs: csharp
- returns: <[null]|[JsonElement]> - returns: <[null]|[JsonElement]>
@ -41,27 +41,27 @@ Returns the JSON representation of response body.
This method will throw if the response body is not parsable via `JSON.parse`. This method will throw if the response body is not parsable via `JSON.parse`.
## method: FetchResponse.ok ## method: ApiResponse.ok
- returns: <[boolean]> - returns: <[boolean]>
Contains a boolean stating whether the response was successful (status in the range 200-299) or not. Contains a boolean stating whether the response was successful (status in the range 200-299) or not.
## method: FetchResponse.status ## method: ApiResponse.status
- returns: <[int]> - returns: <[int]>
Contains the status code of the response (e.g., 200 for a success). Contains the status code of the response (e.g., 200 for a success).
## method: FetchResponse.statusText ## method: ApiResponse.statusText
- returns: <[string]> - returns: <[string]>
Contains the status text of the response (e.g. usually an "OK" for a success). Contains the status text of the response (e.g. usually an "OK" for a success).
## async method: FetchResponse.text ## async method: ApiResponse.text
- returns: <[string]> - returns: <[string]>
Returns the text representation of response body. Returns the text representation of response body.
## method: FetchResponse.url ## method: ApiResponse.url
- returns: <[string]> - returns: <[string]>
Contains the URL of the response. Contains the URL of the response.

View file

@ -851,7 +851,7 @@ Returns all open pages in the context.
## property: BrowserContext.request ## property: BrowserContext.request
* langs: js * langs: js
- type: <[FetchRequest]> - type: <[ApiRequestContext]>
API testing helper associated with this context. Requests made with this API will use context cookies. API testing helper associated with this context. Requests made with this API will use context cookies.

View file

@ -2416,7 +2416,7 @@ last redirect.
## property: Page.request ## property: Page.request
* langs: js * langs: js
- type: <[FetchRequest]> - type: <[ApiRequestContext]>
API testing helper associated with this page. Requests made with this API will use page cookies. API testing helper associated with this page. Requests made with this API will use page cookies.

View file

@ -214,56 +214,11 @@ except TimeoutError as e:
This object can be used to launch or connect to Firefox, returning instances of [Browser]. This object can be used to launch or connect to Firefox, returning instances of [Browser].
## async method: Playwright.newRequest ## property: Playwright.request
* langs: js * langs: js
- returns: <[FetchRequest]> - type: <[ApiRequest]>
**experimental** Creates new instances of [FetchRequest]. Exposes API that can be used for the Web API testing.
### option: Playwright.newRequest.useragent = %%-context-option-useragent-%%
### option: Playwright.newRequest.extraHTTPHeaders = %%-context-option-extrahttpheaders-%%
### option: Playwright.newRequest.httpCredentials = %%-context-option-httpcredentials-%%
### option: Playwright.newRequest.proxy = %%-browser-option-proxy-%%
### option: Playwright.newRequest.timeout
- `timeout` <[float]>
Maximum time in milliseconds to wait for the response. Defaults to
`30000` (30 seconds). Pass `0` to disable timeout.
### option: Playwright.newRequest.ignoreHTTPSErrors = %%-context-option-ignorehttpserrors-%%
### option: Playwright.newRequest.baseURL
- `baseURL` <[string]>
When using [`method: FetchRequest.get`], [`method: FetchRequest.post`], [`method: FetchRequest.fetch`] it takes the base URL in consideration by using the [`URL()`](https://developer.mozilla.org/en-US/docs/Web/API/URL/URL) constructor for building the corresponding URL. Examples:
* baseURL: `http://localhost:3000` and sending rquest to `/bar.html` results in `http://localhost:3000/bar.html`
* baseURL: `http://localhost:3000/foo/` and sending rquest to `./bar.html` results in `http://localhost:3000/foo/bar.html`
### option: Playwright.newRequest.storageState
- `storageState` <[path]|[Object]>
- `cookies` <[Array]<[Object]>>
- `name` <[string]>
- `value` <[string]>
- `domain` <[string]>
- `path` <[string]>
- `expires` <[float]> Unix time in seconds.
- `httpOnly` <[boolean]>
- `secure` <[boolean]>
- `sameSite` <[SameSiteAttribute]<"Strict"|"Lax"|"None">>
- `origins` <[Array]<[Object]>>
- `origin` <[string]>
- `localStorage` <[Array]<[Object]>>
- `name` <[string]>
- `value` <[string]>
Populates context with given storage state. This option can be used to initialize context with logged-in information
obtained via [`method: BrowserContext.storageState`] or [`method: FetchRequest.storageState`]. Either a path to the
file with saved storage, or the value returned by one of [`method: BrowserContext.storageState`] or
[`method: FetchRequest.storageState`] methods.
## property: Playwright.selectors ## property: Playwright.selectors
- type: <[Selectors]> - type: <[Selectors]>

View file

@ -222,9 +222,9 @@ is resolved relative to the current working directory.
### option: Route.fulfill.response ### option: Route.fulfill.response
* langs: js * langs: js
- `response` <[FetchResponse]> - `response` <[ApiResponse]>
[FetchResponse] to fulfill route's request with. Individual fields of the response (such as headers) can be overridden using fulfill options. [ApiResponse] to fulfill route's request with. Individual fields of the response (such as headers) can be overridden using fulfill options.
## method: Route.request ## method: Route.request
- returns: <[Request]> - returns: <[Request]>

View file

@ -34,7 +34,7 @@ export { Frame } from './frame';
export { Keyboard, Mouse, Touchscreen } from './input'; export { Keyboard, Mouse, Touchscreen } from './input';
export { JSHandle } from './jsHandle'; export { JSHandle } from './jsHandle';
export { Request, Response, Route, WebSocket } from './network'; export { Request, Response, Route, WebSocket } from './network';
export { FetchRequest, FetchResponse } from './fetch'; export { Fetch as ApiRequest, FetchRequest as ApiRequestContext, FetchResponse as ApiResponse } from './fetch';
export { Page } from './page'; export { Page } from './page';
export { Selectors } from './selectors'; export { Selectors } from './selectors';
export { Tracing } from './tracing'; export { Tracing } from './tracing';

View file

@ -27,6 +27,7 @@ import { ChannelOwner } from './channelOwner';
import * as network from './network'; import * as network from './network';
import { RawHeaders } from './network'; import { RawHeaders } from './network';
import { FilePayload, Headers, StorageState } from './types'; import { FilePayload, Headers, StorageState } from './types';
import { Playwright } from './playwright';
export type FetchOptions = { export type FetchOptions = {
params?: { [key: string]: string; }, params?: { [key: string]: string; },
@ -40,7 +41,32 @@ export type FetchOptions = {
ignoreHTTPSErrors?: boolean, ignoreHTTPSErrors?: boolean,
}; };
export class FetchRequest extends ChannelOwner<channels.FetchRequestChannel, channels.FetchRequestInitializer> implements api.FetchRequest { type NewContextOptions = Omit<channels.PlaywrightNewRequestOptions, 'extraHTTPHeaders' | 'storageState'> & {
extraHTTPHeaders?: Headers,
storageState?: string | StorageState,
};
export class Fetch implements api.ApiRequest {
private _playwright: Playwright;
constructor(playwright: Playwright) {
this._playwright = playwright;
}
async newContext(options: NewContextOptions = {}): Promise<FetchRequest> {
return await this._playwright._wrapApiCall(async (channel: channels.PlaywrightChannel) => {
const storageState = typeof options.storageState === 'string' ?
JSON.parse(await fs.promises.readFile(options.storageState, 'utf8')) :
options.storageState;
return FetchRequest.from((await channel.newRequest({
...options,
extraHTTPHeaders: options.extraHTTPHeaders ? headersObjectToArray(options.extraHTTPHeaders) : undefined,
storageState,
})).request);
});
}
}
export class FetchRequest extends ChannelOwner<channels.FetchRequestChannel, channels.FetchRequestInitializer> implements api.ApiRequestContext {
static from(channel: channels.FetchRequestChannel): FetchRequest { static from(channel: channels.FetchRequestChannel): FetchRequest {
return (channel as any)._object; return (channel as any)._object;
} }
@ -153,7 +179,7 @@ export class FetchRequest extends ChannelOwner<channels.FetchRequestChannel, cha
} }
} }
export class FetchResponse implements api.FetchResponse { export class FetchResponse implements api.ApiResponse {
private readonly _initializer: channels.FetchResponse; private readonly _initializer: channels.FetchResponse;
private readonly _headers: RawHeaders; private readonly _headers: RawHeaders;
private readonly _request: FetchRequest; private readonly _request: FetchRequest;

View file

@ -320,7 +320,7 @@ export class Route extends ChannelOwner<channels.RouteChannel, channels.RouteIni
}); });
} }
async fulfill(options: { response?: api.Response | api.FetchResponse, status?: number, headers?: Headers, contentType?: string, body?: string | Buffer, path?: string } = {}) { async fulfill(options: { response?: api.Response | api.ApiResponse, 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 useInterceptedResponseBody; let useInterceptedResponseBody;
let fetchResponseUid; let fetchResponseUid;

View file

@ -15,20 +15,18 @@
*/ */
import dns from 'dns'; import dns from 'dns';
import fs from 'fs';
import net from 'net'; import net from 'net';
import util from 'util'; import util from 'util';
import * as channels from '../protocol/channels'; import * as channels from '../protocol/channels';
import { TimeoutError } from '../utils/errors'; import { TimeoutError } from '../utils/errors';
import { createSocket } from '../utils/netUtils'; import { createSocket } from '../utils/netUtils';
import { headersObjectToArray } from '../utils/utils';
import { Android } from './android'; import { Android } from './android';
import { BrowserType } from './browserType'; import { BrowserType } from './browserType';
import { ChannelOwner } from './channelOwner'; import { ChannelOwner } from './channelOwner';
import { Electron } from './electron'; import { Electron } from './electron';
import { FetchRequest } from './fetch'; import { Fetch } from './fetch';
import { Selectors, SelectorsOwner, sharedSelectors } from './selectors'; import { Selectors, SelectorsOwner, sharedSelectors } from './selectors';
import { NewRequestOptions, Size } from './types'; import { Size } from './types';
const dnsLookupAsync = util.promisify(dns.lookup); const dnsLookupAsync = util.promisify(dns.lookup);
type DeviceDescriptor = { type DeviceDescriptor = {
@ -49,6 +47,7 @@ export class Playwright extends ChannelOwner<channels.PlaywrightChannel, channel
readonly webkit: BrowserType; readonly webkit: BrowserType;
readonly devices: Devices; readonly devices: Devices;
readonly selectors: Selectors; readonly selectors: Selectors;
readonly request: Fetch;
readonly errors: { TimeoutError: typeof TimeoutError }; readonly errors: { TimeoutError: typeof TimeoutError };
private _selectorsOwner: SelectorsOwner; private _selectorsOwner: SelectorsOwner;
private _sockets = new Map<string, net.Socket>(); private _sockets = new Map<string, net.Socket>();
@ -56,6 +55,7 @@ export class Playwright extends ChannelOwner<channels.PlaywrightChannel, channel
constructor(parent: ChannelOwner, type: string, guid: string, initializer: channels.PlaywrightInitializer) { constructor(parent: ChannelOwner, type: string, guid: string, initializer: channels.PlaywrightInitializer) {
super(parent, type, guid, initializer); super(parent, type, guid, initializer);
this.request = new Fetch(this);
this.chromium = BrowserType.from(initializer.chromium); this.chromium = BrowserType.from(initializer.chromium);
this.firefox = BrowserType.from(initializer.firefox); this.firefox = BrowserType.from(initializer.firefox);
this.webkit = BrowserType.from(initializer.webkit); this.webkit = BrowserType.from(initializer.webkit);
@ -71,19 +71,6 @@ export class Playwright extends ChannelOwner<channels.PlaywrightChannel, channel
this.selectors._addChannel(this._selectorsOwner); this.selectors._addChannel(this._selectorsOwner);
} }
async newRequest(options: NewRequestOptions = {}): Promise<FetchRequest> {
return await this._wrapApiCall(async (channel: channels.PlaywrightChannel) => {
const storageState = typeof options.storageState === 'string' ?
JSON.parse(await fs.promises.readFile(options.storageState, 'utf8')) :
options.storageState;
return FetchRequest.from((await channel.newRequest({
...options,
extraHTTPHeaders: options.extraHTTPHeaders ? headersObjectToArray(options.extraHTTPHeaders) : undefined,
storageState,
})).request);
});
}
_enablePortForwarding(redirectPortForTest?: number) { _enablePortForwarding(redirectPortForTest?: number) {
this._redirectPortForTest = redirectPortForTest; this._redirectPortForTest = redirectPortForTest;
this._channel.on('socksRequested', ({ uid, host, port }) => this._onSocksRequested(uid, host, port)); this._channel.on('socksRequested', ({ uid, host, port }) => this._onSocksRequested(uid, host, port));

View file

@ -118,8 +118,3 @@ export type SelectorEngine = {
export type RemoteAddr = channels.RemoteAddr; export type RemoteAddr = channels.RemoteAddr;
export type SecurityDetails = channels.SecurityDetails; export type SecurityDetails = channels.SecurityDetails;
export type NewRequestOptions = Omit<channels.PlaywrightNewRequestOptions, 'extraHTTPHeaders' | 'storageState'> & {
extraHTTPHeaders?: Headers,
storageState?: string | StorageState,
};

View file

@ -885,4 +885,4 @@ it('context request should export same storage state as context', async ({ conte
expect(requestState).toEqual(contextState); expect(requestState).toEqual(contextState);
const pageState = await page.request.storageState(); const pageState = await page.request.storageState();
expect(pageState).toEqual(contextState); expect(pageState).toEqual(contextState);
}); });

View file

@ -16,23 +16,23 @@
import fs from 'fs'; import fs from 'fs';
import http from 'http'; import http from 'http';
import { FetchRequest } from '../index'; import { ApiRequestContext } from '../index';
import { expect, playwrightTest } from './config/browserTest'; import { expect, playwrightTest } from './config/browserTest';
export type GlobalFetchFixtures = { export type GlobalFetchFixtures = {
request: FetchRequest; request: ApiRequestContext;
}; };
const it = playwrightTest.extend<GlobalFetchFixtures>({ const it = playwrightTest.extend<GlobalFetchFixtures>({
request: async ({ playwright }, use) => { request: async ({ playwright }, use) => {
const request = await playwright.newRequest({ ignoreHTTPSErrors: true }); const request = await playwright.request.newContext({ ignoreHTTPSErrors: true });
await use(request); await use(request);
await request.dispose(); await request.dispose();
}, },
}); });
type PromiseArg<T> = T extends Promise<infer R> ? R : never; type PromiseArg<T> = T extends Promise<infer R> ? R : never;
type StorageStateType = PromiseArg<ReturnType<FetchRequest['storageState']>>; type StorageStateType = PromiseArg<ReturnType<ApiRequestContext['storageState']>>;
it.skip(({ mode }) => mode !== 'default'); it.skip(({ mode }) => mode !== 'default');
@ -235,7 +235,7 @@ it('should preserve local storage on import/export of storage state', async ({ p
}, },
] ]
}; };
const request = await playwright.newRequest({ storageState }); const request = await playwright.request.newContext({ storageState });
await request.get(server.EMPTY_PAGE); await request.get(server.EMPTY_PAGE);
const exportedState = await request.storageState(); const exportedState = await request.storageState();
expect(exportedState).toEqual(storageState); expect(exportedState).toEqual(storageState);
@ -279,7 +279,7 @@ it('should send cookies from storage state', async ({ playwright, server }) => {
], ],
'origins': [] 'origins': []
}; };
const request = await playwright.newRequest({ storageState }); const request = await playwright.request.newContext({ storageState });
const [serverRequest] = await Promise.all([ const [serverRequest] = await Promise.all([
server.waitForRequest('/first/second/third/not_found.html'), server.waitForRequest('/first/second/third/not_found.html'),
request.get(`http://www.a.b.one.com:${server.PORT}/first/second/third/not_found.html`) request.get(`http://www.a.b.one.com:${server.PORT}/first/second/third/not_found.html`)
@ -304,7 +304,7 @@ it('storage state should round-trip through file', async ({ playwright, server }
'origins': [] 'origins': []
}; };
const request1 = await playwright.newRequest({ storageState }); const request1 = await playwright.request.newContext({ storageState });
const path = testInfo.outputPath('storage-state.json'); const path = testInfo.outputPath('storage-state.json');
const state1 = await request1.storageState({ path }); const state1 = await request1.storageState({ path });
expect(state1).toEqual(storageState); expect(state1).toEqual(storageState);
@ -312,7 +312,7 @@ it('storage state should round-trip through file', async ({ playwright, server }
const written = await fs.promises.readFile(path, 'utf8'); const written = await fs.promises.readFile(path, 'utf8');
expect(JSON.stringify(state1, undefined, 2)).toBe(written); expect(JSON.stringify(state1, undefined, 2)).toBe(written);
const request2 = await playwright.newRequest({ storageState: path }); const request2 = await playwright.request.newContext({ storageState: path });
const state2 = await request2.storageState(); const state2 = await request2.storageState();
expect(state2).toEqual(storageState); expect(state2).toEqual(storageState);
}); });

View file

@ -40,7 +40,7 @@ it.afterAll(() => {
for (const method of ['get', 'post', 'fetch']) { for (const method of ['get', 'post', 'fetch']) {
it(`${method} should work`, async ({ playwright, server }) => { it(`${method} should work`, async ({ playwright, server }) => {
const request = await playwright.newRequest(); const request = await playwright.request.newContext();
const response = await request[method](server.PREFIX + '/simple.json'); const response = await request[method](server.PREFIX + '/simple.json');
expect(response.url()).toBe(server.PREFIX + '/simple.json'); expect(response.url()).toBe(server.PREFIX + '/simple.json');
expect(response.status()).toBe(200); expect(response.status()).toBe(200);
@ -53,7 +53,7 @@ for (const method of ['get', 'post', 'fetch']) {
}); });
it(`should dispose global ${method} request`, async function({ playwright, context, server }) { it(`should dispose global ${method} request`, async function({ playwright, context, server }) {
const request = await playwright.newRequest(); const request = await playwright.request.newContext();
const response = await request.get(server.PREFIX + '/simple.json'); const response = await request.get(server.PREFIX + '/simple.json');
expect(await response.json()).toEqual({ foo: 'bar' }); expect(await response.json()).toEqual({ foo: 'bar' });
await request.dispose(); await request.dispose();
@ -63,7 +63,7 @@ for (const method of ['get', 'post', 'fetch']) {
} }
it('should support global userAgent option', async ({ playwright, server }) => { it('should support global userAgent option', async ({ playwright, server }) => {
const request = await playwright.newRequest({ userAgent: 'My Agent' }); const request = await playwright.request.newContext({ userAgent: 'My Agent' });
const [serverRequest, response] = await Promise.all([ const [serverRequest, response] = await Promise.all([
server.waitForRequest('/empty.html'), server.waitForRequest('/empty.html'),
request.get(server.EMPTY_PAGE) request.get(server.EMPTY_PAGE)
@ -74,7 +74,7 @@ it('should support global userAgent option', async ({ playwright, server }) => {
}); });
it('should support global timeout option', async ({ playwright, server }) => { it('should support global timeout option', async ({ playwright, server }) => {
const request = await playwright.newRequest({ timeout: 1 }); const request = await playwright.request.newContext({ timeout: 1 });
server.setRoute('/empty.html', (req, res) => {}); server.setRoute('/empty.html', (req, res) => {});
const error = await request.get(server.EMPTY_PAGE).catch(e => e); const error = await request.get(server.EMPTY_PAGE).catch(e => e);
expect(error.message).toContain('Request timed out after 1ms'); expect(error.message).toContain('Request timed out after 1ms');
@ -83,7 +83,7 @@ it('should support global timeout option', async ({ playwright, server }) => {
it('should propagate extra http headers with redirects', async ({ playwright, server }) => { it('should propagate extra http headers with redirects', async ({ playwright, server }) => {
server.setRedirect('/a/redirect1', '/b/c/redirect2'); server.setRedirect('/a/redirect1', '/b/c/redirect2');
server.setRedirect('/b/c/redirect2', '/simple.json'); server.setRedirect('/b/c/redirect2', '/simple.json');
const request = await playwright.newRequest({ extraHTTPHeaders: { 'My-Secret': 'Value' } }); const request = await playwright.request.newContext({ extraHTTPHeaders: { 'My-Secret': 'Value' } });
const [req1, req2, req3] = await Promise.all([ const [req1, req2, req3] = await Promise.all([
server.waitForRequest('/a/redirect1'), server.waitForRequest('/a/redirect1'),
server.waitForRequest('/b/c/redirect2'), server.waitForRequest('/b/c/redirect2'),
@ -97,12 +97,12 @@ it('should propagate extra http headers with redirects', async ({ playwright, se
it('should support global httpCredentials option', async ({ playwright, server }) => { it('should support global httpCredentials option', async ({ playwright, server }) => {
server.setAuth('/empty.html', 'user', 'pass'); server.setAuth('/empty.html', 'user', 'pass');
const request1 = await playwright.newRequest(); const request1 = await playwright.request.newContext();
const response1 = await request1.get(server.EMPTY_PAGE); const response1 = await request1.get(server.EMPTY_PAGE);
expect(response1.status()).toBe(401); expect(response1.status()).toBe(401);
await request1.dispose(); await request1.dispose();
const request2 = await playwright.newRequest({ httpCredentials: { username: 'user', password: 'pass' } }); const request2 = await playwright.request.newContext({ httpCredentials: { username: 'user', password: 'pass' } });
const response2 = await request2.get(server.EMPTY_PAGE); const response2 = await request2.get(server.EMPTY_PAGE);
expect(response2.status()).toBe(200); expect(response2.status()).toBe(200);
await request2.dispose(); await request2.dispose();
@ -110,7 +110,7 @@ it('should support global httpCredentials option', async ({ playwright, server }
it('should return error with wrong credentials', async ({ playwright, server }) => { it('should return error with wrong credentials', async ({ playwright, server }) => {
server.setAuth('/empty.html', 'user', 'pass'); server.setAuth('/empty.html', 'user', 'pass');
const request = await playwright.newRequest({ httpCredentials: { username: 'user', password: 'wrong' } }); const request = await playwright.request.newContext({ httpCredentials: { username: 'user', password: 'wrong' } });
const response2 = await request.get(server.EMPTY_PAGE); const response2 = await request.get(server.EMPTY_PAGE);
expect(response2.status()).toBe(401); expect(response2.status()).toBe(401);
}); });
@ -122,7 +122,7 @@ it('should pass proxy credentials', async ({ playwright, server, proxyServer })
auth = req.headers['proxy-authorization']; auth = req.headers['proxy-authorization'];
return !!auth; return !!auth;
}); });
const request = await playwright.newRequest({ const request = await playwright.request.newContext({
proxy: { server: `localhost:${proxyServer.PORT}`, username: 'user', password: 'secret' } proxy: { server: `localhost:${proxyServer.PORT}`, username: 'user', password: 'secret' }
}); });
const response = await request.get('http://non-existent.com/simple.json'); const response = await request.get('http://non-existent.com/simple.json');
@ -133,19 +133,19 @@ it('should pass proxy credentials', async ({ playwright, server, proxyServer })
}); });
it('should support global ignoreHTTPSErrors option', async ({ playwright, httpsServer }) => { it('should support global ignoreHTTPSErrors option', async ({ playwright, httpsServer }) => {
const request = await playwright.newRequest({ ignoreHTTPSErrors: true }); const request = await playwright.request.newContext({ ignoreHTTPSErrors: true });
const response = await request.get(httpsServer.EMPTY_PAGE); const response = await request.get(httpsServer.EMPTY_PAGE);
expect(response.status()).toBe(200); expect(response.status()).toBe(200);
}); });
it('should resolve url relative to gobal baseURL option', async ({ playwright, server }) => { it('should resolve url relative to gobal baseURL option', async ({ playwright, server }) => {
const request = await playwright.newRequest({ baseURL: server.PREFIX }); const request = await playwright.request.newContext({ baseURL: server.PREFIX });
const response = await request.get('/empty.html'); const response = await request.get('/empty.html');
expect(response.url()).toBe(server.EMPTY_PAGE); expect(response.url()).toBe(server.EMPTY_PAGE);
}); });
it('should set playwright as user-agent', async ({ playwright, server }) => { it('should set playwright as user-agent', async ({ playwright, server }) => {
const request = await playwright.newRequest(); const request = await playwright.request.newContext();
const [serverRequest] = await Promise.all([ const [serverRequest] = await Promise.all([
server.waitForRequest('/empty.html'), server.waitForRequest('/empty.html'),
request.get(server.EMPTY_PAGE) request.get(server.EMPTY_PAGE)

View file

@ -197,7 +197,7 @@ it('should include the origin header', async ({ page, server, isAndroid }) => {
it('should fulfill with global fetch result', async ({ playwright, page, server, isElectron }) => { it('should fulfill with global fetch result', async ({ playwright, page, server, isElectron }) => {
it.fixme(isElectron, 'error: Browser context management is not supported.'); it.fixme(isElectron, 'error: Browser context management is not supported.');
await page.route('**/*', async route => { await page.route('**/*', async route => {
const request = await playwright.newRequest(); const request = await playwright.request.newContext();
const response = await request.get(server.PREFIX + '/simple.json'); const response = await request.get(server.PREFIX + '/simple.json');
route.fulfill({ response }); route.fulfill({ response });
}); });
@ -277,7 +277,7 @@ it('should fulfill with fetch response that has multiple set-cookie', async ({ p
res.end(); res.end();
}); });
await page.route('**/empty.html', async route => { await page.route('**/empty.html', async route => {
const request = await playwright.newRequest(); const request = await playwright.request.newContext();
const response = await request.fetch(route.request()); const response = await request.fetch(route.request());
route.fulfill({ response }); route.fulfill({ response });
}); });

872
types/types.d.ts vendored
View file

@ -2753,7 +2753,7 @@ export interface Page {
/** /**
* API testing helper associated with this page. Requests made with this API will use page cookies. * API testing helper associated with this page. Requests made with this API will use page cookies.
*/ */
request: FetchRequest; request: ApiRequestContext;
/** /**
* Routing provides the capability to modify network requests that are made by a page. * Routing provides the capability to modify network requests that are made by a page.
@ -6455,7 +6455,7 @@ export interface BrowserContext {
/** /**
* API testing helper associated with this context. Requests made with this API will use context cookies. * API testing helper associated with this context. Requests made with this API will use context cookies.
*/ */
request: FetchRequest; request: ApiRequestContext;
/** /**
* Routing provides the capability to modify network requests that are made by any page in the browser context. Once route * Routing provides the capability to modify network requests that are made by any page in the browser context. Once route
@ -11589,6 +11589,441 @@ export interface AndroidWebView {
pkg(): string; pkg(): string;
} }
/**
* Exposes API that can be used for the Web API testing.
*/
export interface ApiRequest {
/**
* **experimental** Creates new instances of [ApiRequestContext].
* @param options
*/
newContext(options?: {
/**
* When using
* [apiRequestContext.get(url[, options])](https://playwright.dev/docs/api/class-apirequestcontext#api-request-context-get),
* [apiRequestContext.post(url[, options])](https://playwright.dev/docs/api/class-apirequestcontext#api-request-context-post),
* [apiRequestContext.fetch(urlOrRequest[, options])](https://playwright.dev/docs/api/class-apirequestcontext#api-request-context-fetch)
* it takes the base URL in consideration by using the [`URL()`](https://developer.mozilla.org/en-US/docs/Web/API/URL/URL)
* constructor for building the corresponding URL. Examples:
* - baseURL: `http://localhost:3000` and sending rquest to `/bar.html` results in `http://localhost:3000/bar.html`
* - baseURL: `http://localhost:3000/foo/` and sending rquest to `./bar.html` results in
* `http://localhost:3000/foo/bar.html`
*/
baseURL?: string;
/**
* An object containing additional HTTP headers to be sent with every request.
*/
extraHTTPHeaders?: { [key: string]: string; };
/**
* Credentials for [HTTP authentication](https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication).
*/
httpCredentials?: {
username: string;
password: string;
};
/**
* Whether to ignore HTTPS errors when sending network requests. Defaults to `false`.
*/
ignoreHTTPSErrors?: boolean;
/**
* Network proxy settings.
*/
proxy?: {
/**
* Proxy to be used for all requests. HTTP and SOCKS proxies are supported, for example `http://myproxy.com:3128` or
* `socks5://myproxy.com:3128`. Short form `myproxy.com:3128` is considered an HTTP proxy.
*/
server: string;
/**
* Optional coma-separated domains to bypass proxy, for example `".com, chromium.org, .domain.com"`.
*/
bypass?: string;
/**
* Optional username to use if HTTP proxy requires authentication.
*/
username?: string;
/**
* Optional password to use if HTTP proxy requires authentication.
*/
password?: string;
};
/**
* Populates context with given storage state. This option can be used to initialize context with logged-in information
* obtained via
* [browserContext.storageState([options])](https://playwright.dev/docs/api/class-browsercontext#browser-context-storage-state)
* or
* [apiRequestContext.storageState([options])](https://playwright.dev/docs/api/class-apirequestcontext#api-request-context-storage-state).
* Either a path to the file with saved storage, or the value returned by one of
* [browserContext.storageState([options])](https://playwright.dev/docs/api/class-browsercontext#browser-context-storage-state)
* or
* [apiRequestContext.storageState([options])](https://playwright.dev/docs/api/class-apirequestcontext#api-request-context-storage-state)
* methods.
*/
storageState?: string|{
cookies: Array<{
name: string;
value: string;
domain: string;
path: string;
/**
* Unix time in seconds.
*/
expires: number;
httpOnly: boolean;
secure: boolean;
sameSite: "Strict"|"Lax"|"None";
}>;
origins: Array<{
origin: string;
localStorage: Array<{
name: string;
value: string;
}>;
}>;
};
/**
* Maximum time in milliseconds to wait for the response. Defaults to `30000` (30 seconds). Pass `0` to disable timeout.
*/
timeout?: number;
/**
* Specific user agent to use in this context.
*/
userAgent?: string;
}): Promise<ApiRequestContext>;
}
/**
* This API is used for the Web API testing. You can use it to trigger API endpoints, configure micro-services, prepare
* environment or the service to your e2e test. When used on [Page] or a [BrowserContext], this API will automatically use
* the cookies from the corresponding [BrowserContext]. This means that if you log in using this API, your e2e test will be
* logged in and vice versa.
*/
export interface ApiRequestContext {
/**
* All responses received through
* [apiRequestContext.fetch(urlOrRequest[, options])](https://playwright.dev/docs/api/class-apirequestcontext#api-request-context-fetch),
* [apiRequestContext.get(url[, options])](https://playwright.dev/docs/api/class-apirequestcontext#api-request-context-get),
* [apiRequestContext.post(url[, options])](https://playwright.dev/docs/api/class-apirequestcontext#api-request-context-post)
* and other methods are stored in the memory, so that you can later call
* [apiResponse.body()](https://playwright.dev/docs/api/class-apiresponse#api-response-body). This method discards all
* stored responses, and makes [apiResponse.body()](https://playwright.dev/docs/api/class-apiresponse#api-response-body)
* throw "Response disposed" error.
*/
dispose(): Promise<void>;
/**
* Sends HTTP(S) fetch and returns its response. The method will populate fetch cookies from the context and update context
* cookies from the response. The method will automatically follow redirects.
* @param urlOrRequest Target URL or Request to get all fetch parameters from.
* @param options
*/
fetch(urlOrRequest: string|Request, 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.
*/
headers?: { [key: string]: string; };
/**
* Whether to ignore HTTPS errors when sending network requests. Defaults to `false`.
*/
ignoreHTTPSErrors?: boolean;
/**
* If set changes the fetch method (e.g. PUT or POST). If not specified, GET method is used.
*/
method?: string;
/**
* 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?: { [key: string]: string|number|boolean|ReadStream|{
/**
* File name
*/
name: string;
/**
* File type
*/
mimeType: string;
/**
* File content
*/
buffer: Buffer;
}; };
/**
* Query parameters to be send with the URL.
*/
params?: { [key: string]: string; };
/**
* Request timeout in milliseconds.
*/
timeout?: number;
}): Promise<ApiResponse>;
/**
* Sends HTTP(S) GET request and returns its response. The method will populate fetch cookies from the context and update
* context cookies from the response. The method will automatically follow redirects.
* @param url Target URL.
* @param options
*/
get(url: string, 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.
*/
headers?: { [key: string]: string; };
/**
* Whether to ignore HTTPS errors when sending network requests. Defaults to `false`.
*/
ignoreHTTPSErrors?: boolean;
/**
* Query parameters to be send with the URL.
*/
params?: { [key: string]: string; };
/**
* Request timeout in milliseconds.
*/
timeout?: number;
}): Promise<ApiResponse>;
/**
* Sends HTTP(S) fetch and returns its response. The method will populate fetch cookies from the context and update context
* cookies from the response. The method will automatically follow redirects.
* @param url Target URL.
* @param options
*/
post(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.
*/
headers?: { [key: string]: string; };
/**
* Whether to ignore HTTPS errors when sending network requests. Defaults to `false`.
*/
ignoreHTTPSErrors?: boolean;
/**
* 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?: { [key: string]: string|number|boolean|ReadStream|{
/**
* File name
*/
name: string;
/**
* File type
*/
mimeType: string;
/**
* File content
*/
buffer: Buffer;
}; };
/**
* Query parameters to be send with the URL.
*/
params?: { [key: string]: string; };
/**
* Request timeout in milliseconds.
*/
timeout?: number;
}): Promise<ApiResponse>;
/**
* Returns storage state for this request context, contains current cookies and local storage snapshot if it was passed to
* the constructor.
* @param options
*/
storageState(options?: {
/**
* The file path to save the storage state to. If `path` is a relative path, then it is resolved relative to current
* working directory. If no path is provided, storage state is still returned, but won't be saved to the disk.
*/
path?: string;
}): Promise<{
cookies: Array<{
name: string;
value: string;
domain: string;
path: string;
/**
* Unix time in seconds.
*/
expires: number;
httpOnly: boolean;
secure: boolean;
sameSite: "Strict"|"Lax"|"None";
}>;
origins: Array<{
origin: string;
localStorage: Array<{
name: string;
value: string;
}>;
}>;
}>;
}
/**
* [ApiResponse] class represents responses received from
* [apiRequestContext.fetch(urlOrRequest[, options])](https://playwright.dev/docs/api/class-apirequestcontext#api-request-context-fetch).
*/
export interface ApiResponse {
/**
* Returns the buffer with response body.
*/
body(): Promise<Buffer>;
/**
* Disposes the body of this response. If not called then the body will stay in memory until the context closes.
*/
dispose(): Promise<void>;
/**
* An object with all the response HTTP headers associated with this response.
*/
headers(): { [key: string]: string; };
/**
* An array with all the request HTTP headers associated with this response. Header names are not lower-cased. Headers with
* multiple entries, such as `Set-Cookie`, appear in the array multiple times.
*/
headersArray(): Array<{
/**
* Name of the header.
*/
name: string;
/**
* Value of the header.
*/
value: string;
}>;
/**
* Returns the JSON representation of response body.
*
* This method will throw if the response body is not parsable via `JSON.parse`.
*/
json(): Promise<Serializable>;
/**
* Contains a boolean stating whether the response was successful (status in the range 200-299) or not.
*/
ok(): boolean;
/**
* Contains the status code of the response (e.g., 200 for a success).
*/
status(): number;
/**
* Contains the status text of the response (e.g. usually an "OK" for a success).
*/
statusText(): string;
/**
* Returns the text representation of response body.
*/
text(): Promise<string>;
/**
* Contains the URL of the response.
*/
url(): string;
}
/** /**
* - extends: [EventEmitter] * - extends: [EventEmitter]
* *
@ -12655,318 +13090,6 @@ export interface Electron {
}): Promise<ElectronApplication>; }): Promise<ElectronApplication>;
} }
/**
* This API is used for Web API testing. You can use it to trigger API endpoints, configure micro-services, prepare
* environment or the service to your e2e test. When used on [Page] or a [BrowserContext], this API will automatically use
* the cookies from the corresponding [BrowserContext]. This means that if you log in using this API, your e2e test will be
* logged in and vice versa.
*/
export interface FetchRequest {
/**
* All responses received through
* [fetchRequest.fetch(urlOrRequest[, options])](https://playwright.dev/docs/api/class-fetchrequest#fetch-request-fetch),
* [fetchRequest.get(url[, options])](https://playwright.dev/docs/api/class-fetchrequest#fetch-request-get),
* [fetchRequest.post(url[, options])](https://playwright.dev/docs/api/class-fetchrequest#fetch-request-post) and other
* methods are stored in the memory, so that you can later call
* [fetchResponse.body()](https://playwright.dev/docs/api/class-fetchresponse#fetch-response-body). This method discards
* all stored responses, and makes
* [fetchResponse.body()](https://playwright.dev/docs/api/class-fetchresponse#fetch-response-body) throw "Response
* disposed" error.
*/
dispose(): Promise<void>;
/**
* Sends HTTP(S) fetch and returns its response. The method will populate fetch cookies from the context and update context
* cookies from the response. The method will automatically follow redirects.
* @param urlOrRequest Target URL or Request to get all fetch parameters from.
* @param options
*/
fetch(urlOrRequest: string|Request, 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.
*/
headers?: { [key: string]: string; };
/**
* Whether to ignore HTTPS errors when sending network requests. Defaults to `false`.
*/
ignoreHTTPSErrors?: boolean;
/**
* If set changes the fetch method (e.g. PUT or POST). If not specified, GET method is used.
*/
method?: string;
/**
* 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?: { [key: string]: string|number|boolean|ReadStream|{
/**
* File name
*/
name: string;
/**
* File type
*/
mimeType: string;
/**
* File content
*/
buffer: Buffer;
}; };
/**
* Query parameters to be send with the URL.
*/
params?: { [key: string]: string; };
/**
* Request timeout in milliseconds.
*/
timeout?: number;
}): Promise<FetchResponse>;
/**
* Sends HTTP(S) GET request and returns its response. The method will populate fetch cookies from the context and update
* context cookies from the response. The method will automatically follow redirects.
* @param url Target URL.
* @param options
*/
get(url: string, 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.
*/
headers?: { [key: string]: string; };
/**
* Whether to ignore HTTPS errors when sending network requests. Defaults to `false`.
*/
ignoreHTTPSErrors?: boolean;
/**
* Query parameters to be send with the URL.
*/
params?: { [key: string]: string; };
/**
* Request timeout in milliseconds.
*/
timeout?: number;
}): Promise<FetchResponse>;
/**
* Sends HTTP(S) fetch and returns its response. The method will populate fetch cookies from the context and update context
* cookies from the response. The method will automatically follow redirects.
* @param url Target URL.
* @param options
*/
post(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.
*/
headers?: { [key: string]: string; };
/**
* Whether to ignore HTTPS errors when sending network requests. Defaults to `false`.
*/
ignoreHTTPSErrors?: boolean;
/**
* 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?: { [key: string]: string|number|boolean|ReadStream|{
/**
* File name
*/
name: string;
/**
* File type
*/
mimeType: string;
/**
* File content
*/
buffer: Buffer;
}; };
/**
* Query parameters to be send with the URL.
*/
params?: { [key: string]: string; };
/**
* Request timeout in milliseconds.
*/
timeout?: number;
}): Promise<FetchResponse>;
/**
* Returns storage state for this request context, contains current cookies and local storage snapshot if it was passed to
* the constructor.
* @param options
*/
storageState(options?: {
/**
* The file path to save the storage state to. If `path` is a relative path, then it is resolved relative to current
* working directory. If no path is provided, storage state is still returned, but won't be saved to the disk.
*/
path?: string;
}): Promise<{
cookies: Array<{
name: string;
value: string;
domain: string;
path: string;
/**
* Unix time in seconds.
*/
expires: number;
httpOnly: boolean;
secure: boolean;
sameSite: "Strict"|"Lax"|"None";
}>;
origins: Array<{
origin: string;
localStorage: Array<{
name: string;
value: string;
}>;
}>;
}>;
}
/**
* [FetchResponse] class represents responses received from
* [fetchRequest.fetch(urlOrRequest[, options])](https://playwright.dev/docs/api/class-fetchrequest#fetch-request-fetch).
*/
export interface FetchResponse {
/**
* Returns the buffer with response body.
*/
body(): Promise<Buffer>;
/**
* Disposes the body of this response. If not called then the body will stay in memory until the context closes.
*/
dispose(): Promise<void>;
/**
* An object with all the response HTTP headers associated with this response.
*/
headers(): { [key: string]: string; };
/**
* An array with all the request HTTP headers associated with this response. Header names are not lower-cased. Headers with
* multiple entries, such as `Set-Cookie`, appear in the array multiple times.
*/
headersArray(): Array<{
/**
* Name of the header.
*/
name: string;
/**
* Value of the header.
*/
value: string;
}>;
/**
* Returns the JSON representation of response body.
*
* This method will throw if the response body is not parsable via `JSON.parse`.
*/
json(): Promise<Serializable>;
/**
* Contains a boolean stating whether the response was successful (status in the range 200-299) or not.
*/
ok(): boolean;
/**
* Contains the status code of the response (e.g., 200 for a success).
*/
status(): number;
/**
* Contains the status text of the response (e.g. usually an "OK" for a success).
*/
statusText(): string;
/**
* Returns the text representation of response body.
*/
text(): Promise<string>;
/**
* Contains the URL of the response.
*/
url(): string;
}
/** /**
* [FileChooser] objects are dispatched by the page in the * [FileChooser] objects are dispatched by the page in the
* [page.on('filechooser')](https://playwright.dev/docs/api/class-page#page-event-file-chooser) event. * [page.on('filechooser')](https://playwright.dev/docs/api/class-page#page-event-file-chooser) event.
@ -13382,122 +13505,9 @@ export const chromium: BrowserType;
export const firefox: BrowserType; export const firefox: BrowserType;
/** /**
* **experimental** Creates new instances of [FetchRequest]. * Exposes API that can be used for the Web API testing.
* @param options
*/ */
export const newRequest: (options?: { export const request: ApiRequest;
/**
* When using [fetchRequest.get(url[, options])](https://playwright.dev/docs/api/class-fetchrequest#fetch-request-get),
* [fetchRequest.post(url[, options])](https://playwright.dev/docs/api/class-fetchrequest#fetch-request-post),
* [fetchRequest.fetch(urlOrRequest[, options])](https://playwright.dev/docs/api/class-fetchrequest#fetch-request-fetch) it
* takes the base URL in consideration by using the [`URL()`](https://developer.mozilla.org/en-US/docs/Web/API/URL/URL)
* constructor for building the corresponding URL. Examples:
* - baseURL: `http://localhost:3000` and sending rquest to `/bar.html` results in `http://localhost:3000/bar.html`
* - baseURL: `http://localhost:3000/foo/` and sending rquest to `./bar.html` results in
* `http://localhost:3000/foo/bar.html`
*/
baseURL?: string;
/**
* An object containing additional HTTP headers to be sent with every request.
*/
extraHTTPHeaders?: { [key: string]: string; };
/**
* Credentials for [HTTP authentication](https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication).
*/
httpCredentials?: {
username: string;
password: string;
};
/**
* Whether to ignore HTTPS errors when sending network requests. Defaults to `false`.
*/
ignoreHTTPSErrors?: boolean;
/**
* Network proxy settings.
*/
proxy?: {
/**
* Proxy to be used for all requests. HTTP and SOCKS proxies are supported, for example `http://myproxy.com:3128` or
* `socks5://myproxy.com:3128`. Short form `myproxy.com:3128` is considered an HTTP proxy.
*/
server: string;
/**
* Optional coma-separated domains to bypass proxy, for example `".com, chromium.org, .domain.com"`.
*/
bypass?: string;
/**
* Optional username to use if HTTP proxy requires authentication.
*/
username?: string;
/**
* Optional password to use if HTTP proxy requires authentication.
*/
password?: string;
};
/**
* Populates context with given storage state. This option can be used to initialize context with logged-in information
* obtained via
* [browserContext.storageState([options])](https://playwright.dev/docs/api/class-browsercontext#browser-context-storage-state)
* or
* [fetchRequest.storageState([options])](https://playwright.dev/docs/api/class-fetchrequest#fetch-request-storage-state).
* Either a path to the file with saved storage, or the value returned by one of
* [browserContext.storageState([options])](https://playwright.dev/docs/api/class-browsercontext#browser-context-storage-state)
* or
* [fetchRequest.storageState([options])](https://playwright.dev/docs/api/class-fetchrequest#fetch-request-storage-state)
* methods.
*/
storageState?: string|{
cookies: Array<{
name: string;
value: string;
domain: string;
path: string;
/**
* Unix time in seconds.
*/
expires: number;
httpOnly: boolean;
secure: boolean;
sameSite: "Strict"|"Lax"|"None";
}>;
origins: Array<{
origin: string;
localStorage: Array<{
name: string;
value: string;
}>;
}>;
};
/**
* Maximum time in milliseconds to wait for the response. Defaults to `30000` (30 seconds). Pass `0` to disable timeout.
*/
timeout?: number;
/**
* Specific user agent to use in this context.
*/
userAgent?: string;
}) => Promise<FetchRequest>;
/** /**
* Selectors can be used to install custom selector engines. See [Working with selectors](https://playwright.dev/docs/selectors) for more * Selectors can be used to install custom selector engines. See [Working with selectors](https://playwright.dev/docs/selectors) for more
@ -14021,10 +14031,10 @@ export interface Route {
path?: string; path?: string;
/** /**
* [FetchResponse] to fulfill route's request with. Individual fields of the response (such as headers) can be overridden * [ApiResponse] to fulfill route's request with. Individual fields of the response (such as headers) can be overridden
* using fulfill options. * using fulfill options.
*/ */
response?: FetchResponse; response?: ApiResponse;
/** /**
* Response status code, defaults to `200`. * Response status code, defaults to `200`.