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.
## 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
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.
## 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
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
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
* langs: csharp, js, python
- type: <[Accessibility]>
@ -2420,6 +2414,12 @@ last redirect.
### 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
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
- 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].
## 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
- type: <[Selectors]>

View file

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

View file

@ -78,7 +78,7 @@ export class Page extends ChannelOwner<channels.PageChannel, channels.PageInitia
readonly coverage: Coverage;
readonly keyboard: Keyboard;
readonly mouse: Mouse;
readonly _request: FetchRequest;
readonly request: FetchRequest;
readonly touchscreen: Touchscreen;
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.keyboard = new Keyboard(this);
this.mouse = new Mouse(this);
this._request = this._browserContext._request;
this.request = this._browserContext.request;
this.touchscreen = new Touchscreen(this);
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);
}
async _newRequest(options: NewRequestOptions = {}): Promise<FetchRequest> {
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')) :

View file

@ -43,7 +43,7 @@ it.afterAll(() => {
});
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.status()).toBe(200);
expect(response.statusText()).toBe('OK');
@ -55,7 +55,7 @@ it('get 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.status()).toBe(200);
expect(response.statusText()).toBe('OK');
@ -70,7 +70,7 @@ it('should throw on network error', async ({ context, server }) => {
server.setRoute('/test', (req, res) => {
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');
});
@ -79,7 +79,7 @@ it('should throw on network error after redirect', async ({ context, server }) =
server.setRoute('/test', (req, res) => {
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');
});
@ -93,7 +93,7 @@ it('should throw on network error when sending body', async ({ context, server }
res.uncork();
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');
});
@ -108,7 +108,7 @@ it('should throw on network error when sending body after redirect', async ({ co
res.uncork();
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');
});
@ -125,7 +125,7 @@ it('should add session cookies to request', async ({ context, server }) => {
}]);
const [req] = await Promise.all([
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');
});
@ -140,7 +140,7 @@ for (const method of ['get', 'post', 'fetch']) {
request = req;
server.serveFile(req, res);
});
await context._request[method](server.EMPTY_PAGE + '?p1=foo', {
await context.request[method](server.EMPTY_PAGE + '?p1=foo', {
params: {
'p1': 'v1',
'парам2': 'знач2',
@ -152,14 +152,14 @@ for (const method of ['get', 'post', 'fetch']) {
});
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
}).catch(e => e);
expect(error.message).toContain('404 Not Found');
});
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);
});
}
@ -177,7 +177,7 @@ it('should not add context cookie if cookie header passed as a parameter', async
}]);
const [req] = await Promise.all([
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: {
'Cookie': 'foo=bar'
}
@ -201,7 +201,7 @@ it('should follow redirects', async ({ context, server }) => {
}]);
const [req, response] = await Promise.all([
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(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.end();
});
await context._request.get(server.PREFIX + '/setcookie.html');
await context.request.get(server.PREFIX + '/setcookie.html');
const cookies = await context.cookies();
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.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');
});
@ -254,7 +254,7 @@ it('should handle cookies on redirects', async ({ context, server, browserName,
server.waitForRequest('/redirect1'),
server.waitForRequest('/a/b/redirect2'),
server.waitForRequest('/title.html'),
context._request.get(`${server.PREFIX}/redirect1`),
context.request.get(`${server.PREFIX}/redirect1`),
]);
expect(req1.headers.cookie).toBeFalsy();
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('/a/b/redirect2'),
server.waitForRequest('/title.html'),
context._request.get(`${server.PREFIX}/redirect1`),
context.request.get(`${server.PREFIX}/redirect1`),
]);
expect(req1.headers.cookie).toBe('r1=v1');
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.end();
});
const response = await context._request.get(`${server.PREFIX}/headers`);
const response = await context.request.get(`${server.PREFIX}/headers`);
expect(response.status()).toBe(200);
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' }]);
@ -338,7 +338,7 @@ it('should work with context level proxy', async ({ browserOptions, browserType,
const [request, response] = await Promise.all([
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(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' }
});
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(auth).toBe('Basic ' + Buffer.from('user:secret').toString('base64'));
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([
server.waitForRequest('/empty.html'),
context._request.get(server.EMPTY_PAGE, {
context.request.get(server.EMPTY_PAGE, {
headers: {
'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 }) => {
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);
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);
});
it('should return error with wrong credentials', async ({ context, server }) => {
server.setAuth('/empty.html', 'user', 'pass');
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);
});
it('should support post data', async ({ context, server }) => {
const [request, response] = await Promise.all([
server.waitForRequest('/simple.json'),
context._request.post(`${server.PREFIX}/simple.json`, {
context.request.post(`${server.PREFIX}/simple.json`, {
data: 'My request'
})
]);
@ -414,7 +414,7 @@ it('should support post data', async ({ context, server }) => {
it('should add default headers', async ({ context, server, page }) => {
const [request] = await Promise.all([
server.waitForRequest('/empty.html'),
context._request.get(server.EMPTY_PAGE)
context.request.get(server.EMPTY_PAGE)
]);
expect(request.headers['accept']).toBe('*/*');
const userAgent = await page.evaluate(() => navigator.userAgent);
@ -428,7 +428,7 @@ it('should send content-length', async function({ context, asset, server }) {
bytes.push(i);
const [request] = await Promise.all([
server.waitForRequest('/empty.html'),
context._request.post(server.EMPTY_PAGE, {
context.request.post(server.EMPTY_PAGE, {
data: Buffer.from(bytes)
})
]);
@ -440,7 +440,7 @@ it('should add default headers to redirects', async ({ context, server, page })
server.setRedirect('/redirect', '/empty.html');
const [request] = await Promise.all([
server.waitForRequest('/empty.html'),
context._request.get(`${server.PREFIX}/redirect`)
context.request.get(`${server.PREFIX}/redirect`)
]);
expect(request.headers['accept']).toBe('*/*');
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 }) => {
const [request] = await Promise.all([
server.waitForRequest('/empty.html'),
context._request.get(server.EMPTY_PAGE, {
context.request.get(server.EMPTY_PAGE, {
headers: {
'User-Agent': 'Playwright',
'Accept': 'text/html',
@ -471,7 +471,7 @@ it('should propagate custom headers with redirects', async ({ context, server })
server.waitForRequest('/a/redirect1'),
server.waitForRequest('/b/c/redirect2'),
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(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('/b/c/redirect2'),
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(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 }) => {
const error = await context._request.get(`${server.PREFIX}/a/redirect1`, {
const error = await context.request.get(`${server.PREFIX}/a/redirect1`, {
headers: {
'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 }) => {
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');
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');
});
@ -515,7 +515,7 @@ it('should support https', async ({ context, httpsServer }) => {
process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = '0';
suppressCertificateWarning();
try {
const response = await context._request.get(httpsServer.EMPTY_PAGE);
const response = await context.request.get(httpsServer.EMPTY_PAGE);
expect(response.status()).toBe(200);
} finally {
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 }) => {
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);
});
@ -533,7 +533,7 @@ it('should resolve url relative to baseURL', async function({ server, contextFac
...contextOptions,
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);
});
@ -553,7 +553,7 @@ it('should support gzip compression', async function({ context, server }) {
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!');
});
@ -567,7 +567,7 @@ it('should throw informatibe error on corrupted gzip body', async function({ con
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`);
});
@ -587,7 +587,7 @@ it('should support brotli compression', async function({ context, server }) {
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!');
});
@ -601,7 +601,7 @@ it('should throw informatibe error on corrupted brotli body', async function({ c
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`);
});
@ -621,7 +621,7 @@ it('should support deflate compression', async function({ context, server }) {
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!');
});
@ -635,7 +635,7 @@ it('should throw informatibe error on corrupted deflate body', async function({
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`);
});
@ -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`);
});
@ -662,7 +662,7 @@ it('should support a timeout of 0', async function({ context, server }) {
}, 50);
});
const response = await context._request.get(server.PREFIX + '/slow', {
const response = await context.request.get(server.PREFIX + '/slow', {
timeout: 0,
});
expect(await response.text()).toBe('done');
@ -678,12 +678,12 @@ it('should respect timeout after redirects', async function({ context, server })
});
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`);
});
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' });
await response.dispose();
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 }) {
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' });
await context.close();
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 }) {
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');
});
@ -710,7 +710,7 @@ it('should override request parameters', async function({ context, page, server
]);
const [req] = await Promise.all([
server.waitForRequest('/empty.html'),
context._request.post(pageReq, {
context.request.post(pageReq, {
headers: {
'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 }) {
const [req] = await Promise.all([
server.waitForRequest('/empty.html'),
context._request.post(server.EMPTY_PAGE, {
context.request.post(server.EMPTY_PAGE, {
form: {
firstName: 'John',
lastName: 'Doe',
@ -753,7 +753,7 @@ it('should encode to application/json by default', async function({ context, pag
};
const [req] = await Promise.all([
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.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([
formReceived,
context._request.post(server.EMPTY_PAGE, {
context.request.post(server.EMPTY_PAGE, {
multipart: {
firstName: 'John',
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 [{ error, fields, files, serverRequest }, response] = await Promise.all([
formReceived,
context._request.post(server.EMPTY_PAGE, {
context.request.post(server.EMPTY_PAGE, {
multipart: {
firstName: 'John',
lastName: 'Doe',
@ -839,7 +839,7 @@ it('should serialize data to json regardless of content-type', async function({
};
const [req] = await Promise.all([
server.waitForRequest('/empty.html'),
context._request.post(server.EMPTY_PAGE, {
context.request.post(server.EMPTY_PAGE, {
headers: {
'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 }) {
const error = await context._request.post(server.EMPTY_PAGE, {
const error = await context.request.post(server.EMPTY_PAGE, {
headers: {
'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 }) {
const error = await context._request.fetch(server.EMPTY_PAGE, {
const error = await context.request.fetch(server.EMPTY_PAGE, {
method: 'GET',
data: {
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.end();
});
await context._request.get(server.PREFIX + '/setcookie.html');
await context.request.get(server.PREFIX + '/setcookie.html');
const contextState = await context.storageState();
expect(contextState.cookies.length).toBe(2);
const requestState = await context._request.storageState();
const requestState = await context.request.storageState();
expect(requestState).toEqual(contextState);
const pageState = await page._request.storageState();
const pageState = await page.request.storageState();
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 });
await page.goto(server.EMPTY_PAGE);
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({
response,
headers: {

View file

@ -25,7 +25,7 @@ export type GlobalFetchFixtures = {
const it = playwrightTest.extend<GlobalFetchFixtures>({
request: async ({ playwright }, use) => {
const request = await playwright._newRequest({ ignoreHTTPSErrors: true });
const request = await playwright.newRequest({ ignoreHTTPSErrors: true });
await use(request);
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);
const exportedState = await request.storageState();
expect(exportedState).toEqual(storageState);
@ -279,7 +279,7 @@ it('should send cookies from storage state', async ({ playwright, server }) => {
],
'origins': []
};
const request = await playwright._newRequest({ storageState });
const request = await playwright.newRequest({ storageState });
const [serverRequest] = await Promise.all([
server.waitForRequest('/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': []
};
const request1 = await playwright._newRequest({ storageState });
const request1 = await playwright.newRequest({ storageState });
const path = testInfo.outputPath('storage-state.json');
const state1 = await request1.storageState({ path });
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');
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();
expect(state2).toEqual(storageState);
});

View file

@ -40,7 +40,7 @@ it.afterAll(() => {
for (const method of ['get', 'post', 'fetch']) {
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');
expect(response.url()).toBe(server.PREFIX + '/simple.json');
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 }) {
const request = await playwright._newRequest();
const request = await playwright.newRequest();
const response = await request.get(server.PREFIX + '/simple.json');
expect(await response.json()).toEqual({ foo: 'bar' });
await request.dispose();
@ -63,7 +63,7 @@ for (const method of ['get', 'post', 'fetch']) {
}
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([
server.waitForRequest('/empty.html'),
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 }) => {
const request = await playwright._newRequest({ timeout: 1 });
const request = await playwright.newRequest({ timeout: 1 });
server.setRoute('/empty.html', (req, res) => {});
const error = await request.get(server.EMPTY_PAGE).catch(e => e);
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 }) => {
server.setRedirect('/a/redirect1', '/b/c/redirect2');
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([
server.waitForRequest('/a/redirect1'),
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 }) => {
server.setAuth('/empty.html', 'user', 'pass');
const request1 = await playwright._newRequest();
const request1 = await playwright.newRequest();
const response1 = await request1.get(server.EMPTY_PAGE);
expect(response1.status()).toBe(401);
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);
expect(response2.status()).toBe(200);
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 }) => {
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);
expect(response2.status()).toBe(401);
});
@ -122,7 +122,7 @@ it('should pass proxy credentials', async ({ playwright, server, proxyServer })
auth = req.headers['proxy-authorization'];
return !!auth;
});
const request = await playwright._newRequest({
const request = await playwright.newRequest({
proxy: { server: `localhost:${proxyServer.PORT}`, username: 'user', password: 'secret' }
});
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 }) => {
const request = await playwright._newRequest({ ignoreHTTPSErrors: true });
const request = await playwright.newRequest({ ignoreHTTPSErrors: true });
const response = await request.get(httpsServer.EMPTY_PAGE);
expect(response.status()).toBe(200);
});
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');
expect(response.url()).toBe(server.EMPTY_PAGE);
});
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([
server.waitForRequest('/empty.html'),
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.fixme(isElectron, 'error: Browser context management is not supported.');
await page.route('**/*', async route => {
const request = await playwright._newRequest();
const request = await playwright.newRequest();
const response = await request.get(server.PREFIX + '/simple.json');
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.fixme(isElectron, 'error: Browser context management is not supported.');
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 });
});
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.fixme(isElectron, 'error: Browser context management is not supported.');
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,
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.fixme(isElectron, 'error: Browser context management is not supported.');
await page.route('**/*', async route => {
const response = await page._request.get(route.request());
const response = await page.request.get(route.request());
route.fulfill({
response,
});
@ -276,7 +276,7 @@ it('should fulfill with fetch response that has multiple set-cookie', async ({ p
res.end();
});
await page.route('**/empty.html', async route => {
const request = await playwright._newRequest();
const request = await playwright.newRequest();
const response = await request.fetch(route.request());
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;
/**
* API testing helper associated with this page. Requests made with this API will use page cookies.
*/
_request: FetchRequest;
accessibility: Accessibility;
/**
@ -2755,6 +2750,11 @@ export interface Page {
waitUntil?: "load"|"domcontentloaded"|"networkidle";
}): 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.
*
@ -6230,11 +6230,6 @@ export interface BrowserContext {
*/
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
* obtained via
@ -6457,6 +6452,11 @@ export interface BrowserContext {
*/
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
* 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>;
}
/**
* 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].
* @param options
*/
export const _newRequest: (options?: {
export const newRequest: (options?: {
/**
* When using
* [fetchRequest.get(urlOrRequest[, options])](https://playwright.dev/docs/api/class-fetchrequest#fetch-request-get),
@ -13490,16 +13500,6 @@ export const _newRequest: (options?: {
userAgent?: string;
}) => 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
* information.