cherry-pick(#15046): fix(har): remove types/har.d.ts, update har.ts per spec (#15054)

Drive-by: typo fix in `notFound` option name.
This commit is contained in:
Dmitry Gozman 2022-06-22 14:38:34 -07:00 committed by GitHub
parent c840a28946
commit d3e80664e8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 41 additions and 195 deletions

View file

@ -1036,7 +1036,7 @@ Playwright will not serve requests intercepted by Service Worker from the HAR fi
Path to a [HAR](http://www.softwareishard.com/blog/har-12-spec) file with prerecorded network data. If `path` is a relative path, then it is resolved relative to the current working directory.
### option: BrowserContext.routeFromHAR.fallback
### option: BrowserContext.routeFromHAR.notFound
- `notFound` ?<[HarNotFound]<"abort"|"fallback">>
* If set to 'abort' any request not found in the HAR file will be aborted.

View file

@ -38,7 +38,6 @@
"./lib/server": "./lib/server/index.js",
"./lib/utilsBundle": "./lib/utilsBundle.js",
"./lib/zipBundle": "./lib/zipBundle.js",
"./types/har": "./types/har.d.ts",
"./types/protocol": "./types/protocol.d.ts",
"./types/structs": "./types/structs.d.ts"
},

View file

@ -24,7 +24,7 @@ import type { DispatcherScope } from './dispatcher';
import { Dispatcher } from './dispatcher';
import { yazl, yauzl } from '../../zipBundle';
import { ZipFile } from '../../utils/zipFile';
import type { HAREntry, HARFile, HARHeader } from '../../../types/har';
import type * as har from '../har/har';
import type { HeadersArray } from '../types';
export class LocalUtilsDispatcher extends Dispatcher<{ guid: string }, channels.LocalUtilsChannel> implements channels.LocalUtilsChannel {
@ -100,10 +100,10 @@ export class LocalUtilsDispatcher extends Dispatcher<{ guid: string }, channels.
if (!harEntryName)
return { error: 'Specified archive does not have a .har file' };
const har = await zipFile.read(harEntryName);
const harFile = JSON.parse(har.toString()) as HARFile;
const harFile = JSON.parse(har.toString()) as har.HARFile;
harBackend = new HarBackend(harFile, null, zipFile);
} else {
const harFile = JSON.parse(await fs.promises.readFile(params.file, 'utf-8')) as HARFile;
const harFile = JSON.parse(await fs.promises.readFile(params.file, 'utf-8')) as har.HARFile;
harBackend = new HarBackend(harFile, path.dirname(params.file), null);
}
this._harBakends.set(harBackend.id, harBackend);
@ -130,11 +130,11 @@ const redirectStatus = [301, 302, 303, 307, 308];
class HarBackend {
readonly id = createGuid();
private _harFile: HARFile;
private _harFile: har.HARFile;
private _zipFile: ZipFile | null;
private _baseDir: string | null;
constructor(harFile: HARFile, baseDir: string | null, zipFile: ZipFile | null) {
constructor(harFile: har.HARFile, baseDir: string | null, zipFile: ZipFile | null) {
this._harFile = harFile;
this._baseDir = baseDir;
this._zipFile = zipFile;
@ -190,11 +190,11 @@ class HarBackend {
return buffer;
}
private async _harFindResponse(url: string, method: string, headers: HeadersArray, postData: Buffer | undefined): Promise<HAREntry | undefined> {
private async _harFindResponse(url: string, method: string, headers: HeadersArray, postData: Buffer | undefined): Promise<har.Entry | undefined> {
const harLog = this._harFile.log;
const visited = new Set<HAREntry>();
const visited = new Set<har.Entry>();
while (true) {
const entries: HAREntry[] = [];
const entries: har.Entry[] = [];
for (const candidate of harLog.entries) {
if (candidate.request.url !== url || candidate.request.method !== method)
continue;
@ -213,7 +213,7 @@ class HarBackend {
// Disambiguate using headers - then one with most matching headers wins.
if (entries.length > 1) {
const list: { candidate: HAREntry, matchingHeaders: number }[] = [];
const list: { candidate: har.Entry, matchingHeaders: number }[] = [];
for (const candidate of entries) {
const matchingHeaders = countMatchingHeaders(candidate.request.headers, headers);
list.push({ candidate, matchingHeaders });
@ -249,7 +249,7 @@ class HarBackend {
}
}
function countMatchingHeaders(harHeaders: HARHeader[], headers: HeadersArray): number {
function countMatchingHeaders(harHeaders: har.Header[], headers: HeadersArray): number {
const set = new Set(headers.map(h => h.name.toLowerCase() + ':' + h.value));
let matches = 0;
for (const h of harHeaders) {

View file

@ -22,19 +22,22 @@ export type HARFile = {
export type Log = {
version: string;
creator: Creator;
browser: Browser;
pages: Page[];
browser?: Browser;
pages?: Page[];
entries: Entry[];
comment?: string;
};
export type Creator = {
name: string;
version: string;
comment?: string;
};
export type Browser = {
name: string;
version: string;
comment?: string;
};
export type Page = {
@ -42,11 +45,13 @@ export type Page = {
id: string;
title: string;
pageTimings: PageTimings;
comment?: string;
};
export type PageTimings = {
onContentLoad: number;
onLoad: number;
onContentLoad?: number;
onLoad?: number;
comment?: string;
};
export type Entry = {
@ -76,6 +81,7 @@ export type Request = {
postData?: PostData;
headersSize: number;
bodySize: number;
comment?: string;
};
export type Response = {
@ -88,6 +94,7 @@ export type Response = {
redirectURL: string;
headersSize: number;
bodySize: number;
comment?: string;
_transferSize: number;
_failureText?: string
};
@ -101,22 +108,26 @@ export type Cookie = {
httpOnly?: boolean;
secure?: boolean;
sameSite?: string;
comment?: string;
};
export type Header = {
name: string;
value: string;
comment?: string;
};
export type QueryParameter = {
name: string;
value: string;
comment?: string;
};
export type PostData = {
mimeType: string;
params: Param[];
text: string;
comment?: string;
_sha1?: string;
};
@ -125,6 +136,7 @@ export type Param = {
value?: string;
fileName?: string;
contentType?: string;
comment?: string;
};
export type Content = {
@ -133,12 +145,14 @@ export type Content = {
mimeType: string;
text?: string;
encoding?: string;
comment?: string;
_sha1?: string;
};
export type Cache = {
beforeRequest: CacheState | null;
afterRequest: CacheState | null;
beforeRequest?: CacheState | null;
afterRequest?: CacheState | null;
comment?: string;
};
export type CacheState = {
@ -146,6 +160,7 @@ export type CacheState = {
lastAccess: string;
eTag: string;
hitCount: number;
comment?: string;
};
export type Timings = {
@ -156,6 +171,7 @@ export type Timings = {
wait: number;
receive: number;
ssl?: number;
comment?: string;
};
export type SecurityDetails = {

View file

@ -407,13 +407,13 @@ export class HarTracer {
pages: Array.from(this._pageEntries.values()),
entries: [],
};
for (const pageEntry of log.pages) {
if (pageEntry.pageTimings.onContentLoad >= 0)
pageEntry.pageTimings.onContentLoad -= pageEntry.startedDateTime.valueOf();
for (const pageEntry of log.pages!) {
if (pageEntry.pageTimings.onContentLoad! >= 0)
pageEntry.pageTimings.onContentLoad! -= pageEntry.startedDateTime.valueOf();
else
pageEntry.pageTimings.onContentLoad = -1;
if (pageEntry.pageTimings.onLoad >= 0)
pageEntry.pageTimings.onLoad -= pageEntry.startedDateTime.valueOf();
if (pageEntry.pageTimings.onLoad! >= 0)
pageEntry.pageTimings.onLoad! -= pageEntry.startedDateTime.valueOf();
else
pageEntry.pageTimings.onLoad = -1;
}

View file

@ -1,167 +0,0 @@
/**
* 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.
*/
// see http://www.softwareishard.com/blog/har-12-spec/
export type HARFile = {
log: HARLog;
}
export type HARLog = {
version: string;
creator: HARCreator;
browser?: HARBrowser;
pages?: HARPage[];
entries: HAREntry[];
comment?: string;
};
export type HARCreator = {
name: string;
version: string;
comment?: string;
};
export type HARBrowser = {
name: string;
version: string;
comment?: string;
};
export type HARPage = {
startedDateTime: string;
id: string;
title: string;
pageTimings: HARPageTimings;
comment?: string;
};
export type HARPageTimings = {
onContentLoad?: number;
onLoad?: number;
comment?: string;
};
export type HAREntry = {
pageref?: string;
startedDateTime: string;
time: number;
request: HARRequest;
response: HARResponse;
cache: HARCache;
timings: HARTimings;
serverIPAddress?: string;
connection?: string;
comment?: string;
};
export type HARRequest = {
method: string;
url: string;
httpVersion: string;
cookies: HARCookie[];
headers: HARHeader[];
queryString: HARQueryParameter[];
postData?: HARPostData;
headersSize: number;
bodySize: number;
comment?: string;
};
export type HARResponse = {
status: number;
statusText: string;
httpVersion: string;
cookies: HARCookie[];
headers: HARHeader[];
content: HARContent;
redirectURL: string;
headersSize: number;
bodySize: number;
comment?: string;
};
export type HARCookie = {
name: string;
value: string;
path?: string;
domain?: string;
expires?: string;
httpOnly?: boolean;
secure?: boolean;
sameSite?: string;
comment?: string;
};
export type HARHeader = {
name: string;
value: string;
comment?: string;
};
export type HARQueryParameter = {
name: string;
value: string;
comment?: string;
};
export type HARPostData = {
mimeType: string;
params: HARParam[];
text: string;
comment?: string;
};
export type HARParam = {
name: string;
value?: string;
fileName?: string;
contentType?: string;
comment?: string;
};
export type HARContent = {
size: number;
compression?: number;
mimeType: string;
text?: string;
encoding?: string;
comment?: string;
};
export type HARCache = {
beforeRequest?: HARCacheState;
afterRequest?: HARCacheState;
comment?: string;
};
export type HARCacheState = {
expires?: string;
lastAccess: string;
eTag: string;
hitCount: number;
comment?: string;
};
export type HARTimings = {
blocked?: number;
dns?: number;
connect?: number;
send: number;
wait: number;
receive: number;
ssl?: number;
comment?: string;
};

View file

@ -17,7 +17,6 @@
import { Protocol } from 'playwright-core/types/protocol';
import { ChildProcess } from 'child_process';
import { EventEmitter } from 'events';
import { HARResponse } from 'playwright-core/types/har';
import { Readable } from 'stream';
import { ReadStream } from 'fs';
import { Serializable, EvaluationArgument, PageFunction, PageFunctionOn, SmartHandle, ElementHandleForTag, BindingSource } from 'playwright-core/types/structs';

View file

@ -17,7 +17,7 @@
import { test as base, expect } from './pageTest';
import fs from 'fs';
import type { HARFile, HARResponse } from 'playwright-core/types/har';
import type * as har from 'playwright-core/lib/server/har/har';
const it = base.extend<{
// We access test servers at 10.0.2.2 from inside the browser on Android,
@ -327,7 +327,7 @@ it('should fulfill with har response', async ({ page, isAndroid, asset }) => {
it.fixme(isAndroid);
const harPath = asset('har-fulfill.har');
const har = JSON.parse(await fs.promises.readFile(harPath, 'utf-8')) as HARFile;
const har = JSON.parse(await fs.promises.readFile(harPath, 'utf-8')) as har.HARFile;
await page.route('**/*', async route => {
const response = findResponse(har, route.request().url());
const headers = {};
@ -346,7 +346,7 @@ it('should fulfill with har response', async ({ page, isAndroid, asset }) => {
await expect(page.locator('body')).toHaveCSS('background-color', 'rgb(0, 255, 255)');
});
function findResponse(har: HARFile, url: string): HARResponse {
function findResponse(har: har.HARFile, url: string): har.Response {
let entry;
const originalUrl = url;
while (url.trim()) {

View file

@ -16,7 +16,6 @@
import { Protocol } from 'playwright-core/types/protocol';
import { ChildProcess } from 'child_process';
import { EventEmitter } from 'events';
import { HARResponse } from 'playwright-core/types/har';
import { Readable } from 'stream';
import { ReadStream } from 'fs';
import { Serializable, EvaluationArgument, PageFunction, PageFunctionOn, SmartHandle, ElementHandleForTag, BindingSource } from 'playwright-core/types/structs';