feat: add Response.fromServiceWorker flag (#14715)
Resolves #14666. Relates #1090. Supercedes #14321.
This commit is contained in:
parent
beb276a2be
commit
fccee89b41
|
|
@ -22,6 +22,11 @@ Waits for this response to finish, returns always `null`.
|
||||||
|
|
||||||
Returns the [Frame] that initiated this response.
|
Returns the [Frame] that initiated this response.
|
||||||
|
|
||||||
|
## method: Response.fromServiceWorker
|
||||||
|
- returns: <[boolean]>
|
||||||
|
|
||||||
|
Indicates whether this Response was fullfilled by a Service Worker's Fetch Handler (i.e. via [FetchEvent.respondWith](https://developer.mozilla.org/en-US/docs/Web/API/FetchEvent/respondWith)).
|
||||||
|
|
||||||
## method: Response.headers
|
## method: Response.headers
|
||||||
- returns: <[Object]<[string], [string]>>
|
- returns: <[Object]<[string], [string]>>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -368,6 +368,10 @@ export class Response extends ChannelOwner<channels.ResponseChannel> implements
|
||||||
return this._initializer.statusText;
|
return this._initializer.statusText;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fromServiceWorker(): boolean {
|
||||||
|
return this._initializer.fromServiceWorker;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated
|
* @deprecated
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -3183,6 +3183,7 @@ export type ResponseInitializer = {
|
||||||
statusText: string,
|
statusText: string,
|
||||||
headers: NameValue[],
|
headers: NameValue[],
|
||||||
timing: ResourceTiming,
|
timing: ResourceTiming,
|
||||||
|
fromServiceWorker: boolean,
|
||||||
};
|
};
|
||||||
export interface ResponseEventTarget {
|
export interface ResponseEventTarget {
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2497,6 +2497,7 @@ Response:
|
||||||
type: array
|
type: array
|
||||||
items: NameValue
|
items: NameValue
|
||||||
timing: ResourceTiming
|
timing: ResourceTiming
|
||||||
|
fromServiceWorker: boolean
|
||||||
|
|
||||||
|
|
||||||
commands:
|
commands:
|
||||||
|
|
|
||||||
|
|
@ -299,7 +299,7 @@ export class CRNetworkManager {
|
||||||
responseStart: -1,
|
responseStart: -1,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
const response = new network.Response(request.request, responsePayload.status, responsePayload.statusText, headersObjectToArray(responsePayload.headers), timing, getResponseBody, responsePayload.protocol);
|
const response = new network.Response(request.request, responsePayload.status, responsePayload.statusText, headersObjectToArray(responsePayload.headers), timing, getResponseBody, !!responsePayload.fromServiceWorker, responsePayload.protocol);
|
||||||
if (responsePayload?.remoteIPAddress && typeof responsePayload?.remotePort === 'number') {
|
if (responsePayload?.remoteIPAddress && typeof responsePayload?.remotePort === 'number') {
|
||||||
response._serverAddrFinished({
|
response._serverAddrFinished({
|
||||||
ipAddress: responsePayload.remoteIPAddress,
|
ipAddress: responsePayload.remoteIPAddress,
|
||||||
|
|
|
||||||
|
|
@ -80,7 +80,8 @@ export class ResponseDispatcher extends Dispatcher<Response, channels.ResponseCh
|
||||||
status: response.status(),
|
status: response.status(),
|
||||||
statusText: response.statusText(),
|
statusText: response.statusText(),
|
||||||
headers: response.headers(),
|
headers: response.headers(),
|
||||||
timing: response.timing()
|
timing: response.timing(),
|
||||||
|
fromServiceWorker: response.fromServiceWorker(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -97,7 +97,7 @@ export class FFNetworkManager {
|
||||||
requestStart: relativeToStart(event.timing.requestStart),
|
requestStart: relativeToStart(event.timing.requestStart),
|
||||||
responseStart: relativeToStart(event.timing.responseStart),
|
responseStart: relativeToStart(event.timing.responseStart),
|
||||||
};
|
};
|
||||||
const response = new network.Response(request.request, event.status, event.statusText, parseMultivalueHeaders(event.headers), timing, getResponseBody);
|
const response = new network.Response(request.request, event.status, event.statusText, parseMultivalueHeaders(event.headers), timing, getResponseBody, event.fromServiceWorker);
|
||||||
if (event?.remoteIPAddress && typeof event?.remotePort === 'number') {
|
if (event?.remoteIPAddress && typeof event?.remotePort === 'number') {
|
||||||
response._serverAddrFinished({
|
response._serverAddrFinished({
|
||||||
ipAddress: event.remoteIPAddress,
|
ipAddress: event.remoteIPAddress,
|
||||||
|
|
|
||||||
|
|
@ -360,8 +360,9 @@ export class Response extends SdkObject {
|
||||||
private _securityDetailsPromise = new ManualPromise<SecurityDetails | undefined>();
|
private _securityDetailsPromise = new ManualPromise<SecurityDetails | undefined>();
|
||||||
private _rawResponseHeadersPromise: ManualPromise<types.HeadersArray> | undefined;
|
private _rawResponseHeadersPromise: ManualPromise<types.HeadersArray> | undefined;
|
||||||
private _httpVersion: string | undefined;
|
private _httpVersion: string | undefined;
|
||||||
|
private _fromServiceWorker: boolean;
|
||||||
|
|
||||||
constructor(request: Request, status: number, statusText: string, headers: types.HeadersArray, timing: ResourceTiming, getResponseBodyCallback: GetResponseBodyCallback, httpVersion?: string) {
|
constructor(request: Request, status: number, statusText: string, headers: types.HeadersArray, timing: ResourceTiming, getResponseBodyCallback: GetResponseBodyCallback, fromServiceWorker: boolean, httpVersion?: string) {
|
||||||
super(request.frame(), 'response');
|
super(request.frame(), 'response');
|
||||||
this._request = request;
|
this._request = request;
|
||||||
this._timing = timing;
|
this._timing = timing;
|
||||||
|
|
@ -374,6 +375,7 @@ export class Response extends SdkObject {
|
||||||
this._getResponseBodyCallback = getResponseBodyCallback;
|
this._getResponseBodyCallback = getResponseBodyCallback;
|
||||||
this._request._setResponse(this);
|
this._request._setResponse(this);
|
||||||
this._httpVersion = httpVersion;
|
this._httpVersion = httpVersion;
|
||||||
|
this._fromServiceWorker = fromServiceWorker;
|
||||||
}
|
}
|
||||||
|
|
||||||
_serverAddrFinished(addr?: RemoteAddr) {
|
_serverAddrFinished(addr?: RemoteAddr) {
|
||||||
|
|
@ -469,6 +471,10 @@ export class Response extends SdkObject {
|
||||||
return this._httpVersion;
|
return this._httpVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fromServiceWorker(): boolean {
|
||||||
|
return this._fromServiceWorker;
|
||||||
|
}
|
||||||
|
|
||||||
private async _responseHeadersSize(): Promise<number> {
|
private async _responseHeadersSize(): Promise<number> {
|
||||||
if (this._request.responseSize.responseHeadersSize)
|
if (this._request.responseSize.responseHeadersSize)
|
||||||
return this._request.responseSize.responseHeadersSize;
|
return this._request.responseSize.responseHeadersSize;
|
||||||
|
|
|
||||||
|
|
@ -88,7 +88,7 @@ export class WKInterceptableRequest {
|
||||||
responseStart: timingPayload ? wkMillisToRoundishMillis(timingPayload.responseStart) : -1,
|
responseStart: timingPayload ? wkMillisToRoundishMillis(timingPayload.responseStart) : -1,
|
||||||
};
|
};
|
||||||
const setCookieSeparator = process.platform === 'darwin' ? ',' : '\n';
|
const setCookieSeparator = process.platform === 'darwin' ? ',' : '\n';
|
||||||
return new network.Response(this.request, responsePayload.status, responsePayload.statusText, headersObjectToArray(responsePayload.headers, ',', setCookieSeparator), timing, getResponseBody);
|
return new network.Response(this.request, responsePayload.status, responsePayload.statusText, headersObjectToArray(responsePayload.headers, ',', setCookieSeparator), timing, getResponseBody, responsePayload.source === 'service-worker');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
6
packages/playwright-core/types/types.d.ts
vendored
6
packages/playwright-core/types/types.d.ts
vendored
|
|
@ -14611,6 +14611,12 @@ export interface Response {
|
||||||
*/
|
*/
|
||||||
frame(): Frame;
|
frame(): Frame;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates whether this Response was fullfilled by a Service Worker's Fetch Handler (i.e. via
|
||||||
|
* [FetchEvent.respondWith](https://developer.mozilla.org/en-US/docs/Web/API/FetchEvent/respondWith)).
|
||||||
|
*/
|
||||||
|
fromServiceWorker(): boolean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* **DEPRECATED** Incomplete list of headers as seen by the rendering engine. Use
|
* **DEPRECATED** Incomplete list of headers as seen by the rendering engine. Use
|
||||||
* [response.allHeaders()](https://playwright.dev/docs/api/class-response#response-all-headers) instead.
|
* [response.allHeaders()](https://playwright.dev/docs/api/class-response#response-all-headers) instead.
|
||||||
|
|
|
||||||
|
|
@ -318,3 +318,18 @@ it('should return headers after route.fulfill', async ({ page, server }) => {
|
||||||
'content-language': 'en'
|
'content-language': 'en'
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should report if request was fromServiceWorker', async ({ page, server }) => {
|
||||||
|
{
|
||||||
|
const res = await page.goto(server.PREFIX + '/serviceworkers/fetch/sw.html');
|
||||||
|
expect(res.fromServiceWorker()).toBe(false);
|
||||||
|
}
|
||||||
|
await page.evaluate(() => window['activationPromise']);
|
||||||
|
{
|
||||||
|
const [res] = await Promise.all([
|
||||||
|
page.waitForResponse(/example\.txt/),
|
||||||
|
page.evaluate(() => fetch('/example.txt')),
|
||||||
|
]);
|
||||||
|
expect(res.fromServiceWorker()).toBe(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue