fix(size): fix some of the request.size() problems (#8645)
This commit is contained in:
parent
0ae38b5aec
commit
54bda2c8dd
|
|
@ -188,7 +188,7 @@ following: `document`, `stylesheet`, `image`, `media`, `font`, `script`, `texttr
|
||||||
|
|
||||||
Returns the matching [Response] object, or `null` if the response was not received due to error.
|
Returns the matching [Response] object, or `null` if the response was not received due to error.
|
||||||
|
|
||||||
## method: Request.sizes
|
## async method: Request.sizes
|
||||||
- returns: <[Object]>
|
- returns: <[Object]>
|
||||||
- `requestBodySize` <[int]> Size of the request body (POST data payload) in bytes. Set to 0 if there was no body.
|
- `requestBodySize` <[int]> Size of the request body (POST data payload) in bytes. Set to 0 if there was no body.
|
||||||
- `requestHeadersSize` <[int]> Total number of bytes from the start of the HTTP request message until (and including) the double CRLF before the body.
|
- `requestHeadersSize` <[int]> Total number of bytes from the start of the HTTP request message until (and including) the double CRLF before the body.
|
||||||
|
|
|
||||||
|
|
@ -125,13 +125,12 @@ export class BrowserContext extends ChannelOwner<channels.BrowserContextChannel,
|
||||||
}
|
}
|
||||||
|
|
||||||
private _onRequestFinished(params: channels.BrowserContextRequestFinishedEvent) {
|
private _onRequestFinished(params: channels.BrowserContextRequestFinishedEvent) {
|
||||||
const { requestSizes, responseEndTiming } = params;
|
const { responseEndTiming } = params;
|
||||||
const request = network.Request.from(params.request);
|
const request = network.Request.from(params.request);
|
||||||
const response = network.Response.fromNullable(params.response);
|
const response = network.Response.fromNullable(params.response);
|
||||||
const page = Page.fromNullable(params.page);
|
const page = Page.fromNullable(params.page);
|
||||||
if (request._timing)
|
if (request._timing)
|
||||||
request._timing.responseEnd = responseEndTiming;
|
request._timing.responseEnd = responseEndTiming;
|
||||||
request._sizes = requestSizes;
|
|
||||||
this.emit(Events.BrowserContext.RequestFinished, request);
|
this.emit(Events.BrowserContext.RequestFinished, request);
|
||||||
if (page)
|
if (page)
|
||||||
page.emit(Events.Page.RequestFinished, request);
|
page.emit(Events.Page.RequestFinished, request);
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,6 @@ export class Request extends ChannelOwner<channels.RequestChannel, channels.Requ
|
||||||
private _rawHeadersPromise: Promise<RawHeaders> | undefined;
|
private _rawHeadersPromise: Promise<RawHeaders> | undefined;
|
||||||
private _postData: Buffer | null;
|
private _postData: Buffer | null;
|
||||||
_timing: ResourceTiming;
|
_timing: ResourceTiming;
|
||||||
_sizes: RequestSizes = { requestBodySize: 0, requestHeadersSize: 0, responseBodySize: 0, responseHeadersSize: 0, responseTransferSize: 0 };
|
|
||||||
|
|
||||||
static from(request: channels.RequestChannel): Request {
|
static from(request: channels.RequestChannel): Request {
|
||||||
return (request as any)._object;
|
return (request as any)._object;
|
||||||
|
|
@ -187,8 +186,13 @@ export class Request extends ChannelOwner<channels.RequestChannel, channels.Requ
|
||||||
return this._timing;
|
return this._timing;
|
||||||
}
|
}
|
||||||
|
|
||||||
sizes(): RequestSizes {
|
async sizes(): Promise<RequestSizes> {
|
||||||
return this._sizes;
|
const response = await this.response();
|
||||||
|
if (!response)
|
||||||
|
throw new Error('Unable to fetch sizes for failed request');
|
||||||
|
return response._wrapApiCall(async (channel: channels.ResponseChannel) => {
|
||||||
|
return (await channel.sizes()).sizes;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
_finalRequest(): Request {
|
_finalRequest(): Request {
|
||||||
|
|
|
||||||
|
|
@ -87,7 +87,6 @@ export class BrowserContextDispatcher extends Dispatcher<BrowserContext, channel
|
||||||
request: RequestDispatcher.from(scope, request),
|
request: RequestDispatcher.from(scope, request),
|
||||||
response: ResponseDispatcher.fromNullable(scope, response),
|
response: ResponseDispatcher.fromNullable(scope, response),
|
||||||
responseEndTiming: request._responseEndTiming,
|
responseEndTiming: request._responseEndTiming,
|
||||||
requestSizes: request.sizes(),
|
|
||||||
page: PageDispatcher.fromNullable(this._scope, request.frame()._page.initializedOrUndefined()),
|
page: PageDispatcher.fromNullable(this._scope, request.frame()._page.initializedOrUndefined()),
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -91,6 +91,10 @@ export class ResponseDispatcher extends Dispatcher<Response, channels.ResponseIn
|
||||||
async rawResponseHeaders(params?: channels.ResponseRawResponseHeadersParams, metadata?: channels.Metadata): Promise<channels.ResponseRawResponseHeadersResult> {
|
async rawResponseHeaders(params?: channels.ResponseRawResponseHeadersParams, metadata?: channels.Metadata): Promise<channels.ResponseRawResponseHeadersResult> {
|
||||||
return { headers: await this._object.rawResponseHeaders() };
|
return { headers: await this._object.rawResponseHeaders() };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async sizes(params?: channels.ResponseSizesParams, metadata?: channels.Metadata): Promise<channels.ResponseSizesResult> {
|
||||||
|
return { sizes: await this._object.sizes() };
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class RouteDispatcher extends Dispatcher<Route, channels.RouteInitializer, channels.RouteEvents> implements channels.RouteChannel {
|
export class RouteDispatcher extends Dispatcher<Route, channels.RouteInitializer, channels.RouteEvents> implements channels.RouteChannel {
|
||||||
|
|
|
||||||
|
|
@ -802,7 +802,6 @@ export type BrowserContextRequestFinishedEvent = {
|
||||||
request: RequestChannel,
|
request: RequestChannel,
|
||||||
response?: ResponseChannel,
|
response?: ResponseChannel,
|
||||||
responseEndTiming: number,
|
responseEndTiming: number,
|
||||||
requestSizes: RequestSizes,
|
|
||||||
page?: PageChannel,
|
page?: PageChannel,
|
||||||
};
|
};
|
||||||
export type BrowserContextResponseEvent = {
|
export type BrowserContextResponseEvent = {
|
||||||
|
|
@ -2698,6 +2697,7 @@ export interface ResponseChannel extends Channel {
|
||||||
serverAddr(params?: ResponseServerAddrParams, metadata?: Metadata): Promise<ResponseServerAddrResult>;
|
serverAddr(params?: ResponseServerAddrParams, metadata?: Metadata): Promise<ResponseServerAddrResult>;
|
||||||
rawRequestHeaders(params?: ResponseRawRequestHeadersParams, metadata?: Metadata): Promise<ResponseRawRequestHeadersResult>;
|
rawRequestHeaders(params?: ResponseRawRequestHeadersParams, metadata?: Metadata): Promise<ResponseRawRequestHeadersResult>;
|
||||||
rawResponseHeaders(params?: ResponseRawResponseHeadersParams, metadata?: Metadata): Promise<ResponseRawResponseHeadersResult>;
|
rawResponseHeaders(params?: ResponseRawResponseHeadersParams, metadata?: Metadata): Promise<ResponseRawResponseHeadersResult>;
|
||||||
|
sizes(params?: ResponseSizesParams, metadata?: Metadata): Promise<ResponseSizesResult>;
|
||||||
}
|
}
|
||||||
export type ResponseBodyParams = {};
|
export type ResponseBodyParams = {};
|
||||||
export type ResponseBodyOptions = {};
|
export type ResponseBodyOptions = {};
|
||||||
|
|
@ -2724,6 +2724,11 @@ export type ResponseRawResponseHeadersOptions = {};
|
||||||
export type ResponseRawResponseHeadersResult = {
|
export type ResponseRawResponseHeadersResult = {
|
||||||
headers: NameValue[],
|
headers: NameValue[],
|
||||||
};
|
};
|
||||||
|
export type ResponseSizesParams = {};
|
||||||
|
export type ResponseSizesOptions = {};
|
||||||
|
export type ResponseSizesResult = {
|
||||||
|
sizes: RequestSizes,
|
||||||
|
};
|
||||||
|
|
||||||
export interface ResponseEvents {
|
export interface ResponseEvents {
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -766,7 +766,6 @@ BrowserContext:
|
||||||
request: Request
|
request: Request
|
||||||
response: Response?
|
response: Response?
|
||||||
responseEndTiming: number
|
responseEndTiming: number
|
||||||
requestSizes: RequestSizes
|
|
||||||
page: Page?
|
page: Page?
|
||||||
|
|
||||||
response:
|
response:
|
||||||
|
|
@ -2226,6 +2225,10 @@ Response:
|
||||||
type: array
|
type: array
|
||||||
items: NameValue
|
items: NameValue
|
||||||
|
|
||||||
|
sizes:
|
||||||
|
returns:
|
||||||
|
sizes: RequestSizes
|
||||||
|
|
||||||
|
|
||||||
SecurityDetails:
|
SecurityDetails:
|
||||||
type: object
|
type: object
|
||||||
|
|
|
||||||
|
|
@ -1055,6 +1055,7 @@ export function createScheme(tChannel: (name: string) => Validator): Scheme {
|
||||||
scheme.ResponseServerAddrParams = tOptional(tObject({}));
|
scheme.ResponseServerAddrParams = tOptional(tObject({}));
|
||||||
scheme.ResponseRawRequestHeadersParams = tOptional(tObject({}));
|
scheme.ResponseRawRequestHeadersParams = tOptional(tObject({}));
|
||||||
scheme.ResponseRawResponseHeadersParams = tOptional(tObject({}));
|
scheme.ResponseRawResponseHeadersParams = tOptional(tObject({}));
|
||||||
|
scheme.ResponseSizesParams = tOptional(tObject({}));
|
||||||
scheme.SecurityDetails = tObject({
|
scheme.SecurityDetails = tObject({
|
||||||
issuer: tOptional(tString),
|
issuer: tOptional(tString),
|
||||||
protocol: tOptional(tString),
|
protocol: tOptional(tString),
|
||||||
|
|
|
||||||
|
|
@ -51,6 +51,7 @@ export class CRNetworkManager {
|
||||||
return [
|
return [
|
||||||
eventsHelper.addEventListener(session, 'Fetch.requestPaused', this._onRequestPaused.bind(this, workerFrame)),
|
eventsHelper.addEventListener(session, 'Fetch.requestPaused', this._onRequestPaused.bind(this, workerFrame)),
|
||||||
eventsHelper.addEventListener(session, 'Fetch.authRequired', this._onAuthRequired.bind(this)),
|
eventsHelper.addEventListener(session, 'Fetch.authRequired', this._onAuthRequired.bind(this)),
|
||||||
|
eventsHelper.addEventListener(session, 'Network.dataReceived', this._onDataReceived.bind(this)),
|
||||||
eventsHelper.addEventListener(session, 'Network.requestWillBeSent', this._onRequestWillBeSent.bind(this, workerFrame)),
|
eventsHelper.addEventListener(session, 'Network.requestWillBeSent', this._onRequestWillBeSent.bind(this, workerFrame)),
|
||||||
eventsHelper.addEventListener(session, 'Network.requestWillBeSentExtraInfo', this._onRequestWillBeSentExtraInfo.bind(this)),
|
eventsHelper.addEventListener(session, 'Network.requestWillBeSentExtraInfo', this._onRequestWillBeSentExtraInfo.bind(this)),
|
||||||
eventsHelper.addEventListener(session, 'Network.responseReceived', this._onResponseReceived.bind(this)),
|
eventsHelper.addEventListener(session, 'Network.responseReceived', this._onResponseReceived.bind(this)),
|
||||||
|
|
@ -350,6 +351,12 @@ export class CRNetworkManager {
|
||||||
this._page._frameManager.requestReceivedResponse(response);
|
this._page._frameManager.requestReceivedResponse(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_onDataReceived(event: Protocol.Network.dataReceivedPayload) {
|
||||||
|
const request = this._requestIdToRequest.get(event.requestId);
|
||||||
|
if (request)
|
||||||
|
request.request.responseSize.bodySize += event.dataLength;
|
||||||
|
}
|
||||||
|
|
||||||
_onLoadingFinished(event: Protocol.Network.loadingFinishedPayload) {
|
_onLoadingFinished(event: Protocol.Network.loadingFinishedPayload) {
|
||||||
this._responseExtraInfoTracker.loadingFinished(event);
|
this._responseExtraInfoTracker.loadingFinished(event);
|
||||||
|
|
||||||
|
|
@ -365,8 +372,7 @@ export class CRNetworkManager {
|
||||||
// event from protocol. @see https://crbug.com/883475
|
// event from protocol. @see https://crbug.com/883475
|
||||||
const response = request.request._existingResponse();
|
const response = request.request._existingResponse();
|
||||||
if (response) {
|
if (response) {
|
||||||
request.request._sizes.transferSize = event.encodedDataLength;
|
request.request.responseSize.transferSize = event.encodedDataLength;
|
||||||
request.request._sizes.responseBodySize = event.encodedDataLength - response?.headersSize();
|
|
||||||
response._requestFinished(helper.secondsToRoundishMillis(event.timestamp - request._timestamp));
|
response._requestFinished(helper.secondsToRoundishMillis(event.timestamp - request._timestamp));
|
||||||
}
|
}
|
||||||
this._requestIdToRequest.delete(request._requestId);
|
this._requestIdToRequest.delete(request._requestId);
|
||||||
|
|
|
||||||
|
|
@ -116,9 +116,7 @@ export class FFNetworkManager {
|
||||||
if (!request)
|
if (!request)
|
||||||
return;
|
return;
|
||||||
const response = request.request._existingResponse()!;
|
const response = request.request._existingResponse()!;
|
||||||
|
request.request.responseSize.transferSize = event.transferSize;
|
||||||
request.request._sizes.transferSize = event.transferSize;
|
|
||||||
request.request._sizes.responseBodySize = event.transferSize - response.headersSize();
|
|
||||||
|
|
||||||
// Keep redirected requests in the map for future reference as redirectedFrom.
|
// Keep redirected requests in the map for future reference as redirectedFrom.
|
||||||
const isRedirected = response.status() >= 300 && response.status() <= 399;
|
const isRedirected = response.status() >= 300 && response.status() <= 399;
|
||||||
|
|
|
||||||
|
|
@ -80,8 +80,9 @@ export function stripFragmentFromUrl(url: string): string {
|
||||||
return url.substring(0, url.indexOf('#'));
|
return url.substring(0, url.indexOf('#'));
|
||||||
}
|
}
|
||||||
|
|
||||||
type RequestSizes = {
|
type ResponseSize = {
|
||||||
responseBodySize: number;
|
bodySize: number;
|
||||||
|
encodedBodySize: number;
|
||||||
transferSize: number;
|
transferSize: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -101,7 +102,7 @@ export class Request extends SdkObject {
|
||||||
private _frame: frames.Frame;
|
private _frame: frames.Frame;
|
||||||
private _waitForResponsePromise = new ManualPromise<Response | null>();
|
private _waitForResponsePromise = new ManualPromise<Response | null>();
|
||||||
_responseEndTiming = -1;
|
_responseEndTiming = -1;
|
||||||
_sizes: RequestSizes = { responseBodySize: 0, transferSize: 0 };
|
readonly responseSize: ResponseSize = { bodySize: 0, encodedBodySize: 0, transferSize: 0 };
|
||||||
|
|
||||||
constructor(frame: frames.Frame, redirectedFrom: Request | null, documentId: string | undefined,
|
constructor(frame: frames.Frame, redirectedFrom: Request | null, documentId: string | undefined,
|
||||||
url: string, resourceType: string, method: string, postData: Buffer | null, headers: types.HeadersArray) {
|
url: string, resourceType: string, method: string, postData: Buffer | null, headers: types.HeadersArray) {
|
||||||
|
|
@ -195,28 +196,6 @@ export class Request extends SdkObject {
|
||||||
bodySize(): number {
|
bodySize(): number {
|
||||||
return this.postDataBuffer()?.length || 0;
|
return this.postDataBuffer()?.length || 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
headersSize(): number {
|
|
||||||
if (!this._response)
|
|
||||||
return 0;
|
|
||||||
let headersSize = 4; // 4 = 2 spaces + 2 line breaks (GET /path \r\n)
|
|
||||||
headersSize += this.method().length;
|
|
||||||
headersSize += (new URL(this.url())).pathname.length;
|
|
||||||
headersSize += 8; // httpVersion
|
|
||||||
for (const header of this._headers)
|
|
||||||
headersSize += header.name.length + header.value.length + 4; // 4 = ': ' + '\r\n'
|
|
||||||
return headersSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
sizes() {
|
|
||||||
return {
|
|
||||||
requestBodySize: this.bodySize(),
|
|
||||||
requestHeadersSize: this.headersSize(),
|
|
||||||
responseBodySize: this._sizes.responseBodySize,
|
|
||||||
responseHeadersSize: this._existingResponse()!.headersSize(),
|
|
||||||
responseTransferSize: this._sizes.transferSize,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Route extends SdkObject {
|
export class Route extends SdkObject {
|
||||||
|
|
@ -297,6 +276,14 @@ export type ResourceTiming = {
|
||||||
responseStart: number;
|
responseStart: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type ResourceSizes = {
|
||||||
|
requestBodySize: number,
|
||||||
|
requestHeadersSize: number,
|
||||||
|
responseBodySize: number,
|
||||||
|
responseHeadersSize: number,
|
||||||
|
responseTransferSize: number,
|
||||||
|
};
|
||||||
|
|
||||||
export type RemoteAddr = {
|
export type RemoteAddr = {
|
||||||
ipAddress: string;
|
ipAddress: string;
|
||||||
port: number;
|
port: number;
|
||||||
|
|
@ -435,14 +422,6 @@ export class Response extends SdkObject {
|
||||||
return this._request.frame();
|
return this._request.frame();
|
||||||
}
|
}
|
||||||
|
|
||||||
transferSize(): number | undefined {
|
|
||||||
return this._request._sizes.transferSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
bodySize(): number {
|
|
||||||
return this._request._sizes.responseBodySize;
|
|
||||||
}
|
|
||||||
|
|
||||||
httpVersion(): string {
|
httpVersion(): string {
|
||||||
if (!this._httpVersion)
|
if (!this._httpVersion)
|
||||||
return 'HTTP/1.1';
|
return 'HTTP/1.1';
|
||||||
|
|
@ -451,16 +430,52 @@ export class Response extends SdkObject {
|
||||||
return this._httpVersion;
|
return this._httpVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
headersSize(): number {
|
private async _requestHeadersSize(): Promise<number> {
|
||||||
|
let headersSize = 4; // 4 = 2 spaces + 2 line breaks (GET /path \r\n)
|
||||||
|
headersSize += this._request.method().length;
|
||||||
|
headersSize += (new URL(this.url())).pathname.length;
|
||||||
|
headersSize += 8; // httpVersion
|
||||||
|
const headers = this._rawRequestHeadersPromise ? await this._rawRequestHeadersPromise : this._request._headers;
|
||||||
|
for (const header of headers)
|
||||||
|
headersSize += header.name.length + header.value.length + 4; // 4 = ': ' + '\r\n'
|
||||||
|
return headersSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async _responseHeadersSize(): Promise<number> {
|
||||||
let headersSize = 4; // 4 = 2 spaces + 2 line breaks (HTTP/1.1 200 Ok\r\n)
|
let headersSize = 4; // 4 = 2 spaces + 2 line breaks (HTTP/1.1 200 Ok\r\n)
|
||||||
headersSize += 8; // httpVersion;
|
headersSize += 8; // httpVersion;
|
||||||
headersSize += 3; // statusCode;
|
headersSize += 3; // statusCode;
|
||||||
headersSize += this.statusText().length;
|
headersSize += this.statusText().length;
|
||||||
for (const header of this.headers())
|
const headers = this._rawResponseHeadersPromise ? await this._rawResponseHeadersPromise : this._headers;
|
||||||
|
for (const header of headers)
|
||||||
headersSize += header.name.length + header.value.length + 4; // 4 = ': ' + '\r\n'
|
headersSize += header.name.length + header.value.length + 4; // 4 = ': ' + '\r\n'
|
||||||
headersSize += 2; // '\r\n'
|
headersSize += 2; // '\r\n'
|
||||||
return headersSize;
|
return headersSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async sizes(): Promise<ResourceSizes> {
|
||||||
|
await this._finishedPromise;
|
||||||
|
const requestHeadersSize = await this._requestHeadersSize();
|
||||||
|
const responseHeadersSize = await this._responseHeadersSize();
|
||||||
|
let { bodySize, encodedBodySize, transferSize } = this._request.responseSize;
|
||||||
|
if (!encodedBodySize && transferSize) {
|
||||||
|
// Chromium only populates transferSize
|
||||||
|
encodedBodySize = transferSize - responseHeadersSize;
|
||||||
|
// Firefox only populate transferSize.
|
||||||
|
if (!bodySize)
|
||||||
|
bodySize = encodedBodySize;
|
||||||
|
} else if (!transferSize) {
|
||||||
|
// WebKit does not provide transfer size.
|
||||||
|
transferSize = encodedBodySize + responseHeadersSize;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
requestBodySize: this._request.bodySize(),
|
||||||
|
requestHeadersSize,
|
||||||
|
responseBodySize: bodySize,
|
||||||
|
responseHeadersSize,
|
||||||
|
responseTransferSize: transferSize,
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class InterceptedResponse extends SdkObject {
|
export class InterceptedResponse extends SdkObject {
|
||||||
|
|
|
||||||
|
|
@ -202,19 +202,11 @@ export class HarTracer {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const httpVersion = response.httpVersion();
|
const httpVersion = response.httpVersion();
|
||||||
const transferSize = response.transferSize() || -1;
|
|
||||||
const responseHeadersSize = response.headersSize();
|
|
||||||
|
|
||||||
harEntry.request.httpVersion = httpVersion;
|
harEntry.request.httpVersion = httpVersion;
|
||||||
harEntry.response.bodySize = response.bodySize();
|
|
||||||
harEntry.response.headersSize = responseHeadersSize;
|
|
||||||
harEntry.response._transferSize = transferSize;
|
|
||||||
harEntry.request.headersSize = request.headersSize();
|
|
||||||
|
|
||||||
const promise = response.body().then(buffer => {
|
const promise = response.body().then(buffer => {
|
||||||
const content = harEntry.response.content;
|
const content = harEntry.response.content;
|
||||||
content.size = buffer.length;
|
content.size = buffer.length;
|
||||||
content.compression = harEntry.response.bodySize !== -1 ? buffer.length - harEntry.response.bodySize : 0;
|
|
||||||
if (buffer && buffer.length > 0) {
|
if (buffer && buffer.length > 0) {
|
||||||
if (this._options.content === 'embedded') {
|
if (this._options.content === 'embedded') {
|
||||||
content.text = buffer.toString('base64');
|
content.text = buffer.toString('base64');
|
||||||
|
|
@ -236,6 +228,14 @@ export class HarTracer {
|
||||||
this._delegate.onEntryFinished(harEntry);
|
this._delegate.onEntryFinished(harEntry);
|
||||||
});
|
});
|
||||||
this._addBarrier(page, promise);
|
this._addBarrier(page, promise);
|
||||||
|
this._addBarrier(page, response.sizes().then(async sizes => {
|
||||||
|
harEntry.response.bodySize = sizes.responseBodySize;
|
||||||
|
harEntry.response.headersSize = sizes.responseHeadersSize;
|
||||||
|
harEntry.response._transferSize = sizes.responseTransferSize;
|
||||||
|
harEntry.request.headersSize = sizes.requestHeadersSize;
|
||||||
|
const content = harEntry.response.content;
|
||||||
|
content.compression = Math.max(0, sizes.responseBodySize - sizes.responseTransferSize - sizes.responseHeadersSize);
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
private _onResponse(response: network.Response) {
|
private _onResponse(response: network.Response) {
|
||||||
|
|
|
||||||
|
|
@ -1053,7 +1053,6 @@ export class WKPage implements PageDelegate {
|
||||||
validFrom: responseReceivedPayload?.response.security?.certificate?.validFrom,
|
validFrom: responseReceivedPayload?.response.security?.certificate?.validFrom,
|
||||||
validTo: responseReceivedPayload?.response.security?.certificate?.validUntil,
|
validTo: responseReceivedPayload?.response.security?.certificate?.validUntil,
|
||||||
});
|
});
|
||||||
request.request._sizes.transferSize += response.headersSize();
|
|
||||||
if (event.metrics?.protocol)
|
if (event.metrics?.protocol)
|
||||||
response._setHttpVersion(event.metrics.protocol);
|
response._setHttpVersion(event.metrics.protocol);
|
||||||
response._requestFinished(helper.secondsToRoundishMillis(event.timestamp - request._timestamp));
|
response._requestFinished(helper.secondsToRoundishMillis(event.timestamp - request._timestamp));
|
||||||
|
|
@ -1088,8 +1087,8 @@ export class WKPage implements PageDelegate {
|
||||||
const request = this._requestIdToRequest.get(event.requestId);
|
const request = this._requestIdToRequest.get(event.requestId);
|
||||||
if (!request)
|
if (!request)
|
||||||
return;
|
return;
|
||||||
request.request._sizes.responseBodySize += event.encodedDataLength === -1 ? event.dataLength : event.encodedDataLength;
|
request.request.responseSize.bodySize += event.dataLength || (event.encodedDataLength === -1 ? 0 : event.encodedDataLength);
|
||||||
request.request._sizes.transferSize += event.encodedDataLength === -1 ? event.dataLength : event.encodedDataLength;
|
request.request.responseSize.encodedBodySize += event.encodedDataLength !== -1 ? event.encodedDataLength : event.dataLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
async _grantPermissions(origin: string, permissions: string[]) {
|
async _grantPermissions(origin: string, permissions: string[]) {
|
||||||
|
|
|
||||||
340
tests/assets/simplezip.json
Normal file
340
tests/assets/simplezip.json
Normal file
|
|
@ -0,0 +1,340 @@
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
{"foo": "bar"}
|
||||||
|
|
@ -276,18 +276,18 @@ it('should include sizes', async ({ contextFactory, server, asset }, testInfo) =
|
||||||
expect(log.entries[1].request.url.endsWith('one-style.css')).toBe(true);
|
expect(log.entries[1].request.url.endsWith('one-style.css')).toBe(true);
|
||||||
expect(log.entries[1].response.bodySize).toBe(fs.statSync(asset('one-style.css')).size);
|
expect(log.entries[1].response.bodySize).toBe(fs.statSync(asset('one-style.css')).size);
|
||||||
expect(log.entries[1].response.headersSize).toBeGreaterThanOrEqual(100);
|
expect(log.entries[1].response.headersSize).toBeGreaterThanOrEqual(100);
|
||||||
expect(log.entries[1].response._transferSize).toBeGreaterThanOrEqual(200);
|
expect(log.entries[1].response._transferSize).toBeGreaterThanOrEqual(150);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should work with gzip compression', async ({ contextFactory, server, browserName }, testInfo) => {
|
it('should work with gzip compression', async ({ contextFactory, server, browserName }, testInfo) => {
|
||||||
it.fixme(browserName === 'webkit');
|
it.fixme(browserName !== 'chromium');
|
||||||
const { page, getLog } = await pageWithHar(contextFactory, testInfo);
|
const { page, getLog } = await pageWithHar(contextFactory, testInfo);
|
||||||
server.enableGzip('/simple.json');
|
server.enableGzip('/simplezip.json');
|
||||||
const response = await page.goto(server.PREFIX + '/simple.json');
|
const response = await page.goto(server.PREFIX + '/simplezip.json');
|
||||||
expect(response.headers()['content-encoding']).toBe('gzip');
|
expect(response.headers()['content-encoding']).toBe('gzip');
|
||||||
const log = await getLog();
|
const log = await getLog();
|
||||||
expect(log.entries.length).toBe(1);
|
expect(log.entries.length).toBe(1);
|
||||||
expect(log.entries[0].response.content.compression).toBe(-20);
|
expect(log.entries[0].response.content.compression).toBeGreaterThan(4000);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should calculate time', async ({ contextFactory, server }, testInfo) => {
|
it('should calculate time', async ({ contextFactory, server }, testInfo) => {
|
||||||
|
|
|
||||||
|
|
@ -273,55 +273,6 @@ it('should return navigation bit when navigating to image', async ({page, server
|
||||||
expect(requests[0].isNavigationRequest()).toBe(true);
|
expect(requests[0].isNavigationRequest()).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should set bodySize and headersSize', async ({page, server,browserName, platform}) => {
|
|
||||||
await page.goto(server.EMPTY_PAGE);
|
|
||||||
const [request] = await Promise.all([
|
|
||||||
page.waitForEvent('request'),
|
|
||||||
page.evaluate(() => fetch('./get', { method: 'POST', body: '12345'}).then(r => r.text())),
|
|
||||||
]);
|
|
||||||
await (await request.response()).finished();
|
|
||||||
expect(request.sizes().requestBodySize).toBe(5);
|
|
||||||
expect(request.sizes().requestHeadersSize).toBeGreaterThanOrEqual(250);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should should set bodySize to 0 if there was no body', async ({page, server,browserName, platform}) => {
|
|
||||||
await page.goto(server.EMPTY_PAGE);
|
|
||||||
const [request] = await Promise.all([
|
|
||||||
page.waitForEvent('request'),
|
|
||||||
page.evaluate(() => fetch('./get').then(r => r.text())),
|
|
||||||
]);
|
|
||||||
await (await request.response()).finished();
|
|
||||||
expect(request.sizes().requestBodySize).toBe(0);
|
|
||||||
expect(request.sizes().requestHeadersSize).toBeGreaterThanOrEqual(200);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should should set bodySize, headersSize, and transferSize', async ({page, server, browserName, platform}) => {
|
|
||||||
server.setRoute('/get', (req, res) => {
|
|
||||||
// In Firefox, |fetch| will be hanging until it receives |Content-Type| header
|
|
||||||
// from server.
|
|
||||||
res.setHeader('Content-Type', 'text/plain; charset=utf-8');
|
|
||||||
res.end('abc134');
|
|
||||||
});
|
|
||||||
await page.goto(server.EMPTY_PAGE);
|
|
||||||
const [response] = await Promise.all([
|
|
||||||
page.waitForEvent('response'),
|
|
||||||
page.evaluate(async () => fetch('./get').then(r => r.text())),
|
|
||||||
server.waitForRequest('/get'),
|
|
||||||
]);
|
|
||||||
await response.finished();
|
|
||||||
expect(response.request().sizes().responseBodySize).toBe(6);
|
|
||||||
expect(response.request().sizes().responseHeadersSize).toBeGreaterThanOrEqual(150);
|
|
||||||
expect(response.request().sizes().responseTransferSize).toBeGreaterThanOrEqual(160);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should should set bodySize to 0 when there was no response body', async ({page, server, browserName, platform}) => {
|
|
||||||
const response = await page.goto(server.EMPTY_PAGE);
|
|
||||||
await response.finished();
|
|
||||||
expect(response.request().sizes().responseBodySize).toBe(0);
|
|
||||||
expect(response.request().sizes().responseHeadersSize).toBeGreaterThanOrEqual(150);
|
|
||||||
expect(response.request().sizes().responseTransferSize).toBeGreaterThanOrEqual(160);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should report raw headers', async ({ page, server, browserName }) => {
|
it('should report raw headers', async ({ page, server, browserName }) => {
|
||||||
const response = await page.goto(server.EMPTY_PAGE);
|
const response = await page.goto(server.EMPTY_PAGE);
|
||||||
const requestHeaders = await response.request().rawHeaders();
|
const requestHeaders = await response.request().rawHeaders();
|
||||||
|
|
|
||||||
68
tests/page/page-network-sizes.spec.ts
Normal file
68
tests/page/page-network-sizes.spec.ts
Normal file
|
|
@ -0,0 +1,68 @@
|
||||||
|
/**
|
||||||
|
* Copyright 2018 Google Inc. All rights reserved.
|
||||||
|
* Modifications copyright (c) Microsoft Corporation.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { test as it, expect } from './pageTest';
|
||||||
|
|
||||||
|
it('should set bodySize and headersSize', async ({page, server,browserName, platform}) => {
|
||||||
|
await page.goto(server.EMPTY_PAGE);
|
||||||
|
const [request] = await Promise.all([
|
||||||
|
page.waitForEvent('request'),
|
||||||
|
page.evaluate(() => fetch('./get', { method: 'POST', body: '12345'}).then(r => r.text())),
|
||||||
|
]);
|
||||||
|
await (await request.response()).finished();
|
||||||
|
const sizes = await request.sizes();
|
||||||
|
expect(sizes.requestBodySize).toBe(5);
|
||||||
|
expect(sizes.requestHeadersSize).toBeGreaterThanOrEqual(250);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should set bodySize to 0 if there was no body', async ({page, server,browserName, platform}) => {
|
||||||
|
await page.goto(server.EMPTY_PAGE);
|
||||||
|
const [request] = await Promise.all([
|
||||||
|
page.waitForEvent('request'),
|
||||||
|
page.evaluate(() => fetch('./get').then(r => r.text())),
|
||||||
|
]);
|
||||||
|
const sizes = await request.sizes();
|
||||||
|
expect(sizes.requestBodySize).toBe(0);
|
||||||
|
expect(sizes.requestHeadersSize).toBeGreaterThanOrEqual(200);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should set bodySize, headersSize, and transferSize', async ({page, server, browserName, platform}) => {
|
||||||
|
server.setRoute('/get', (req, res) => {
|
||||||
|
// In Firefox, |fetch| will be hanging until it receives |Content-Type| header
|
||||||
|
// from server.
|
||||||
|
res.setHeader('Content-Type', 'text/plain; charset=utf-8');
|
||||||
|
res.end('abc134');
|
||||||
|
});
|
||||||
|
await page.goto(server.EMPTY_PAGE);
|
||||||
|
const [response] = await Promise.all([
|
||||||
|
page.waitForEvent('response'),
|
||||||
|
page.evaluate(async () => fetch('./get').then(r => r.text())),
|
||||||
|
server.waitForRequest('/get'),
|
||||||
|
]);
|
||||||
|
const sizes = await response.request().sizes();
|
||||||
|
expect(sizes.responseBodySize).toBe(6);
|
||||||
|
expect(sizes.responseHeadersSize).toBeGreaterThanOrEqual(150);
|
||||||
|
expect(sizes.responseTransferSize).toBeGreaterThanOrEqual(160);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should set bodySize to 0 when there was no response body', async ({page, server, browserName, platform}) => {
|
||||||
|
const response = await page.goto(server.EMPTY_PAGE);
|
||||||
|
const sizes = await response.request().sizes();
|
||||||
|
expect(sizes.responseBodySize).toBe(0);
|
||||||
|
expect(sizes.responseHeadersSize).toBeGreaterThanOrEqual(150);
|
||||||
|
expect(sizes.responseTransferSize).toBeGreaterThanOrEqual(160);
|
||||||
|
});
|
||||||
4
types/types.d.ts
vendored
4
types/types.d.ts
vendored
|
|
@ -13133,7 +13133,7 @@ export interface Request {
|
||||||
* Returns resource size information for given request. Requires the response to be finished via
|
* Returns resource size information for given request. Requires the response to be finished via
|
||||||
* [response.finished()](https://playwright.dev/docs/api/class-response#response-finished) to ensure the info is available.
|
* [response.finished()](https://playwright.dev/docs/api/class-response#response-finished) to ensure the info is available.
|
||||||
*/
|
*/
|
||||||
sizes(): {
|
sizes(): Promise<{
|
||||||
/**
|
/**
|
||||||
* Size of the request body (POST data payload) in bytes. Set to 0 if there was no body.
|
* Size of the request body (POST data payload) in bytes. Set to 0 if there was no body.
|
||||||
*/
|
*/
|
||||||
|
|
@ -13158,7 +13158,7 @@ export interface Request {
|
||||||
* Total number of bytes received for the request.
|
* Total number of bytes received for the request.
|
||||||
*/
|
*/
|
||||||
responseTransferSize: number;
|
responseTransferSize: number;
|
||||||
};
|
}>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns resource timing information for given request. Most of the timing values become available upon the response,
|
* Returns resource timing information for given request. Most of the timing values become available upon the response,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue