feat: add Response.fromServiceWorker flag (#14715)

Resolves #14666.

Relates #1090.
Supercedes #14321.
This commit is contained in:
Ross Wollman 2022-06-08 17:34:19 -04:00 committed by GitHub
parent beb276a2be
commit fccee89b41
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 44 additions and 5 deletions

View file

@ -22,6 +22,11 @@ Waits for this response to finish, returns always `null`.
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
- returns: <[Object]<[string], [string]>>

View file

@ -368,6 +368,10 @@ export class Response extends ChannelOwner<channels.ResponseChannel> implements
return this._initializer.statusText;
}
fromServiceWorker(): boolean {
return this._initializer.fromServiceWorker;
}
/**
* @deprecated
*/

View file

@ -3183,6 +3183,7 @@ export type ResponseInitializer = {
statusText: string,
headers: NameValue[],
timing: ResourceTiming,
fromServiceWorker: boolean,
};
export interface ResponseEventTarget {
}

View file

@ -2497,6 +2497,7 @@ Response:
type: array
items: NameValue
timing: ResourceTiming
fromServiceWorker: boolean
commands:

View file

@ -299,7 +299,7 @@ export class CRNetworkManager {
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') {
response._serverAddrFinished({
ipAddress: responsePayload.remoteIPAddress,

View file

@ -80,7 +80,8 @@ export class ResponseDispatcher extends Dispatcher<Response, channels.ResponseCh
status: response.status(),
statusText: response.statusText(),
headers: response.headers(),
timing: response.timing()
timing: response.timing(),
fromServiceWorker: response.fromServiceWorker(),
});
}

View file

@ -97,7 +97,7 @@ export class FFNetworkManager {
requestStart: relativeToStart(event.timing.requestStart),
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') {
response._serverAddrFinished({
ipAddress: event.remoteIPAddress,

View file

@ -360,8 +360,9 @@ export class Response extends SdkObject {
private _securityDetailsPromise = new ManualPromise<SecurityDetails | undefined>();
private _rawResponseHeadersPromise: ManualPromise<types.HeadersArray> | 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');
this._request = request;
this._timing = timing;
@ -374,6 +375,7 @@ export class Response extends SdkObject {
this._getResponseBodyCallback = getResponseBodyCallback;
this._request._setResponse(this);
this._httpVersion = httpVersion;
this._fromServiceWorker = fromServiceWorker;
}
_serverAddrFinished(addr?: RemoteAddr) {
@ -469,6 +471,10 @@ export class Response extends SdkObject {
return this._httpVersion;
}
fromServiceWorker(): boolean {
return this._fromServiceWorker;
}
private async _responseHeadersSize(): Promise<number> {
if (this._request.responseSize.responseHeadersSize)
return this._request.responseSize.responseHeadersSize;

View file

@ -88,7 +88,7 @@ export class WKInterceptableRequest {
responseStart: timingPayload ? wkMillisToRoundishMillis(timingPayload.responseStart) : -1,
};
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');
}
}

View file

@ -14611,6 +14611,12 @@ export interface Response {
*/
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
* [response.allHeaders()](https://playwright.dev/docs/api/class-response#response-all-headers) instead.

View file

@ -318,3 +318,18 @@ it('should return headers after route.fulfill', async ({ page, server }) => {
'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);
}
});