chore: route.fetch(postData) (#19436)

This commit is contained in:
Pavel Feldman 2022-12-13 14:01:39 -08:00 committed by GitHub
parent 87141f6856
commit d1559a0fcc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 70 additions and 65 deletions

View File

@ -115,7 +115,7 @@ If set changes the request method (e.g. GET or POST).
### option: Route.continue.postData
* since: v1.8
* langs: js, python, java
- `postData` <[string]|[Buffer]>
- `postData` <[string]|[Buffer]|[Serializable]>
If set changes the post data of request.
@ -391,7 +391,7 @@ If set changes the request method (e.g. GET or POST).
### option: Route.fallback.postData
* since: v1.23
* langs: js, python, java
- `postData` <[string]|[Buffer]>
- `postData` <[string]|[Buffer]|[Serializable]>
If set changes the post data of request.
@ -480,10 +480,10 @@ If set changes the request URL. New URL must have same protocol as original one.
If set changes the request method (e.g. GET or POST).
### option: Route.fetch.postData = %%-js-python-csharp-fetch-option-data-%%
### option: Route.fetch.postData = %%-js-python-csharp-fetch-option-post-data-%%
* since: v1.29
### option: Route.fetch.data
### option: Route.fetch.postData
* since: v1.29
* langs: csharp
- `postData` <[Buffer]>
@ -616,33 +616,6 @@ Optional response body as raw bytes.
JSON response. This method will set the content type to `application/json` if not set.
**Usage**
```js
await page.route('https://dog.ceo/api/breeds/list/all', async route => {
const json = {
message: { 'test_breed': [] }
};
await route.fulfill({ json });
});
```
```python async
async def handle(route):
json = { "test_breed": [] }
await route.fulfill(json=json)
await page.route("https://dog.ceo/api/breeds/list/all", handle)
```
```python sync
async def handle(route):
json = { "test_breed": [] }
route.fulfill(json=json)
page.route("https://dog.ceo/api/breeds/list/all", handle)
```
### option: Route.fulfill.json
* since: v1.29
* langs: csharp

View File

@ -389,6 +389,14 @@ Allows to set post data of the request. If the data parameter is an object, it w
and `content-type` header will be set to `application/json` if not explicitly set. Otherwise the `content-type` header will be
set to `application/octet-stream` if not explicitly set.
## js-python-csharp-fetch-option-post-data
* langs: js, python, csharp
- `postData` <[string]|[Buffer]|[Serializable]>
Allows to set post data of the request. If the data parameter is an object, it will be serialized to json string
and `content-type` header will be set to `application/json` if not explicitly set. Otherwise the `content-type` header will be
set to `application/octet-stream` if not explicitly set.
## js-python-csharp-fetch-option-ignorehttpserrors
* langs: js, python, csharp
- `ignoreHTTPSErrors` <[boolean]>

View File

@ -32,6 +32,7 @@ import type { HeadersArray, URLMatch } from '../common/types';
import { urlMatches } from '../common/netUtils';
import { MultiMap } from '../utils/multimap';
import { APIResponse } from './fetch';
import type { Serializable } from '../../types/structs';
export type NetworkCookie = {
name: string,
@ -56,11 +57,18 @@ export type SetNetworkCookieParam = {
sameSite?: 'Strict' | 'Lax' | 'None'
};
type SerializedFallbackOverrides = {
url?: string;
method?: string;
headers?: Headers;
postDataBuffer?: Buffer;
};
type FallbackOverrides = {
url?: string;
method?: string;
headers?: Headers;
postData?: string | Buffer;
postData?: string | Buffer | Serializable;
};
export class Request extends ChannelOwner<channels.RequestChannel> implements api.Request {
@ -71,7 +79,7 @@ export class Request extends ChannelOwner<channels.RequestChannel> implements ap
private _actualHeadersPromise: Promise<RawHeaders> | undefined;
private _postData: Buffer | null;
_timing: ResourceTiming;
private _fallbackOverrides: FallbackOverrides = {};
private _fallbackOverrides: SerializedFallbackOverrides = {};
static from(request: channels.RequestChannel): Request {
return (request as any)._object;
@ -114,17 +122,14 @@ export class Request extends ChannelOwner<channels.RequestChannel> implements ap
}
postData(): string | null {
if (this._fallbackOverrides.postData)
return this._fallbackOverrides.postData.toString('utf-8');
if (this._fallbackOverrides.postDataBuffer)
return this._fallbackOverrides.postDataBuffer.toString('utf-8');
return this._postData ? this._postData.toString('utf8') : null;
}
postDataBuffer(): Buffer | null {
if (this._fallbackOverrides.postData) {
if (isString(this._fallbackOverrides.postData))
return Buffer.from(this._fallbackOverrides.postData, 'utf-8');
return this._fallbackOverrides.postData;
}
if (this._fallbackOverrides.postDataBuffer)
return this._fallbackOverrides.postDataBuffer;
return this._postData;
}
@ -251,7 +256,21 @@ export class Request extends ChannelOwner<channels.RequestChannel> implements ap
}
_applyFallbackOverrides(overrides: FallbackOverrides) {
this._fallbackOverrides = { ...this._fallbackOverrides, ...overrides };
const basicOptions = { ...overrides, postData: undefined };
const postData = overrides.postData;
let postDataBuffer = this._fallbackOverrides.postDataBuffer;
if (isString(postData))
postDataBuffer = Buffer.from(postData, 'utf-8');
else if (postData instanceof Buffer)
postDataBuffer = postData;
else if (postData)
postDataBuffer = Buffer.from(JSON.stringify(postData), 'utf-8');
this._fallbackOverrides = {
...this._fallbackOverrides,
...basicOptions,
postDataBuffer,
};
}
_fallbackOverridesForContinue() {
@ -400,12 +419,11 @@ export class Route extends ChannelOwner<channels.RouteChannel> implements api.Ro
async _innerContinue(internal = false) {
const options = this.request()._fallbackOverridesForContinue();
return await this._wrapApiCall(async () => {
const postDataBuffer = isString(options.postData) ? Buffer.from(options.postData, 'utf8') : options.postData;
await this._raceWithTargetClose(this._channel.continue({
url: options.url,
method: options.method,
headers: options.headers ? headersObjectToArray(options.headers) : undefined,
postData: postDataBuffer,
postData: options.postDataBuffer,
}));
}, !!internal);
}

View File

@ -17067,7 +17067,7 @@ export interface Route {
/**
* If set changes the post data of request.
*/
postData?: string|Buffer;
postData?: string|Buffer|Serializable;
/**
* If set changes the request URL. New URL must have same protocol as original one.
@ -17154,7 +17154,7 @@ export interface Route {
/**
* If set changes the post data of request.
*/
postData?: string|Buffer;
postData?: string|Buffer|Serializable;
/**
* If set changes the request URL. New URL must have same protocol as original one. Changing the URL won't affect the
@ -17181,13 +17181,6 @@ export interface Route {
* @param options
*/
fetch(options?: {
/**
* Allows to set post data of the request. If the data parameter is an object, it will be serialized to json string
* and `content-type` header will be set to `application/json` if not explicitly set. Otherwise the `content-type`
* header will be set to `application/octet-stream` if not explicitly set.
*/
data?: string|Buffer|Serializable;
/**
* If set changes the request HTTP headers. Header values will be converted to a string.
*/
@ -17198,6 +17191,13 @@ export interface Route {
*/
method?: string;
/**
* Allows to set post data of the request. If the data parameter is an object, it will be serialized to json string
* and `content-type` header will be set to `application/json` if not explicitly set. Otherwise the `content-type`
* header will be set to `application/octet-stream` if not explicitly set.
*/
postData?: string|Buffer|Serializable;
/**
* If set changes the request URL. New URL must have same protocol as original one.
*/
@ -17247,18 +17247,6 @@ export interface Route {
/**
* JSON response. This method will set the content type to `application/json` if not set.
*
* **Usage**
*
* ```js
* await page.route('https://dog.ceo/api/breeds/list/all', async route => {
* const json = {
* message: { 'test_breed': [] }
* };
* await route.fulfill({ json });
* });
* ```
*
*/
json?: Serializable;

View File

@ -259,4 +259,22 @@ it.describe('post data', () => {
expect(postDataBuffer[i]).toBe(arr[i]);
}
});
it('should amend json post data', async ({ page, server }) => {
await page.goto(server.EMPTY_PAGE);
let postData: string;
await page.route('**/*', route => {
postData = route.request().postDataJSON();
route.continue();
});
await page.route('**/*', route => {
route.fallback({ postData: { foo: 'bar' } });
});
const [serverRequest] = await Promise.all([
server.waitForRequest('/sleep.zzz'),
page.evaluate(() => fetch('/sleep.zzz', { method: 'POST', body: 'birdy' }))
]);
expect(postData).toEqual({ foo: 'bar' });
expect((await serverRequest.postBody).toString('utf8')).toBe('{"foo":"bar"}');
});
});

View File

@ -224,7 +224,7 @@ it('should intercept with post data override', async ({ page, server, isElectron
const requestPromise = server.waitForRequest('/empty.html');
await page.route('**/*.html', async route => {
const response = await route.fetch({
data: { 'foo': 'bar' },
postData: { 'foo': 'bar' },
});
await route.fulfill({ response });
});