chore(fetch): unprefix _request and _newRequest (#9325)

This commit is contained in:
Yury Semikhatsky 2021-10-05 13:56:34 -07:00 committed by GitHub
parent 431aa5c9b3
commit 701a97beca
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 171 additions and 171 deletions

View file

@ -189,12 +189,6 @@ Service workers are only supported on Chromium-based browsers.
Emitted when new service worker is created in the context. Emitted when new service worker is created in the context.
## property: BrowserContext._request
* langs: js
- type: <[FetchRequest]>
API testing helper associated with this context. Requests made with this API will use context cookies.
## async method: BrowserContext.addCookies ## async method: BrowserContext.addCookies
Adds cookies into this browser context. All pages within this context will have these cookies installed. Cookies can be Adds cookies into this browser context. All pages within this context will have these cookies installed. Cookies can be
@ -855,6 +849,12 @@ Creates a new page in the browser context.
Returns all open pages in the context. Returns all open pages in the context.
## property: BrowserContext.request
* langs: js
- type: <[FetchRequest]>
API testing helper associated with this context. Requests made with this API will use context cookies.
## async method: BrowserContext.route ## async method: BrowserContext.route
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

View file

@ -449,12 +449,6 @@ Emitted when [WebSocket] request is sent.
Emitted when a dedicated [WebWorker](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API) is spawned by the Emitted when a dedicated [WebWorker](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API) is spawned by the
page. page.
## property: Page._request
* langs: js
- type: <[FetchRequest]>
API testing helper associated with this page. Requests made with this API will use page cookies.
## property: Page.accessibility ## property: Page.accessibility
* langs: csharp, js, python * langs: csharp, js, python
- type: <[Accessibility]> - type: <[Accessibility]>
@ -2420,6 +2414,12 @@ last redirect.
### option: Page.reload.timeout = %%-navigation-timeout-%% ### option: Page.reload.timeout = %%-navigation-timeout-%%
## property: Page.request
* langs: js
- type: <[FetchRequest]>
API testing helper associated with this page. Requests made with this API will use page cookies.
## async method: Page.route ## async method: Page.route
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.

View file

@ -83,57 +83,6 @@ class PlaywrightExample
} }
``` ```
## async method: Playwright._newRequest
* langs: js
- returns: <[FetchRequest]>
**experimental** Creates new instances of [FetchRequest].
### 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.chromium ## property: Playwright.chromium
- type: <[BrowserType]> - type: <[BrowserType]>
@ -265,6 +214,57 @@ 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
* langs: js
- returns: <[FetchRequest]>
**experimental** Creates new instances of [FetchRequest].
### 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

@ -49,7 +49,7 @@ export class BrowserContext extends ChannelOwner<channels.BrowserContextChannel,
private _closedPromise: Promise<void>; private _closedPromise: Promise<void>;
_options: channels.BrowserNewContextParams = { }; _options: channels.BrowserNewContextParams = { };
readonly _request: FetchRequest; readonly request: FetchRequest;
readonly tracing: Tracing; readonly tracing: Tracing;
readonly _backgroundPages = new Set<Page>(); readonly _backgroundPages = new Set<Page>();
readonly _serviceWorkers = new Set<Worker>(); readonly _serviceWorkers = new Set<Worker>();
@ -69,7 +69,7 @@ export class BrowserContext extends ChannelOwner<channels.BrowserContextChannel,
this._browser = parent; this._browser = parent;
this._isChromium = this._browser?._name === 'chromium'; this._isChromium = this._browser?._name === 'chromium';
this.tracing = new Tracing(this); this.tracing = new Tracing(this);
this._request = FetchRequest.from(initializer.fetchRequest); this.request = FetchRequest.from(initializer.fetchRequest);
this._channel.on('bindingCall', ({ binding }) => this._onBinding(BindingCall.from(binding))); this._channel.on('bindingCall', ({ binding }) => this._onBinding(BindingCall.from(binding)));
this._channel.on('close', () => this._onClose()); this._channel.on('close', () => this._onClose());

View file

@ -78,7 +78,7 @@ export class Page extends ChannelOwner<channels.PageChannel, channels.PageInitia
readonly coverage: Coverage; readonly coverage: Coverage;
readonly keyboard: Keyboard; readonly keyboard: Keyboard;
readonly mouse: Mouse; readonly mouse: Mouse;
readonly _request: FetchRequest; readonly request: FetchRequest;
readonly touchscreen: Touchscreen; readonly touchscreen: Touchscreen;
readonly _bindings = new Map<string, (source: structs.BindingSource, ...args: any[]) => any>(); readonly _bindings = new Map<string, (source: structs.BindingSource, ...args: any[]) => any>();
@ -102,7 +102,7 @@ export class Page extends ChannelOwner<channels.PageChannel, channels.PageInitia
this.accessibility = new Accessibility(this._channel); this.accessibility = new Accessibility(this._channel);
this.keyboard = new Keyboard(this); this.keyboard = new Keyboard(this);
this.mouse = new Mouse(this); this.mouse = new Mouse(this);
this._request = this._browserContext._request; this.request = this._browserContext.request;
this.touchscreen = new Touchscreen(this); this.touchscreen = new Touchscreen(this);
this._mainFrame = Frame.from(initializer.mainFrame); this._mainFrame = Frame.from(initializer.mainFrame);

View file

@ -71,7 +71,7 @@ export class Playwright extends ChannelOwner<channels.PlaywrightChannel, channel
this.selectors._addChannel(this._selectorsOwner); this.selectors._addChannel(this._selectorsOwner);
} }
async _newRequest(options: NewRequestOptions = {}): Promise<FetchRequest> { async newRequest(options: NewRequestOptions = {}): Promise<FetchRequest> {
return await this._wrapApiCall(async (channel: channels.PlaywrightChannel) => { return await this._wrapApiCall(async (channel: channels.PlaywrightChannel) => {
const storageState = typeof options.storageState === 'string' ? const storageState = typeof options.storageState === 'string' ?
JSON.parse(await fs.promises.readFile(options.storageState, 'utf8')) : JSON.parse(await fs.promises.readFile(options.storageState, 'utf8')) :

View file

@ -43,7 +43,7 @@ it.afterAll(() => {
}); });
it('get should work', async ({ context, server }) => { it('get should work', async ({ context, server }) => {
const response = await context._request.get(server.PREFIX + '/simple.json'); const response = await context.request.get(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);
expect(response.statusText()).toBe('OK'); expect(response.statusText()).toBe('OK');
@ -55,7 +55,7 @@ it('get should work', async ({ context, server }) => {
}); });
it('fetch should work', async ({ context, server }) => { it('fetch should work', async ({ context, server }) => {
const response = await context._request.fetch(server.PREFIX + '/simple.json'); const response = await context.request.fetch(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);
expect(response.statusText()).toBe('OK'); expect(response.statusText()).toBe('OK');
@ -70,7 +70,7 @@ it('should throw on network error', async ({ context, server }) => {
server.setRoute('/test', (req, res) => { server.setRoute('/test', (req, res) => {
req.socket.destroy(); req.socket.destroy();
}); });
const error = await context._request.get(server.PREFIX + '/test').catch(e => e); const error = await context.request.get(server.PREFIX + '/test').catch(e => e);
expect(error.message).toContain('socket hang up'); expect(error.message).toContain('socket hang up');
}); });
@ -79,7 +79,7 @@ it('should throw on network error after redirect', async ({ context, server }) =
server.setRoute('/test', (req, res) => { server.setRoute('/test', (req, res) => {
req.socket.destroy(); req.socket.destroy();
}); });
const error = await context._request.get(server.PREFIX + '/redirect').catch(e => e); const error = await context.request.get(server.PREFIX + '/redirect').catch(e => e);
expect(error.message).toContain('socket hang up'); expect(error.message).toContain('socket hang up');
}); });
@ -93,7 +93,7 @@ it('should throw on network error when sending body', async ({ context, server }
res.uncork(); res.uncork();
req.socket.destroy(); req.socket.destroy();
}); });
const error = await context._request.get(server.PREFIX + '/test').catch(e => e); const error = await context.request.get(server.PREFIX + '/test').catch(e => e);
expect(error.message).toContain('Error: aborted'); expect(error.message).toContain('Error: aborted');
}); });
@ -108,7 +108,7 @@ it('should throw on network error when sending body after redirect', async ({ co
res.uncork(); res.uncork();
req.socket.destroy(); req.socket.destroy();
}); });
const error = await context._request.get(server.PREFIX + '/redirect').catch(e => e); const error = await context.request.get(server.PREFIX + '/redirect').catch(e => e);
expect(error.message).toContain('Error: aborted'); expect(error.message).toContain('Error: aborted');
}); });
@ -125,7 +125,7 @@ it('should add session cookies to request', async ({ context, server }) => {
}]); }]);
const [req] = await Promise.all([ const [req] = await Promise.all([
server.waitForRequest('/simple.json'), server.waitForRequest('/simple.json'),
context._request.get(`http://www.my.playwright.dev:${server.PORT}/simple.json`), context.request.get(`http://www.my.playwright.dev:${server.PORT}/simple.json`),
]); ]);
expect(req.headers.cookie).toEqual('username=John Doe'); expect(req.headers.cookie).toEqual('username=John Doe');
}); });
@ -140,7 +140,7 @@ for (const method of ['get', 'post', 'fetch']) {
request = req; request = req;
server.serveFile(req, res); server.serveFile(req, res);
}); });
await context._request[method](server.EMPTY_PAGE + '?p1=foo', { await context.request[method](server.EMPTY_PAGE + '?p1=foo', {
params: { params: {
'p1': 'v1', 'p1': 'v1',
'парам2': 'знач2', 'парам2': 'знач2',
@ -152,14 +152,14 @@ for (const method of ['get', 'post', 'fetch']) {
}); });
it(`${method} should support failOnStatusCode`, async ({ context, server }) => { it(`${method} should support failOnStatusCode`, async ({ context, server }) => {
const error = await context._request[method](server.PREFIX + '/does-not-exist.html', { const error = await context.request[method](server.PREFIX + '/does-not-exist.html', {
failOnStatusCode: true failOnStatusCode: true
}).catch(e => e); }).catch(e => e);
expect(error.message).toContain('404 Not Found'); expect(error.message).toContain('404 Not Found');
}); });
it(`${method}should support ignoreHTTPSErrors option`, async ({ context, httpsServer }) => { it(`${method}should support ignoreHTTPSErrors option`, async ({ context, httpsServer }) => {
const response = await context._request[method](httpsServer.EMPTY_PAGE, { ignoreHTTPSErrors: true }); const response = await context.request[method](httpsServer.EMPTY_PAGE, { ignoreHTTPSErrors: true });
expect(response.status()).toBe(200); expect(response.status()).toBe(200);
}); });
} }
@ -177,7 +177,7 @@ it('should not add context cookie if cookie header passed as a parameter', async
}]); }]);
const [req] = await Promise.all([ const [req] = await Promise.all([
server.waitForRequest('/empty.html'), server.waitForRequest('/empty.html'),
context._request.get(`http://www.my.playwright.dev:${server.PORT}/empty.html`, { context.request.get(`http://www.my.playwright.dev:${server.PORT}/empty.html`, {
headers: { headers: {
'Cookie': 'foo=bar' 'Cookie': 'foo=bar'
} }
@ -201,7 +201,7 @@ it('should follow redirects', async ({ context, server }) => {
}]); }]);
const [req, response] = await Promise.all([ const [req, response] = await Promise.all([
server.waitForRequest('/simple.json'), server.waitForRequest('/simple.json'),
context._request.get(`http://www.my.playwright.dev:${server.PORT}/redirect1`), context.request.get(`http://www.my.playwright.dev:${server.PORT}/redirect1`),
]); ]);
expect(req.headers.cookie).toEqual('username=John Doe'); expect(req.headers.cookie).toEqual('username=John Doe');
expect(response.url()).toBe(`http://www.my.playwright.dev:${server.PORT}/simple.json`); expect(response.url()).toBe(`http://www.my.playwright.dev:${server.PORT}/simple.json`);
@ -213,7 +213,7 @@ it('should add cookies from Set-Cookie header', async ({ context, page, server }
res.setHeader('Set-Cookie', ['session=value', 'foo=bar; max-age=3600']); res.setHeader('Set-Cookie', ['session=value', 'foo=bar; max-age=3600']);
res.end(); res.end();
}); });
await context._request.get(server.PREFIX + '/setcookie.html'); await context.request.get(server.PREFIX + '/setcookie.html');
const cookies = await context.cookies(); const cookies = await context.cookies();
expect(new Set(cookies.map(c => ({ name: c.name, value: c.value })))).toEqual(new Set([ expect(new Set(cookies.map(c => ({ name: c.name, value: c.value })))).toEqual(new Set([
{ {
@ -234,7 +234,7 @@ it('should not lose body while handling Set-Cookie header', async ({ context, se
res.setHeader('Set-Cookie', ['session=value', 'foo=bar; max-age=3600']); res.setHeader('Set-Cookie', ['session=value', 'foo=bar; max-age=3600']);
res.end('text content'); res.end('text content');
}); });
const response = await context._request.get(server.PREFIX + '/setcookie.html'); const response = await context.request.get(server.PREFIX + '/setcookie.html');
expect(await response.text()).toBe('text content'); expect(await response.text()).toBe('text content');
}); });
@ -254,7 +254,7 @@ it('should handle cookies on redirects', async ({ context, server, browserName,
server.waitForRequest('/redirect1'), server.waitForRequest('/redirect1'),
server.waitForRequest('/a/b/redirect2'), server.waitForRequest('/a/b/redirect2'),
server.waitForRequest('/title.html'), server.waitForRequest('/title.html'),
context._request.get(`${server.PREFIX}/redirect1`), context.request.get(`${server.PREFIX}/redirect1`),
]); ]);
expect(req1.headers.cookie).toBeFalsy(); expect(req1.headers.cookie).toBeFalsy();
expect(req2.headers.cookie).toBe('r1=v1'); expect(req2.headers.cookie).toBe('r1=v1');
@ -265,7 +265,7 @@ it('should handle cookies on redirects', async ({ context, server, browserName,
server.waitForRequest('/redirect1'), server.waitForRequest('/redirect1'),
server.waitForRequest('/a/b/redirect2'), server.waitForRequest('/a/b/redirect2'),
server.waitForRequest('/title.html'), server.waitForRequest('/title.html'),
context._request.get(`${server.PREFIX}/redirect1`), context.request.get(`${server.PREFIX}/redirect1`),
]); ]);
expect(req1.headers.cookie).toBe('r1=v1'); expect(req1.headers.cookie).toBe('r1=v1');
expect(req2.headers.cookie.split(';').map(s => s.trim()).sort()).toEqual(['r1=v1', 'r2=v2']); expect(req2.headers.cookie.split(';').map(s => s.trim()).sort()).toEqual(['r1=v1', 'r2=v2']);
@ -310,7 +310,7 @@ it('should return raw headers', async ({ context, page, server }) => {
conn.uncork(); conn.uncork();
conn.end(); conn.end();
}); });
const response = await context._request.get(`${server.PREFIX}/headers`); const response = await context.request.get(`${server.PREFIX}/headers`);
expect(response.status()).toBe(200); expect(response.status()).toBe(200);
const headers = response.headersArray().filter(({ name }) => name.toLowerCase().includes('name-')); const headers = response.headersArray().filter(({ name }) => name.toLowerCase().includes('name-'));
expect(headers).toEqual([{ name: 'Name-A', value: 'v1' }, { name: 'name-b', value: 'v4' }, { name: 'Name-a', value: 'v2' }, { name: 'name-A', value: 'v3' }]); expect(headers).toEqual([{ name: 'Name-A', value: 'v1' }, { name: 'name-b', value: 'v4' }, { name: 'Name-a', value: 'v2' }, { name: 'name-A', value: 'v3' }]);
@ -338,7 +338,7 @@ it('should work with context level proxy', async ({ browserOptions, browserType,
const [request, response] = await Promise.all([ const [request, response] = await Promise.all([
server.waitForRequest('/target.html'), server.waitForRequest('/target.html'),
context._request.get(`http://non-existent.com/target.html`) context.request.get(`http://non-existent.com/target.html`)
]); ]);
expect(response.status()).toBe(200); expect(response.status()).toBe(200);
expect(request.url).toBe('/target.html'); expect(request.url).toBe('/target.html');
@ -359,7 +359,7 @@ it('should pass proxy credentials', async ({ browserType, browserOptions, server
proxy: { server: `localhost:${proxyServer.PORT}`, username: 'user', password: 'secret' } proxy: { server: `localhost:${proxyServer.PORT}`, username: 'user', password: 'secret' }
}); });
const context = await browser.newContext(); const context = await browser.newContext();
const response = await context._request.get('http://non-existent.com/simple.json'); const response = await context.request.get('http://non-existent.com/simple.json');
expect(proxyServer.connectHosts).toContain('non-existent.com:80'); expect(proxyServer.connectHosts).toContain('non-existent.com:80');
expect(auth).toBe('Basic ' + Buffer.from('user:secret').toString('base64')); expect(auth).toBe('Basic ' + Buffer.from('user:secret').toString('base64'));
expect(await response.json()).toEqual({ foo: 'bar' }); expect(await response.json()).toEqual({ foo: 'bar' });
@ -371,7 +371,7 @@ it('should work with http credentials', async ({ context, server }) => {
const [request, response] = await Promise.all([ const [request, response] = await Promise.all([
server.waitForRequest('/empty.html'), server.waitForRequest('/empty.html'),
context._request.get(server.EMPTY_PAGE, { context.request.get(server.EMPTY_PAGE, {
headers: { headers: {
'authorization': 'Basic ' + Buffer.from('user:pass').toString('base64') 'authorization': 'Basic ' + Buffer.from('user:pass').toString('base64')
} }
@ -383,25 +383,25 @@ it('should work with http credentials', async ({ context, server }) => {
it('should work with setHTTPCredentials', async ({ context, server }) => { it('should work with setHTTPCredentials', async ({ context, server }) => {
server.setAuth('/empty.html', 'user', 'pass'); server.setAuth('/empty.html', 'user', 'pass');
const response1 = await context._request.get(server.EMPTY_PAGE); const response1 = await context.request.get(server.EMPTY_PAGE);
expect(response1.status()).toBe(401); expect(response1.status()).toBe(401);
await context.setHTTPCredentials({ username: 'user', password: 'pass' }); await context.setHTTPCredentials({ username: 'user', password: 'pass' });
const response2 = await context._request.get(server.EMPTY_PAGE); const response2 = await context.request.get(server.EMPTY_PAGE);
expect(response2.status()).toBe(200); expect(response2.status()).toBe(200);
}); });
it('should return error with wrong credentials', async ({ context, server }) => { it('should return error with wrong credentials', async ({ context, server }) => {
server.setAuth('/empty.html', 'user', 'pass'); server.setAuth('/empty.html', 'user', 'pass');
await context.setHTTPCredentials({ username: 'user', password: 'wrong' }); await context.setHTTPCredentials({ username: 'user', password: 'wrong' });
const response2 = await context._request.get(server.EMPTY_PAGE); const response2 = await context.request.get(server.EMPTY_PAGE);
expect(response2.status()).toBe(401); expect(response2.status()).toBe(401);
}); });
it('should support post data', async ({ context, server }) => { it('should support post data', async ({ context, server }) => {
const [request, response] = await Promise.all([ const [request, response] = await Promise.all([
server.waitForRequest('/simple.json'), server.waitForRequest('/simple.json'),
context._request.post(`${server.PREFIX}/simple.json`, { context.request.post(`${server.PREFIX}/simple.json`, {
data: 'My request' data: 'My request'
}) })
]); ]);
@ -414,7 +414,7 @@ it('should support post data', async ({ context, server }) => {
it('should add default headers', async ({ context, server, page }) => { it('should add default headers', async ({ context, server, page }) => {
const [request] = await Promise.all([ const [request] = await Promise.all([
server.waitForRequest('/empty.html'), server.waitForRequest('/empty.html'),
context._request.get(server.EMPTY_PAGE) context.request.get(server.EMPTY_PAGE)
]); ]);
expect(request.headers['accept']).toBe('*/*'); expect(request.headers['accept']).toBe('*/*');
const userAgent = await page.evaluate(() => navigator.userAgent); const userAgent = await page.evaluate(() => navigator.userAgent);
@ -428,7 +428,7 @@ it('should send content-length', async function({ context, asset, server }) {
bytes.push(i); bytes.push(i);
const [request] = await Promise.all([ const [request] = await Promise.all([
server.waitForRequest('/empty.html'), server.waitForRequest('/empty.html'),
context._request.post(server.EMPTY_PAGE, { context.request.post(server.EMPTY_PAGE, {
data: Buffer.from(bytes) data: Buffer.from(bytes)
}) })
]); ]);
@ -440,7 +440,7 @@ it('should add default headers to redirects', async ({ context, server, page })
server.setRedirect('/redirect', '/empty.html'); server.setRedirect('/redirect', '/empty.html');
const [request] = await Promise.all([ const [request] = await Promise.all([
server.waitForRequest('/empty.html'), server.waitForRequest('/empty.html'),
context._request.get(`${server.PREFIX}/redirect`) context.request.get(`${server.PREFIX}/redirect`)
]); ]);
expect(request.headers['accept']).toBe('*/*'); expect(request.headers['accept']).toBe('*/*');
const userAgent = await page.evaluate(() => navigator.userAgent); const userAgent = await page.evaluate(() => navigator.userAgent);
@ -451,7 +451,7 @@ it('should add default headers to redirects', async ({ context, server, page })
it('should allow to override default headers', async ({ context, server, page }) => { it('should allow to override default headers', async ({ context, server, page }) => {
const [request] = await Promise.all([ const [request] = await Promise.all([
server.waitForRequest('/empty.html'), server.waitForRequest('/empty.html'),
context._request.get(server.EMPTY_PAGE, { context.request.get(server.EMPTY_PAGE, {
headers: { headers: {
'User-Agent': 'Playwright', 'User-Agent': 'Playwright',
'Accept': 'text/html', 'Accept': 'text/html',
@ -471,7 +471,7 @@ it('should propagate custom headers with redirects', async ({ context, server })
server.waitForRequest('/a/redirect1'), server.waitForRequest('/a/redirect1'),
server.waitForRequest('/b/c/redirect2'), server.waitForRequest('/b/c/redirect2'),
server.waitForRequest('/simple.json'), server.waitForRequest('/simple.json'),
context._request.get(`${server.PREFIX}/a/redirect1`, { headers: { 'foo': 'bar' } }), context.request.get(`${server.PREFIX}/a/redirect1`, { headers: { 'foo': 'bar' } }),
]); ]);
expect(req1.headers['foo']).toBe('bar'); expect(req1.headers['foo']).toBe('bar');
expect(req2.headers['foo']).toBe('bar'); expect(req2.headers['foo']).toBe('bar');
@ -486,7 +486,7 @@ it('should propagate extra http headers with redirects', async ({ context, serve
server.waitForRequest('/a/redirect1'), server.waitForRequest('/a/redirect1'),
server.waitForRequest('/b/c/redirect2'), server.waitForRequest('/b/c/redirect2'),
server.waitForRequest('/simple.json'), server.waitForRequest('/simple.json'),
context._request.get(`${server.PREFIX}/a/redirect1`), context.request.get(`${server.PREFIX}/a/redirect1`),
]); ]);
expect(req1.headers['my-secret']).toBe('Value'); expect(req1.headers['my-secret']).toBe('Value');
expect(req2.headers['my-secret']).toBe('Value'); expect(req2.headers['my-secret']).toBe('Value');
@ -494,7 +494,7 @@ it('should propagate extra http headers with redirects', async ({ context, serve
}); });
it('should throw on invalid header value', async ({ context, server }) => { it('should throw on invalid header value', async ({ context, server }) => {
const error = await context._request.get(`${server.PREFIX}/a/redirect1`, { const error = await context.request.get(`${server.PREFIX}/a/redirect1`, {
headers: { headers: {
'foo': 'недопустимое значение', 'foo': 'недопустимое значение',
} }
@ -503,9 +503,9 @@ it('should throw on invalid header value', async ({ context, server }) => {
}); });
it('should throw on non-http(s) protocol', async ({ context }) => { it('should throw on non-http(s) protocol', async ({ context }) => {
const error1 = await context._request.get(`data:text/plain,test`).catch(e => e); const error1 = await context.request.get(`data:text/plain,test`).catch(e => e);
expect(error1.message).toContain('Protocol "data:" not supported'); expect(error1.message).toContain('Protocol "data:" not supported');
const error2 = await context._request.get(`file:///tmp/foo`).catch(e => e); const error2 = await context.request.get(`file:///tmp/foo`).catch(e => e);
expect(error2.message).toContain('Protocol "file:" not supported'); expect(error2.message).toContain('Protocol "file:" not supported');
}); });
@ -515,7 +515,7 @@ it('should support https', async ({ context, httpsServer }) => {
process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = '0'; process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = '0';
suppressCertificateWarning(); suppressCertificateWarning();
try { try {
const response = await context._request.get(httpsServer.EMPTY_PAGE); const response = await context.request.get(httpsServer.EMPTY_PAGE);
expect(response.status()).toBe(200); expect(response.status()).toBe(200);
} finally { } finally {
process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = oldValue; process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = oldValue;
@ -524,7 +524,7 @@ it('should support https', async ({ context, httpsServer }) => {
it('should inherit ignoreHTTPSErrors from context', async ({ contextFactory, contextOptions, httpsServer }) => { it('should inherit ignoreHTTPSErrors from context', async ({ contextFactory, contextOptions, httpsServer }) => {
const context = await contextFactory({ ...contextOptions, ignoreHTTPSErrors: true }); const context = await contextFactory({ ...contextOptions, ignoreHTTPSErrors: true });
const response = await context._request.get(httpsServer.EMPTY_PAGE); const response = await context.request.get(httpsServer.EMPTY_PAGE);
expect(response.status()).toBe(200); expect(response.status()).toBe(200);
}); });
@ -533,7 +533,7 @@ it('should resolve url relative to baseURL', async function({ server, contextFac
...contextOptions, ...contextOptions,
baseURL: server.PREFIX, baseURL: server.PREFIX,
}); });
const response = await context._request.get('/empty.html'); const response = await context.request.get('/empty.html');
expect(response.url()).toBe(server.EMPTY_PAGE); expect(response.url()).toBe(server.EMPTY_PAGE);
}); });
@ -553,7 +553,7 @@ it('should support gzip compression', async function({ context, server }) {
gzip.end(); gzip.end();
}); });
const response = await context._request.get(server.PREFIX + '/compressed'); const response = await context.request.get(server.PREFIX + '/compressed');
expect(await response.text()).toBe('Hello, world!'); expect(await response.text()).toBe('Hello, world!');
}); });
@ -567,7 +567,7 @@ it('should throw informatibe error on corrupted gzip body', async function({ con
res.end(); res.end();
}); });
const error = await context._request.get(server.PREFIX + '/corrupted').catch(e => e); const error = await context.request.get(server.PREFIX + '/corrupted').catch(e => e);
expect(error.message).toContain(`failed to decompress 'gzip' encoding`); expect(error.message).toContain(`failed to decompress 'gzip' encoding`);
}); });
@ -587,7 +587,7 @@ it('should support brotli compression', async function({ context, server }) {
brotli.end(); brotli.end();
}); });
const response = await context._request.get(server.PREFIX + '/compressed'); const response = await context.request.get(server.PREFIX + '/compressed');
expect(await response.text()).toBe('Hello, world!'); expect(await response.text()).toBe('Hello, world!');
}); });
@ -601,7 +601,7 @@ it('should throw informatibe error on corrupted brotli body', async function({ c
res.end(); res.end();
}); });
const error = await context._request.get(server.PREFIX + '/corrupted').catch(e => e); const error = await context.request.get(server.PREFIX + '/corrupted').catch(e => e);
expect(error.message).toContain(`failed to decompress 'br' encoding`); expect(error.message).toContain(`failed to decompress 'br' encoding`);
}); });
@ -621,7 +621,7 @@ it('should support deflate compression', async function({ context, server }) {
deflate.end(); deflate.end();
}); });
const response = await context._request.get(server.PREFIX + '/compressed'); const response = await context.request.get(server.PREFIX + '/compressed');
expect(await response.text()).toBe('Hello, world!'); expect(await response.text()).toBe('Hello, world!');
}); });
@ -635,7 +635,7 @@ it('should throw informatibe error on corrupted deflate body', async function({
res.end(); res.end();
}); });
const error = await context._request.get(server.PREFIX + '/corrupted').catch(e => e); const error = await context.request.get(server.PREFIX + '/corrupted').catch(e => e);
expect(error.message).toContain(`failed to decompress 'deflate' encoding`); expect(error.message).toContain(`failed to decompress 'deflate' encoding`);
}); });
@ -647,7 +647,7 @@ it('should support timeout option', async function({ context, server }) {
}); });
}); });
const error = await context._request.get(server.PREFIX + '/slow', { timeout: 10 }).catch(e => e); const error = await context.request.get(server.PREFIX + '/slow', { timeout: 10 }).catch(e => e);
expect(error.message).toContain(`Request timed out after 10ms`); expect(error.message).toContain(`Request timed out after 10ms`);
}); });
@ -662,7 +662,7 @@ it('should support a timeout of 0', async function({ context, server }) {
}, 50); }, 50);
}); });
const response = await context._request.get(server.PREFIX + '/slow', { const response = await context.request.get(server.PREFIX + '/slow', {
timeout: 0, timeout: 0,
}); });
expect(await response.text()).toBe('done'); expect(await response.text()).toBe('done');
@ -678,12 +678,12 @@ it('should respect timeout after redirects', async function({ context, server })
}); });
context.setDefaultTimeout(100); context.setDefaultTimeout(100);
const error = await context._request.get(server.PREFIX + '/redirect').catch(e => e); const error = await context.request.get(server.PREFIX + '/redirect').catch(e => e);
expect(error.message).toContain(`Request timed out after 100ms`); expect(error.message).toContain(`Request timed out after 100ms`);
}); });
it('should dispose', async function({ context, server }) { it('should dispose', async function({ context, server }) {
const response = await context._request.get(server.PREFIX + '/simple.json'); const response = await context.request.get(server.PREFIX + '/simple.json');
expect(await response.json()).toEqual({ foo: 'bar' }); expect(await response.json()).toEqual({ foo: 'bar' });
await response.dispose(); await response.dispose();
const error = await response.body().catch(e => e); const error = await response.body().catch(e => e);
@ -691,7 +691,7 @@ it('should dispose', async function({ context, server }) {
}); });
it('should dispose when context closes', async function({ context, server }) { it('should dispose when context closes', async function({ context, server }) {
const response = await context._request.get(server.PREFIX + '/simple.json'); const response = await context.request.get(server.PREFIX + '/simple.json');
expect(await response.json()).toEqual({ foo: 'bar' }); expect(await response.json()).toEqual({ foo: 'bar' });
await context.close(); await context.close();
const error = await response.body().catch(e => e); const error = await response.body().catch(e => e);
@ -699,7 +699,7 @@ it('should dispose when context closes', async function({ context, server }) {
}); });
it('should throw on invalid first argument', async function({ context }) { it('should throw on invalid first argument', async function({ context }) {
const error = await context._request.get({} as any).catch(e => e); const error = await context.request.get({} as any).catch(e => e);
expect(error.message).toContain('First argument must be either URL string or Request'); expect(error.message).toContain('First argument must be either URL string or Request');
}); });
@ -710,7 +710,7 @@ it('should override request parameters', async function({ context, page, server
]); ]);
const [req] = await Promise.all([ const [req] = await Promise.all([
server.waitForRequest('/empty.html'), server.waitForRequest('/empty.html'),
context._request.post(pageReq, { context.request.post(pageReq, {
headers: { headers: {
'foo': 'bar' 'foo': 'bar'
}, },
@ -725,7 +725,7 @@ it('should override request parameters', async function({ context, page, server
it('should support application/x-www-form-urlencoded', async function({ context, page, server }) { it('should support application/x-www-form-urlencoded', async function({ context, page, server }) {
const [req] = await Promise.all([ const [req] = await Promise.all([
server.waitForRequest('/empty.html'), server.waitForRequest('/empty.html'),
context._request.post(server.EMPTY_PAGE, { context.request.post(server.EMPTY_PAGE, {
form: { form: {
firstName: 'John', firstName: 'John',
lastName: 'Doe', lastName: 'Doe',
@ -753,7 +753,7 @@ it('should encode to application/json by default', async function({ context, pag
}; };
const [req] = await Promise.all([ const [req] = await Promise.all([
server.waitForRequest('/empty.html'), server.waitForRequest('/empty.html'),
context._request.post(server.EMPTY_PAGE, { data }) context.request.post(server.EMPTY_PAGE, { data })
]); ]);
expect(req.method).toBe('POST'); expect(req.method).toBe('POST');
expect(req.headers['content-type']).toBe('application/json'); expect(req.headers['content-type']).toBe('application/json');
@ -780,7 +780,7 @@ it('should support multipart/form-data', async function({ context, page, server
}; };
const [{ error, fields, files, serverRequest }, response] = await Promise.all([ const [{ error, fields, files, serverRequest }, response] = await Promise.all([
formReceived, formReceived,
context._request.post(server.EMPTY_PAGE, { context.request.post(server.EMPTY_PAGE, {
multipart: { multipart: {
firstName: 'John', firstName: 'John',
lastName: 'Doe', lastName: 'Doe',
@ -812,7 +812,7 @@ it('should support multipart/form-data with ReadSream values', async function({
const readStream = fs.createReadStream(asset('simplezip.json')); const readStream = fs.createReadStream(asset('simplezip.json'));
const [{ error, fields, files, serverRequest }, response] = await Promise.all([ const [{ error, fields, files, serverRequest }, response] = await Promise.all([
formReceived, formReceived,
context._request.post(server.EMPTY_PAGE, { context.request.post(server.EMPTY_PAGE, {
multipart: { multipart: {
firstName: 'John', firstName: 'John',
lastName: 'Doe', lastName: 'Doe',
@ -839,7 +839,7 @@ it('should serialize data to json regardless of content-type', async function({
}; };
const [req] = await Promise.all([ const [req] = await Promise.all([
server.waitForRequest('/empty.html'), server.waitForRequest('/empty.html'),
context._request.post(server.EMPTY_PAGE, { context.request.post(server.EMPTY_PAGE, {
headers: { headers: {
'content-type': 'unknown' 'content-type': 'unknown'
}, },
@ -853,7 +853,7 @@ it('should serialize data to json regardless of content-type', async function({
}); });
it('should throw nice error on unsupported data type', async function({ context, server }) { it('should throw nice error on unsupported data type', async function({ context, server }) {
const error = await context._request.post(server.EMPTY_PAGE, { const error = await context.request.post(server.EMPTY_PAGE, {
headers: { headers: {
'content-type': 'application/json' 'content-type': 'application/json'
}, },
@ -863,7 +863,7 @@ it('should throw nice error on unsupported data type', async function({ context,
}); });
it('should throw when data passed for unsupported request', async function({ context, server }) { it('should throw when data passed for unsupported request', async function({ context, server }) {
const error = await context._request.fetch(server.EMPTY_PAGE, { const error = await context.request.fetch(server.EMPTY_PAGE, {
method: 'GET', method: 'GET',
data: { data: {
foo: 'bar' foo: 'bar'
@ -877,11 +877,11 @@ it('context request should export same storage state as context', async ({ conte
res.setHeader('Set-Cookie', ['a=b', 'c=d']); res.setHeader('Set-Cookie', ['a=b', 'c=d']);
res.end(); res.end();
}); });
await context._request.get(server.PREFIX + '/setcookie.html'); await context.request.get(server.PREFIX + '/setcookie.html');
const contextState = await context.storageState(); const contextState = await context.storageState();
expect(contextState.cookies.length).toBe(2); expect(contextState.cookies.length).toBe(2);
const requestState = await context._request.storageState(); const requestState = await context.request.storageState();
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

@ -601,7 +601,7 @@ it('should be able to download a inline PDF file', async ({ browser, server, ass
const page = await browser.newPage({ acceptDownloads: true }); const page = await browser.newPage({ acceptDownloads: true });
await page.goto(server.EMPTY_PAGE); await page.goto(server.EMPTY_PAGE);
await page.route('**/empty.pdf', async route => { await page.route('**/empty.pdf', async route => {
const response = await page.context()._request.get(route.request()); const response = await page.context().request.get(route.request());
await route.fulfill({ await route.fulfill({
response, response,
headers: { headers: {

View file

@ -25,7 +25,7 @@ export type GlobalFetchFixtures = {
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.newRequest({ ignoreHTTPSErrors: true });
await use(request); await use(request);
await request.dispose(); await request.dispose();
}, },
@ -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.newRequest({ 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.newRequest({ 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.newRequest({ 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.newRequest({ 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.newRequest();
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.newRequest();
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.newRequest({ 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.newRequest({ 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.newRequest({ 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.newRequest();
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.newRequest({ 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.newRequest({ 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.newRequest({
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.newRequest({ 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.newRequest({ 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.newRequest();
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.newRequest();
const response = await request.get(server.PREFIX + '/simple.json'); const response = await request.get(server.PREFIX + '/simple.json');
route.fulfill({ response }); route.fulfill({ response });
}); });
@ -209,7 +209,7 @@ it('should fulfill with global fetch result', async ({ playwright, page, server,
it('should fulfill with fetch result', async ({ page, server, isElectron }) => { it('should fulfill with fetch result', async ({ 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 response = await page._request.get(server.PREFIX + '/simple.json'); const response = await page.request.get(server.PREFIX + '/simple.json');
route.fulfill({ response }); route.fulfill({ response });
}); });
const response = await page.goto(server.EMPTY_PAGE); const response = await page.goto(server.EMPTY_PAGE);
@ -220,7 +220,7 @@ it('should fulfill with fetch result', async ({ page, server, isElectron }) => {
it('should fulfill with fetch result and overrides', async ({ page, server, isElectron }) => { it('should fulfill with fetch result and overrides', async ({ 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 response = await page._request.get(server.PREFIX + '/simple.json'); const response = await page.request.get(server.PREFIX + '/simple.json');
route.fulfill({ route.fulfill({
response, response,
status: 201, status: 201,
@ -239,7 +239,7 @@ it('should fulfill with fetch result and overrides', async ({ page, server, isEl
it('should fetch original request and fulfill', async ({ page, server, isElectron }) => { it('should fetch original request and fulfill', async ({ 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 response = await page._request.get(route.request()); const response = await page.request.get(route.request());
route.fulfill({ route.fulfill({
response, response,
}); });
@ -276,7 +276,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.newRequest();
const response = await request.fetch(route.request()); const response = await request.fetch(route.request());
route.fulfill({ response }); route.fulfill({ response });
}); });

42
types/types.d.ts vendored
View file

@ -1416,11 +1416,6 @@ export interface Page {
*/ */
off(event: 'worker', listener: (worker: Worker) => void): this; off(event: 'worker', listener: (worker: Worker) => void): this;
/**
* API testing helper associated with this page. Requests made with this API will use page cookies.
*/
_request: FetchRequest;
accessibility: Accessibility; accessibility: Accessibility;
/** /**
@ -2755,6 +2750,11 @@ export interface Page {
waitUntil?: "load"|"domcontentloaded"|"networkidle"; waitUntil?: "load"|"domcontentloaded"|"networkidle";
}): Promise<null|Response>; }): Promise<null|Response>;
/**
* API testing helper associated with this page. Requests made with this API will use page cookies.
*/
request: FetchRequest;
/** /**
* 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.
* *
@ -6230,11 +6230,6 @@ export interface BrowserContext {
*/ */
off(event: 'serviceworker', listener: (worker: Worker) => void): this; off(event: 'serviceworker', listener: (worker: Worker) => void): this;
/**
* API testing helper associated with this context. Requests made with this API will use context cookies.
*/
_request: FetchRequest;
/** /**
* Adds cookies into this browser context. All pages within this context will have these cookies installed. Cookies can be * Adds cookies into this browser context. All pages within this context will have these cookies installed. Cookies can be
* obtained via * obtained via
@ -6457,6 +6452,11 @@ export interface BrowserContext {
*/ */
pages(): Array<Page>; pages(): Array<Page>;
/**
* API testing helper associated with this context. Requests made with this API will use context cookies.
*/
request: FetchRequest;
/** /**
* 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
* is enabled, every request matching the url pattern will stall unless it's continued, fulfilled or aborted. * is enabled, every request matching the url pattern will stall unless it's continued, fulfilled or aborted.
@ -13371,11 +13371,21 @@ export interface Mouse {
wheel(deltaX: number, deltaY: number): Promise<void>; wheel(deltaX: number, deltaY: number): Promise<void>;
} }
/**
* This object can be used to launch or connect to Chromium, returning instances of [Browser].
*/
export const chromium: BrowserType;
/**
* This object can be used to launch or connect to Firefox, returning instances of [Browser].
*/
export const firefox: BrowserType;
/** /**
* **experimental** Creates new instances of [FetchRequest]. * **experimental** Creates new instances of [FetchRequest].
* @param options * @param options
*/ */
export const _newRequest: (options?: { export const newRequest: (options?: {
/** /**
* When using * When using
* [fetchRequest.get(urlOrRequest[, options])](https://playwright.dev/docs/api/class-fetchrequest#fetch-request-get), * [fetchRequest.get(urlOrRequest[, options])](https://playwright.dev/docs/api/class-fetchrequest#fetch-request-get),
@ -13490,16 +13500,6 @@ export const _newRequest: (options?: {
userAgent?: string; userAgent?: string;
}) => Promise<FetchRequest>; }) => Promise<FetchRequest>;
/**
* This object can be used to launch or connect to Chromium, returning instances of [Browser].
*/
export const chromium: BrowserType;
/**
* This object can be used to launch or connect to Firefox, returning instances of [Browser].
*/
export const firefox: BrowserType;
/** /**
* 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
* information. * information.