chore: rename Fetch Request/Response to API (#10087)

This commit is contained in:
Max Schmitt 2021-11-05 16:27:49 +01:00 committed by GitHub
parent ceedf45d4a
commit c5b19351f6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
17 changed files with 124 additions and 124 deletions

View file

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

View file

@ -36,7 +36,7 @@ import { CDPSession } from './cdpSession';
import { Tracing } from './tracing'; import { Tracing } from './tracing';
import type { BrowserType } from './browserType'; import type { BrowserType } from './browserType';
import { Artifact } from './artifact'; import { Artifact } from './artifact';
import { FetchRequest } from './fetch'; import { APIRequestContext } from './fetch';
import { createInstrumentation } from './clientInstrumentation'; import { createInstrumentation } from './clientInstrumentation';
export class BrowserContext extends ChannelOwner<channels.BrowserContextChannel, channels.BrowserContextInitializer> implements api.BrowserContext { export class BrowserContext extends ChannelOwner<channels.BrowserContextChannel, channels.BrowserContextInitializer> implements api.BrowserContext {
@ -50,7 +50,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: APIRequestContext;
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>();
@ -70,7 +70,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 = APIRequestContext.from(initializer.APIRequestContext);
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

@ -39,7 +39,7 @@ import { ParsedStackTrace } from '../utils/stackTrace';
import { Artifact } from './artifact'; import { Artifact } from './artifact';
import { EventEmitter } from 'events'; import { EventEmitter } from 'events';
import { JsonPipe } from './jsonPipe'; import { JsonPipe } from './jsonPipe';
import { FetchRequest } from './fetch'; import { APIRequestContext } from './fetch';
class Root extends ChannelOwner<channels.RootChannel, {}> { class Root extends ChannelOwner<channels.RootChannel, {}> {
constructor(connection: Connection) { constructor(connection: Connection) {
@ -185,6 +185,9 @@ export class Connection extends EventEmitter {
case 'AndroidDevice': case 'AndroidDevice':
result = new AndroidDevice(parent, type, guid, initializer); result = new AndroidDevice(parent, type, guid, initializer);
break; break;
case 'APIRequestContext':
result = new APIRequestContext(parent, type, guid, initializer);
break;
case 'Artifact': case 'Artifact':
result = new Artifact(parent, type, guid, initializer); result = new Artifact(parent, type, guid, initializer);
break; break;
@ -218,9 +221,6 @@ export class Connection extends EventEmitter {
case 'ElementHandle': case 'ElementHandle':
result = new ElementHandle(parent, type, guid, initializer); result = new ElementHandle(parent, type, guid, initializer);
break; break;
case 'FetchRequest':
result = new FetchRequest(parent, type, guid, initializer);
break;
case 'Frame': case 'Frame':
result = new Frame(parent, type, guid, initializer); result = new Frame(parent, type, guid, initializer);
break; break;

View file

@ -49,18 +49,18 @@ type NewContextOptions = Omit<channels.PlaywrightNewRequestOptions, 'extraHTTPHe
type RequestWithBodyOptions = Omit<FetchOptions, 'method'>; type RequestWithBodyOptions = Omit<FetchOptions, 'method'>;
type RequestWithoutBodyOptions = Omit<RequestWithBodyOptions, 'data'|'form'|'multipart'>; type RequestWithoutBodyOptions = Omit<RequestWithBodyOptions, 'data'|'form'|'multipart'>;
export class Fetch implements api.APIRequest { export class APIRequest implements api.APIRequest {
private _playwright: Playwright; private _playwright: Playwright;
constructor(playwright: Playwright) { constructor(playwright: Playwright) {
this._playwright = playwright; this._playwright = playwright;
} }
async newContext(options: NewContextOptions = {}): Promise<FetchRequest> { async newContext(options: NewContextOptions = {}): Promise<APIRequestContext> {
return await this._playwright._wrapApiCall(async (channel: channels.PlaywrightChannel) => { return await this._playwright._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')) :
options.storageState; options.storageState;
return FetchRequest.from((await channel.newRequest({ return APIRequestContext.from((await channel.newRequest({
...options, ...options,
extraHTTPHeaders: options.extraHTTPHeaders ? headersObjectToArray(options.extraHTTPHeaders) : undefined, extraHTTPHeaders: options.extraHTTPHeaders ? headersObjectToArray(options.extraHTTPHeaders) : undefined,
storageState, storageState,
@ -69,65 +69,65 @@ export class Fetch implements api.APIRequest {
} }
} }
export class FetchRequest extends ChannelOwner<channels.FetchRequestChannel, channels.FetchRequestInitializer> implements api.APIRequestContext { export class APIRequestContext extends ChannelOwner<channels.APIRequestContextChannel, channels.APIRequestContextInitializer> implements api.APIRequestContext {
static from(channel: channels.FetchRequestChannel): FetchRequest { static from(channel: channels.APIRequestContextChannel): APIRequestContext {
return (channel as any)._object; return (channel as any)._object;
} }
constructor(parent: ChannelOwner, type: string, guid: string, initializer: channels.FetchRequestInitializer) { constructor(parent: ChannelOwner, type: string, guid: string, initializer: channels.APIRequestContextInitializer) {
super(parent, type, guid, initializer); super(parent, type, guid, initializer);
} }
dispose(): Promise<void> { dispose(): Promise<void> {
return this._wrapApiCall(async (channel: channels.FetchRequestChannel) => { return this._wrapApiCall(async (channel: channels.APIRequestContextChannel) => {
await channel.dispose(); await channel.dispose();
}); });
} }
async delete(url: string, options?: RequestWithBodyOptions): Promise<FetchResponse> { async delete(url: string, options?: RequestWithBodyOptions): Promise<APIResponse> {
return this.fetch(url, { return this.fetch(url, {
...options, ...options,
method: 'DELETE', method: 'DELETE',
}); });
} }
async head(url: string, options?: RequestWithoutBodyOptions): Promise<FetchResponse> { async head(url: string, options?: RequestWithoutBodyOptions): Promise<APIResponse> {
return this.fetch(url, { return this.fetch(url, {
...options, ...options,
method: 'HEAD', method: 'HEAD',
}); });
} }
async get(url: string, options?: RequestWithoutBodyOptions): Promise<FetchResponse> { async get(url: string, options?: RequestWithoutBodyOptions): Promise<APIResponse> {
return this.fetch(url, { return this.fetch(url, {
...options, ...options,
method: 'GET', method: 'GET',
}); });
} }
async patch(url: string, options?: RequestWithBodyOptions): Promise<FetchResponse> { async patch(url: string, options?: RequestWithBodyOptions): Promise<APIResponse> {
return this.fetch(url, { return this.fetch(url, {
...options, ...options,
method: 'PATCH', method: 'PATCH',
}); });
} }
async post(url: string, options?: RequestWithBodyOptions): Promise<FetchResponse> { async post(url: string, options?: RequestWithBodyOptions): Promise<APIResponse> {
return this.fetch(url, { return this.fetch(url, {
...options, ...options,
method: 'POST', method: 'POST',
}); });
} }
async put(url: string, options?: RequestWithBodyOptions): Promise<FetchResponse> { async put(url: string, options?: RequestWithBodyOptions): Promise<APIResponse> {
return this.fetch(url, { return this.fetch(url, {
...options, ...options,
method: 'PUT', method: 'PUT',
}); });
} }
async fetch(urlOrRequest: string | api.Request, options: FetchOptions = {}): Promise<FetchResponse> { async fetch(urlOrRequest: string | api.Request, options: FetchOptions = {}): Promise<APIResponse> {
return this._wrapApiCall(async (channel: channels.FetchRequestChannel) => { return this._wrapApiCall(async (channel: channels.APIRequestContextChannel) => {
const request: network.Request | undefined = (urlOrRequest instanceof network.Request) ? urlOrRequest as network.Request : undefined; const request: network.Request | undefined = (urlOrRequest instanceof network.Request) ? urlOrRequest as network.Request : undefined;
assert(request || typeof urlOrRequest === 'string', 'First argument must be either URL string or Request'); assert(request || typeof urlOrRequest === 'string', 'First argument must be either URL string or Request');
assert((options.data === undefined ? 0 : 1) + (options.form === undefined ? 0 : 1) + (options.multipart === undefined ? 0 : 1) <= 1, `Only one of 'data', 'form' or 'multipart' can be specified`); assert((options.data === undefined ? 0 : 1) + (options.form === undefined ? 0 : 1) + (options.multipart === undefined ? 0 : 1) <= 1, `Only one of 'data', 'form' or 'multipart' can be specified`);
@ -186,12 +186,12 @@ export class FetchRequest extends ChannelOwner<channels.FetchRequestChannel, cha
}); });
if (result.error) if (result.error)
throw new Error(result.error); throw new Error(result.error);
return new FetchResponse(this, result.response!); return new APIResponse(this, result.response!);
}); });
} }
async storageState(options: { path?: string } = {}): Promise<StorageState> { async storageState(options: { path?: string } = {}): Promise<StorageState> {
return await this._wrapApiCall(async (channel: channels.FetchRequestChannel) => { return await this._wrapApiCall(async (channel: channels.APIRequestContextChannel) => {
const state = await channel.storageState(); const state = await channel.storageState();
if (options.path) { if (options.path) {
await mkdirIfNeeded(options.path); await mkdirIfNeeded(options.path);
@ -202,12 +202,12 @@ export class FetchRequest extends ChannelOwner<channels.FetchRequestChannel, cha
} }
} }
export class FetchResponse implements api.APIResponse { export class APIResponse implements api.APIResponse {
private readonly _initializer: channels.FetchResponse; private readonly _initializer: channels.APIResponse;
private readonly _headers: RawHeaders; private readonly _headers: RawHeaders;
private readonly _request: FetchRequest; private readonly _request: APIRequestContext;
constructor(context: FetchRequest, initializer: channels.FetchResponse) { constructor(context: APIRequestContext, initializer: channels.APIResponse) {
this._request = context; this._request = context;
this._initializer = initializer; this._initializer = initializer;
this._headers = new RawHeaders(this._initializer.headers); this._headers = new RawHeaders(this._initializer.headers);
@ -238,7 +238,7 @@ export class FetchResponse implements api.APIResponse {
} }
async body(): Promise<Buffer> { async body(): Promise<Buffer> {
return this._request._wrapApiCall(async (channel: channels.FetchRequestChannel) => { return this._request._wrapApiCall(async (channel: channels.APIRequestContextChannel) => {
try { try {
const result = await channel.fetchResponseBody({ fetchUid: this._fetchUid() }); const result = await channel.fetchResponseBody({ fetchUid: this._fetchUid() });
if (result.binary === undefined) if (result.binary === undefined)
@ -263,8 +263,8 @@ export class FetchResponse implements api.APIResponse {
} }
async dispose(): Promise<void> { async dispose(): Promise<void> {
return this._request._wrapApiCall(async (channel: channels.FetchRequestChannel) => { return this._request._wrapApiCall(async (channel: channels.APIRequestContextChannel) => {
await channel.disposeFetchResponse({ fetchUid: this._fetchUid() }); await channel.disposeAPIResponse({ fetchUid: this._fetchUid() });
}); });
} }

View file

@ -30,7 +30,7 @@ import * as api from '../../types/types';
import { HeadersArray, URLMatch } from '../common/types'; import { HeadersArray, URLMatch } from '../common/types';
import { urlMatches } from './clientHelper'; import { urlMatches } from './clientHelper';
import { MultiMap } from '../utils/multimap'; import { MultiMap } from '../utils/multimap';
import { FetchResponse } from './fetch'; import { APIResponse } from './fetch';
export type NetworkCookie = { export type NetworkCookie = {
name: string, name: string,
@ -241,8 +241,8 @@ export class Route extends ChannelOwner<channels.RouteChannel, channels.RouteIni
if (options.response) { if (options.response) {
statusOption ||= options.response.status(); statusOption ||= options.response.status();
headersOption ||= options.response.headers(); headersOption ||= options.response.headers();
if (options.body === undefined && options.path === undefined && options.response instanceof FetchResponse) if (options.body === undefined && options.path === undefined && options.response instanceof APIResponse)
fetchResponseUid = (options.response as FetchResponse)._fetchUid(); fetchResponseUid = (options.response as APIResponse)._fetchUid();
} }
let isBase64 = false; let isBase64 = false;

View file

@ -47,7 +47,7 @@ import { isString, isRegExp, isObject, mkdirIfNeeded, headersObjectToArray } fro
import { isSafeCloseError } from '../utils/errors'; import { isSafeCloseError } from '../utils/errors';
import { Video } from './video'; import { Video } from './video';
import { Artifact } from './artifact'; import { Artifact } from './artifact';
import { FetchRequest } from './fetch'; import { APIRequestContext } from './fetch';
type PDFOptions = Omit<channels.PagePdfParams, 'width' | 'height' | 'margin'> & { type PDFOptions = Omit<channels.PagePdfParams, 'width' | 'height' | 'margin'> & {
width?: string | number, width?: string | number,
@ -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: APIRequestContext;
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>();

View file

@ -24,7 +24,7 @@ import { Android } from './android';
import { BrowserType } from './browserType'; import { BrowserType } from './browserType';
import { ChannelOwner } from './channelOwner'; import { ChannelOwner } from './channelOwner';
import { Electron } from './electron'; import { Electron } from './electron';
import { Fetch } from './fetch'; import { APIRequest } from './fetch';
import { Selectors, SelectorsOwner } from './selectors'; import { Selectors, SelectorsOwner } from './selectors';
import { Size } from './types'; import { Size } from './types';
const dnsLookupAsync = util.promisify(dns.lookup); const dnsLookupAsync = util.promisify(dns.lookup);
@ -47,14 +47,14 @@ export class Playwright extends ChannelOwner<channels.PlaywrightChannel, channel
readonly webkit: BrowserType; readonly webkit: BrowserType;
readonly devices: Devices; readonly devices: Devices;
selectors: Selectors; selectors: Selectors;
readonly request: Fetch; readonly request: APIRequest;
readonly errors: { TimeoutError: typeof TimeoutError }; readonly errors: { TimeoutError: typeof TimeoutError };
private _sockets = new Map<string, net.Socket>(); private _sockets = new Map<string, net.Socket>();
private _redirectPortForTest: number | undefined; private _redirectPortForTest: number | undefined;
constructor(parent: ChannelOwner, type: string, guid: string, initializer: channels.PlaywrightInitializer) { constructor(parent: ChannelOwner, type: string, guid: string, initializer: channels.PlaywrightInitializer) {
super(parent, type, guid, initializer); super(parent, type, guid, initializer);
this.request = new Fetch(this); this.request = new APIRequest(this);
this.chromium = BrowserType.from(initializer.chromium); this.chromium = BrowserType.from(initializer.chromium);
this.chromium._playwright = this; this.chromium._playwright = this;
this.firefox = BrowserType.from(initializer.firefox); this.firefox = BrowserType.from(initializer.firefox);

View file

@ -19,7 +19,7 @@ import { Dispatcher, DispatcherScope, lookupDispatcher } from './dispatcher';
import { PageDispatcher, BindingCallDispatcher, WorkerDispatcher } from './pageDispatcher'; import { PageDispatcher, BindingCallDispatcher, WorkerDispatcher } from './pageDispatcher';
import { FrameDispatcher } from './frameDispatcher'; import { FrameDispatcher } from './frameDispatcher';
import * as channels from '../protocol/channels'; import * as channels from '../protocol/channels';
import { RouteDispatcher, RequestDispatcher, ResponseDispatcher, FetchRequestDispatcher } from './networkDispatchers'; import { RouteDispatcher, RequestDispatcher, ResponseDispatcher, APIRequestContextDispatcher } from './networkDispatchers';
import { CRBrowserContext } from '../server/chromium/crBrowser'; import { CRBrowserContext } from '../server/chromium/crBrowser';
import { CDPSessionDispatcher } from './cdpSessionDispatcher'; import { CDPSessionDispatcher } from './cdpSessionDispatcher';
import { RecorderSupplement } from '../server/supplements/recorderSupplement'; import { RecorderSupplement } from '../server/supplements/recorderSupplement';
@ -34,7 +34,7 @@ export class BrowserContextDispatcher extends Dispatcher<BrowserContext, channel
constructor(scope: DispatcherScope, context: BrowserContext) { constructor(scope: DispatcherScope, context: BrowserContext) {
super(scope, context, 'BrowserContext', { super(scope, context, 'BrowserContext', {
isChromium: context._browser.options.isChromium, isChromium: context._browser.options.isChromium,
fetchRequest: FetchRequestDispatcher.from(scope, context.fetchRequest), APIRequestContext: APIRequestContextDispatcher.from(scope, context.fetchRequest),
}, true); }, true);
this._context = context; this._context = context;
// Note: when launching persistent context, dispatcher is created very late, // Note: when launching persistent context, dispatcher is created very late,

View file

@ -15,7 +15,7 @@
*/ */
import * as channels from '../protocol/channels'; import * as channels from '../protocol/channels';
import { FetchRequest } from '../server/fetch'; import { APIRequestContext } from '../server/fetch';
import { CallMetadata } from '../server/instrumentation'; import { CallMetadata } from '../server/instrumentation';
import { Request, Response, Route, WebSocket } from '../server/network'; import { Request, Response, Route, WebSocket } from '../server/network';
import { Dispatcher, DispatcherScope, existingDispatcher, lookupNullableDispatcher } from './dispatcher'; import { Dispatcher, DispatcherScope, existingDispatcher, lookupNullableDispatcher } from './dispatcher';
@ -143,33 +143,33 @@ export class WebSocketDispatcher extends Dispatcher<WebSocket, channels.WebSocke
} }
} }
export class FetchRequestDispatcher extends Dispatcher<FetchRequest, channels.FetchRequestInitializer, channels.FetchRequestEvents> implements channels.FetchRequestChannel { export class APIRequestContextDispatcher extends Dispatcher<APIRequestContext, channels.APIRequestContextInitializer, channels.APIRequestContextEvents> implements channels.APIRequestContextChannel {
static from(scope: DispatcherScope, request: FetchRequest): FetchRequestDispatcher { static from(scope: DispatcherScope, request: APIRequestContext): APIRequestContextDispatcher {
const result = existingDispatcher<FetchRequestDispatcher>(request); const result = existingDispatcher<APIRequestContextDispatcher>(request);
return result || new FetchRequestDispatcher(scope, request); return result || new APIRequestContextDispatcher(scope, request);
} }
static fromNullable(scope: DispatcherScope, request: FetchRequest | null): FetchRequestDispatcher | undefined { static fromNullable(scope: DispatcherScope, request: APIRequestContext | null): APIRequestContextDispatcher | undefined {
return request ? FetchRequestDispatcher.from(scope, request) : undefined; return request ? APIRequestContextDispatcher.from(scope, request) : undefined;
} }
private constructor(scope: DispatcherScope, request: FetchRequest) { private constructor(scope: DispatcherScope, request: APIRequestContext) {
super(scope, request, 'FetchRequest', {}, true); super(scope, request, 'APIRequestContext', {}, true);
request.once(FetchRequest.Events.Dispose, () => { request.once(APIRequestContext.Events.Dispose, () => {
if (!this._disposed) if (!this._disposed)
super._dispose(); super._dispose();
}); });
} }
async storageState(params?: channels.FetchRequestStorageStateParams): Promise<channels.FetchRequestStorageStateResult> { async storageState(params?: channels.APIRequestContextStorageStateParams): Promise<channels.APIRequestContextStorageStateResult> {
return this._object.storageState(); return this._object.storageState();
} }
async dispose(params?: channels.FetchRequestDisposeParams): Promise<void> { async dispose(params?: channels.APIRequestContextDisposeParams): Promise<void> {
this._object.dispose(); this._object.dispose();
} }
async fetch(params: channels.FetchRequestFetchParams, metadata?: channels.Metadata): Promise<channels.FetchRequestFetchResult> { async fetch(params: channels.APIRequestContextFetchParams, metadata?: channels.Metadata): Promise<channels.APIRequestContextFetchResult> {
const { fetchResponse, error } = await this._object.fetch(params); const { fetchResponse, error } = await this._object.fetch(params);
let response; let response;
if (fetchResponse) { if (fetchResponse) {
@ -184,12 +184,12 @@ export class FetchRequestDispatcher extends Dispatcher<FetchRequest, channels.Fe
return { response, error }; return { response, error };
} }
async fetchResponseBody(params: channels.FetchRequestFetchResponseBodyParams, metadata?: channels.Metadata): Promise<channels.FetchRequestFetchResponseBodyResult> { async fetchResponseBody(params: channels.APIRequestContextFetchResponseBodyParams, metadata?: channels.Metadata): Promise<channels.APIRequestContextFetchResponseBodyResult> {
const buffer = this._object.fetchResponses.get(params.fetchUid); const buffer = this._object.fetchResponses.get(params.fetchUid);
return { binary: buffer ? buffer.toString('base64') : undefined }; return { binary: buffer ? buffer.toString('base64') : undefined };
} }
async disposeFetchResponse(params: channels.FetchRequestDisposeFetchResponseParams, metadata?: channels.Metadata): Promise<void> { async disposeAPIResponse(params: channels.APIRequestContextDisposeAPIResponseParams, metadata?: channels.Metadata): Promise<void> {
this._object.fetchResponses.delete(params.fetchUid); this._object.fetchResponses.delete(params.fetchUid);
} }
} }

View file

@ -16,7 +16,7 @@
import net, { AddressInfo } from 'net'; import net, { AddressInfo } from 'net';
import * as channels from '../protocol/channels'; import * as channels from '../protocol/channels';
import { GlobalFetchRequest } from '../server/fetch'; import { GlobalAPIRequestContext } from '../server/fetch';
import { Playwright } from '../server/playwright'; import { Playwright } from '../server/playwright';
import * as types from '../server/types'; import * as types from '../server/types';
import { debugLogger } from '../utils/debugLogger'; import { debugLogger } from '../utils/debugLogger';
@ -26,7 +26,7 @@ import { AndroidDispatcher } from './androidDispatcher';
import { BrowserTypeDispatcher } from './browserTypeDispatcher'; import { BrowserTypeDispatcher } from './browserTypeDispatcher';
import { Dispatcher, DispatcherScope } from './dispatcher'; import { Dispatcher, DispatcherScope } from './dispatcher';
import { ElectronDispatcher } from './electronDispatcher'; import { ElectronDispatcher } from './electronDispatcher';
import { FetchRequestDispatcher } from './networkDispatchers'; import { APIRequestContextDispatcher } from './networkDispatchers';
import { SelectorsDispatcher } from './selectorsDispatcher'; import { SelectorsDispatcher } from './selectorsDispatcher';
export class PlaywrightDispatcher extends Dispatcher<Playwright, channels.PlaywrightInitializer, channels.PlaywrightEvents> implements channels.PlaywrightChannel { export class PlaywrightDispatcher extends Dispatcher<Playwright, channels.PlaywrightInitializer, channels.PlaywrightEvents> implements channels.PlaywrightChannel {
@ -75,8 +75,8 @@ export class PlaywrightDispatcher extends Dispatcher<Playwright, channels.Playwr
} }
async newRequest(params: channels.PlaywrightNewRequestParams, metadata?: channels.Metadata): Promise<channels.PlaywrightNewRequestResult> { async newRequest(params: channels.PlaywrightNewRequestParams, metadata?: channels.Metadata): Promise<channels.PlaywrightNewRequestResult> {
const request = new GlobalFetchRequest(this._object, params); const request = new GlobalAPIRequestContext(this._object, params);
return { request: FetchRequestDispatcher.from(this._scope, request) }; return { request: APIRequestContextDispatcher.from(this._scope, request) };
} }
} }

View file

@ -161,16 +161,16 @@ export type FormField = {
}, },
}; };
// ----------- FetchRequest ----------- // ----------- APIRequestContext -----------
export type FetchRequestInitializer = {}; export type APIRequestContextInitializer = {};
export interface FetchRequestChannel extends Channel { export interface APIRequestContextChannel extends Channel {
fetch(params: FetchRequestFetchParams, metadata?: Metadata): Promise<FetchRequestFetchResult>; fetch(params: APIRequestContextFetchParams, metadata?: Metadata): Promise<APIRequestContextFetchResult>;
fetchResponseBody(params: FetchRequestFetchResponseBodyParams, metadata?: Metadata): Promise<FetchRequestFetchResponseBodyResult>; fetchResponseBody(params: APIRequestContextFetchResponseBodyParams, metadata?: Metadata): Promise<APIRequestContextFetchResponseBodyResult>;
storageState(params?: FetchRequestStorageStateParams, metadata?: Metadata): Promise<FetchRequestStorageStateResult>; storageState(params?: APIRequestContextStorageStateParams, metadata?: Metadata): Promise<APIRequestContextStorageStateResult>;
disposeFetchResponse(params: FetchRequestDisposeFetchResponseParams, metadata?: Metadata): Promise<FetchRequestDisposeFetchResponseResult>; disposeAPIResponse(params: APIRequestContextDisposeAPIResponseParams, metadata?: Metadata): Promise<APIRequestContextDisposeAPIResponseResult>;
dispose(params?: FetchRequestDisposeParams, metadata?: Metadata): Promise<FetchRequestDisposeResult>; dispose(params?: APIRequestContextDisposeParams, metadata?: Metadata): Promise<APIRequestContextDisposeResult>;
} }
export type FetchRequestFetchParams = { export type APIRequestContextFetchParams = {
url: string, url: string,
params?: NameValue[], params?: NameValue[],
method?: string, method?: string,
@ -183,7 +183,7 @@ export type FetchRequestFetchParams = {
failOnStatusCode?: boolean, failOnStatusCode?: boolean,
ignoreHTTPSErrors?: boolean, ignoreHTTPSErrors?: boolean,
}; };
export type FetchRequestFetchOptions = { export type APIRequestContextFetchOptions = {
params?: NameValue[], params?: NameValue[],
method?: string, method?: string,
headers?: NameValue[], headers?: NameValue[],
@ -195,40 +195,40 @@ export type FetchRequestFetchOptions = {
failOnStatusCode?: boolean, failOnStatusCode?: boolean,
ignoreHTTPSErrors?: boolean, ignoreHTTPSErrors?: boolean,
}; };
export type FetchRequestFetchResult = { export type APIRequestContextFetchResult = {
response?: FetchResponse, response?: APIResponse,
error?: string, error?: string,
}; };
export type FetchRequestFetchResponseBodyParams = { export type APIRequestContextFetchResponseBodyParams = {
fetchUid: string, fetchUid: string,
}; };
export type FetchRequestFetchResponseBodyOptions = { export type APIRequestContextFetchResponseBodyOptions = {
}; };
export type FetchRequestFetchResponseBodyResult = { export type APIRequestContextFetchResponseBodyResult = {
binary?: Binary, binary?: Binary,
}; };
export type FetchRequestStorageStateParams = {}; export type APIRequestContextStorageStateParams = {};
export type FetchRequestStorageStateOptions = {}; export type APIRequestContextStorageStateOptions = {};
export type FetchRequestStorageStateResult = { export type APIRequestContextStorageStateResult = {
cookies: NetworkCookie[], cookies: NetworkCookie[],
origins: OriginStorage[], origins: OriginStorage[],
}; };
export type FetchRequestDisposeFetchResponseParams = { export type APIRequestContextDisposeAPIResponseParams = {
fetchUid: string, fetchUid: string,
}; };
export type FetchRequestDisposeFetchResponseOptions = { export type APIRequestContextDisposeAPIResponseOptions = {
}; };
export type FetchRequestDisposeFetchResponseResult = void; export type APIRequestContextDisposeAPIResponseResult = void;
export type FetchRequestDisposeParams = {}; export type APIRequestContextDisposeParams = {};
export type FetchRequestDisposeOptions = {}; export type APIRequestContextDisposeOptions = {};
export type FetchRequestDisposeResult = void; export type APIRequestContextDisposeResult = void;
export interface FetchRequestEvents { export interface APIRequestContextEvents {
} }
export type FetchResponse = { export type APIResponse = {
fetchUid: string, fetchUid: string,
url: string, url: string,
status: number, status: number,
@ -389,7 +389,7 @@ export type PlaywrightNewRequestOptions = {
}, },
}; };
export type PlaywrightNewRequestResult = { export type PlaywrightNewRequestResult = {
request: FetchRequestChannel, request: APIRequestContextChannel,
}; };
export interface PlaywrightEvents { export interface PlaywrightEvents {
@ -854,7 +854,7 @@ export interface EventTargetEvents {
// ----------- BrowserContext ----------- // ----------- BrowserContext -----------
export type BrowserContextInitializer = { export type BrowserContextInitializer = {
isChromium: boolean, isChromium: boolean,
fetchRequest: FetchRequestChannel, APIRequestContext: APIRequestContextChannel,
}; };
export interface BrowserContextChannel extends EventTargetChannel { export interface BrowserContextChannel extends EventTargetChannel {
on(event: 'bindingCall', callback: (params: BrowserContextBindingCallEvent) => void): this; on(event: 'bindingCall', callback: (params: BrowserContextBindingCallEvent) => void): this;

View file

@ -227,7 +227,7 @@ FormField:
mimeType: string mimeType: string
buffer: binary buffer: binary
FetchRequest: APIRequestContext:
type: interface type: interface
commands: commands:
@ -254,7 +254,7 @@ FetchRequest:
failOnStatusCode: boolean? failOnStatusCode: boolean?
ignoreHTTPSErrors: boolean? ignoreHTTPSErrors: boolean?
returns: returns:
response: FetchResponse? response: APIResponse?
error: string? error: string?
fetchResponseBody: fetchResponseBody:
@ -272,14 +272,14 @@ FetchRequest:
type: array type: array
items: OriginStorage items: OriginStorage
disposeFetchResponse: disposeAPIResponse:
parameters: parameters:
fetchUid: string fetchUid: string
dispose: dispose:
FetchResponse: APIResponse:
type: object type: object
properties: properties:
fetchUid: string fetchUid: string
@ -520,7 +520,7 @@ Playwright:
items: OriginStorage items: OriginStorage
returns: returns:
request: FetchRequest request: APIRequestContext
events: events:
socksRequested: socksRequested:
@ -684,7 +684,7 @@ BrowserContext:
initializer: initializer:
isChromium: boolean isChromium: boolean
fetchRequest: FetchRequest APIRequestContext: APIRequestContext
commands: commands:

View file

@ -157,7 +157,7 @@ export function createScheme(tChannel: (name: string) => Validator): Scheme {
buffer: tBinary, buffer: tBinary,
})), })),
}); });
scheme.FetchRequestFetchParams = tObject({ scheme.APIRequestContextFetchParams = tObject({
url: tString, url: tString,
params: tOptional(tArray(tType('NameValue'))), params: tOptional(tArray(tType('NameValue'))),
method: tOptional(tString), method: tOptional(tString),
@ -170,15 +170,15 @@ export function createScheme(tChannel: (name: string) => Validator): Scheme {
failOnStatusCode: tOptional(tBoolean), failOnStatusCode: tOptional(tBoolean),
ignoreHTTPSErrors: tOptional(tBoolean), ignoreHTTPSErrors: tOptional(tBoolean),
}); });
scheme.FetchRequestFetchResponseBodyParams = tObject({ scheme.APIRequestContextFetchResponseBodyParams = tObject({
fetchUid: tString, fetchUid: tString,
}); });
scheme.FetchRequestStorageStateParams = tOptional(tObject({})); scheme.APIRequestContextStorageStateParams = tOptional(tObject({}));
scheme.FetchRequestDisposeFetchResponseParams = tObject({ scheme.APIRequestContextDisposeAPIResponseParams = tObject({
fetchUid: tString, fetchUid: tString,
}); });
scheme.FetchRequestDisposeParams = tOptional(tObject({})); scheme.APIRequestContextDisposeParams = tOptional(tObject({}));
scheme.FetchResponse = tObject({ scheme.APIResponse = tObject({
fetchUid: tString, fetchUid: tString,
url: tString, url: tString,
status: tNumber, status: tNumber,

View file

@ -34,7 +34,7 @@ import { Tracing } from './trace/recorder/tracing';
import { HarRecorder } from './supplements/har/harRecorder'; import { HarRecorder } from './supplements/har/harRecorder';
import { RecorderSupplement } from './supplements/recorderSupplement'; import { RecorderSupplement } from './supplements/recorderSupplement';
import * as consoleApiSource from '../generated/consoleApiSource'; import * as consoleApiSource from '../generated/consoleApiSource';
import { BrowserContextFetchRequest } from './fetch'; import { BrowserContextAPIRequestContext } from './fetch';
export abstract class BrowserContext extends SdkObject { export abstract class BrowserContext extends SdkObject {
static Events = { static Events = {
@ -64,7 +64,7 @@ export abstract class BrowserContext extends SdkObject {
private _origins = new Set<string>(); private _origins = new Set<string>();
readonly _harRecorder: HarRecorder | undefined; readonly _harRecorder: HarRecorder | undefined;
readonly tracing: Tracing; readonly tracing: Tracing;
readonly fetchRequest: BrowserContextFetchRequest; readonly fetchRequest: BrowserContextAPIRequestContext;
constructor(browser: Browser, options: types.BrowserContextOptions, browserContextId: string | undefined) { constructor(browser: Browser, options: types.BrowserContextOptions, browserContextId: string | undefined) {
super(browser, 'browser-context'); super(browser, 'browser-context');
@ -82,7 +82,7 @@ export abstract class BrowserContext extends SdkObject {
this._harRecorder = new HarRecorder(this, { ...this._options.recordHar, path: path.join(this._browser.options.artifactsDir, `${createGuid()}.har`) }); this._harRecorder = new HarRecorder(this, { ...this._options.recordHar, path: path.join(this._browser.options.artifactsDir, `${createGuid()}.har`) });
this.tracing = new Tracing(this); this.tracing = new Tracing(this);
this.fetchRequest = new BrowserContextFetchRequest(this); this.fetchRequest = new BrowserContextAPIRequestContext(this);
} }
isPersistentContext(): boolean { isPersistentContext(): boolean {

View file

@ -44,16 +44,16 @@ type FetchRequestOptions = {
baseURL?: string; baseURL?: string;
}; };
export abstract class FetchRequest extends SdkObject { export abstract class APIRequestContext extends SdkObject {
static Events = { static Events = {
Dispose: 'dispose', Dispose: 'dispose',
}; };
readonly fetchResponses: Map<string, Buffer> = new Map(); readonly fetchResponses: Map<string, Buffer> = new Map();
protected static allInstances: Set<FetchRequest> = new Set(); protected static allInstances: Set<APIRequestContext> = new Set();
static findResponseBody(guid: string): Buffer | undefined { static findResponseBody(guid: string): Buffer | undefined {
for (const request of FetchRequest.allInstances) { for (const request of APIRequestContext.allInstances) {
const body = request.fetchResponses.get(guid); const body = request.fetchResponses.get(guid);
if (body) if (body)
return body; return body;
@ -63,13 +63,13 @@ export abstract class FetchRequest extends SdkObject {
constructor(parent: SdkObject) { constructor(parent: SdkObject) {
super(parent, 'fetchRequest'); super(parent, 'fetchRequest');
FetchRequest.allInstances.add(this); APIRequestContext.allInstances.add(this);
} }
protected _disposeImpl() { protected _disposeImpl() {
FetchRequest.allInstances.delete(this); APIRequestContext.allInstances.delete(this);
this.fetchResponses.clear(); this.fetchResponses.clear();
this.emit(FetchRequest.Events.Dispose); this.emit(APIRequestContext.Events.Dispose);
} }
abstract dispose(): void; abstract dispose(): void;
@ -77,7 +77,7 @@ export abstract class FetchRequest extends SdkObject {
abstract _defaultOptions(): FetchRequestOptions; abstract _defaultOptions(): FetchRequestOptions;
abstract _addCookies(cookies: types.NetworkCookie[]): Promise<void>; abstract _addCookies(cookies: types.NetworkCookie[]): Promise<void>;
abstract _cookies(url: URL): Promise<types.NetworkCookie[]>; abstract _cookies(url: URL): Promise<types.NetworkCookie[]>;
abstract storageState(): Promise<channels.FetchRequestStorageStateResult>; abstract storageState(): Promise<channels.APIRequestContextStorageStateResult>;
private _storeResponseBody(body: Buffer): string { private _storeResponseBody(body: Buffer): string {
const uid = createGuid(); const uid = createGuid();
@ -85,7 +85,7 @@ export abstract class FetchRequest extends SdkObject {
return uid; return uid;
} }
async fetch(params: channels.FetchRequestFetchParams): Promise<{fetchResponse?: Omit<types.FetchResponse, 'body'> & { fetchUid: string }, error?: string}> { async fetch(params: channels.APIRequestContextFetchParams): Promise<{fetchResponse?: Omit<types.APIResponse, 'body'> & { fetchUid: string }, error?: string}> {
try { try {
const headers: { [name: string]: string } = {}; const headers: { [name: string]: string } = {};
const defaults = this._defaultOptions(); const defaults = this._defaultOptions();
@ -195,9 +195,9 @@ export abstract class FetchRequest extends SdkObject {
} }
} }
private async _sendRequest(url: URL, options: https.RequestOptions & { maxRedirects: number, deadline: number }, postData?: Buffer): Promise<types.FetchResponse>{ private async _sendRequest(url: URL, options: https.RequestOptions & { maxRedirects: number, deadline: number }, postData?: Buffer): Promise<types.APIResponse>{
await this._updateRequestCookieHeader(url, options); await this._updateRequestCookieHeader(url, options);
return new Promise<types.FetchResponse>((fulfill, reject) => { return new Promise<types.APIResponse>((fulfill, reject) => {
const requestConstructor: ((url: URL, options: http.RequestOptions, callback?: (res: http.IncomingMessage) => void) => http.ClientRequest) const requestConstructor: ((url: URL, options: http.RequestOptions, callback?: (res: http.IncomingMessage) => void) => http.ClientRequest)
= (url.protocol === 'https:' ? https : http).request; = (url.protocol === 'https:' ? https : http).request;
const request = requestConstructor(url, options, async response => { const request = requestConstructor(url, options, async response => {
@ -305,8 +305,8 @@ export abstract class FetchRequest extends SdkObject {
reject(new Error('Request context disposed.')); reject(new Error('Request context disposed.'));
request.destroy(); request.destroy();
}; };
this.on(FetchRequest.Events.Dispose, disposeListener); this.on(APIRequestContext.Events.Dispose, disposeListener);
request.on('close', () => this.off(FetchRequest.Events.Dispose, disposeListener)); request.on('close', () => this.off(APIRequestContext.Events.Dispose, disposeListener));
if (debugLogger.isEnabled('api')) { if (debugLogger.isEnabled('api')) {
debugLogger.log('api', `${options.method} ${url.toString()}`); debugLogger.log('api', `${options.method} ${url.toString()}`);
@ -336,7 +336,7 @@ export abstract class FetchRequest extends SdkObject {
} }
} }
export class BrowserContextFetchRequest extends FetchRequest { export class BrowserContextAPIRequestContext extends APIRequestContext {
private readonly _context: BrowserContext; private readonly _context: BrowserContext;
constructor(context: BrowserContext) { constructor(context: BrowserContext) {
@ -369,13 +369,13 @@ export class BrowserContextFetchRequest extends FetchRequest {
return await this._context.cookies(url.toString()); return await this._context.cookies(url.toString());
} }
override async storageState(): Promise<channels.FetchRequestStorageStateResult> { override async storageState(): Promise<channels.APIRequestContextStorageStateResult> {
return this._context.storageState(); return this._context.storageState();
} }
} }
export class GlobalFetchRequest extends FetchRequest { export class GlobalAPIRequestContext extends APIRequestContext {
private readonly _cookieStore: CookieStore = new CookieStore(); private readonly _cookieStore: CookieStore = new CookieStore();
private readonly _options: FetchRequestOptions; private readonly _options: FetchRequestOptions;
private readonly _origins: channels.OriginStorage[] | undefined; private readonly _origins: channels.OriginStorage[] | undefined;
@ -424,7 +424,7 @@ export class GlobalFetchRequest extends FetchRequest {
return this._cookieStore.cookies(url); return this._cookieStore.cookies(url);
} }
override async storageState(): Promise<channels.FetchRequestStorageStateResult> { override async storageState(): Promise<channels.APIRequestContextStorageStateResult> {
return { return {
cookies: this._cookieStore.allCookies(), cookies: this._cookieStore.allCookies(),
origins: this._origins || [] origins: this._origins || []
@ -488,7 +488,7 @@ function parseCookie(header: string): types.NetworkCookie | null {
return cookie; return cookie;
} }
function serializePostData(params: channels.FetchRequestFetchParams, headers: { [name: string]: string }): Buffer | undefined { function serializePostData(params: channels.APIRequestContextFetchParams, headers: { [name: string]: string }): Buffer | undefined {
assert((params.postData ? 1 : 0) + (params.jsonData ? 1 : 0) + (params.formData ? 1 : 0) + (params.multipartData ? 1 : 0) <= 1, `Only one of 'data', 'form' or 'multipart' can be specified`); assert((params.postData ? 1 : 0) + (params.jsonData ? 1 : 0) + (params.formData ? 1 : 0) + (params.multipartData ? 1 : 0) <= 1, `Only one of 'data', 'form' or 'multipart' can be specified`);
if (params.jsonData) { if (params.jsonData) {
const json = JSON.stringify(params.jsonData); const json = JSON.stringify(params.jsonData);

View file

@ -20,7 +20,7 @@ import { assert } from '../utils/utils';
import { ManualPromise } from '../utils/async'; import { ManualPromise } from '../utils/async';
import { SdkObject } from './instrumentation'; import { SdkObject } from './instrumentation';
import { NameValue } from '../common/types'; import { NameValue } from '../common/types';
import { FetchRequest } from './fetch'; import { APIRequestContext } from './fetch';
export function filterCookies(cookies: types.NetworkCookie[], urls: string[]): types.NetworkCookie[] { export function filterCookies(cookies: types.NetworkCookie[], urls: string[]): types.NetworkCookie[] {
const parsedURLs = urls.map(s => new URL(s)); const parsedURLs = urls.map(s => new URL(s));
@ -251,7 +251,7 @@ export class Route extends SdkObject {
if (body === undefined) { if (body === undefined) {
if (overrides.fetchResponseUid) { if (overrides.fetchResponseUid) {
const context = this._request.frame()._page._browserContext; const context = this._request.frame()._page._browserContext;
const buffer = context.fetchRequest.fetchResponses.get(overrides.fetchResponseUid) || FetchRequest.findResponseBody(overrides.fetchResponseUid); const buffer = context.fetchRequest.fetchResponses.get(overrides.fetchResponseUid) || APIRequestContext.findResponseBody(overrides.fetchResponseUid);
assert(buffer, 'Fetch response has been disposed'); assert(buffer, 'Fetch response has been disposed');
body = buffer.toString('base64'); body = buffer.toString('base64');
isBase64 = true; isBase64 = true;

View file

@ -370,7 +370,7 @@ export type SetStorageState = {
origins?: OriginStorage[] origins?: OriginStorage[]
}; };
export type FetchResponse = { export type APIResponse = {
url: string, url: string,
status: number, status: number,
statusText: string, statusText: string,