2021-08-05 13:36:47 -07:00
|
|
|
/**
|
|
|
|
* 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.
|
|
|
|
*/
|
|
|
|
|
2022-09-20 18:41:51 -07:00
|
|
|
import type { HTMLReport } from './types';
|
2021-12-13 15:37:01 -08:00
|
|
|
import type zip from '@zip.js/zip.js';
|
2022-03-28 17:21:19 -08:00
|
|
|
// @ts-ignore
|
2023-02-04 02:32:23 +08:00
|
|
|
import * as zipImport from '@zip.js/zip.js/lib/zip-no-worker-inflate.js';
|
2021-08-05 13:36:47 -07:00
|
|
|
import * as React from 'react';
|
|
|
|
import * as ReactDOM from 'react-dom';
|
2021-10-18 13:12:56 -08:00
|
|
|
import './colors.css';
|
2022-04-06 13:57:14 -08:00
|
|
|
import type { LoadedReport } from './loadedReport';
|
2021-12-13 15:37:01 -08:00
|
|
|
import { ReportView } from './reportView';
|
2023-02-07 10:21:26 -08:00
|
|
|
import { mergeReports } from './mergeReports';
|
2022-03-28 17:21:19 -08:00
|
|
|
// @ts-ignore
|
|
|
|
const zipjs = zipImport as typeof zip;
|
2021-12-13 15:37:01 -08:00
|
|
|
|
|
|
|
const ReportLoader: React.FC = () => {
|
|
|
|
const [report, setReport] = React.useState<LoadedReport | undefined>();
|
|
|
|
React.useEffect(() => {
|
|
|
|
if (report)
|
|
|
|
return;
|
2023-02-07 10:21:26 -08:00
|
|
|
const shardTotal = window.playwrightShardTotal;
|
2021-12-13 15:37:01 -08:00
|
|
|
const zipReport = new ZipReport();
|
2023-02-07 10:21:26 -08:00
|
|
|
const loadPromise = shardTotal ?
|
|
|
|
zipReport.loadFromShards(shardTotal) :
|
|
|
|
zipReport.loadFromBase64(window.playwrightReportBase64!);
|
|
|
|
loadPromise.then(() => setReport(zipReport));
|
2021-12-13 15:37:01 -08:00
|
|
|
}, [report]);
|
|
|
|
return <ReportView report={report}></ReportView>;
|
|
|
|
};
|
2021-08-05 13:36:47 -07:00
|
|
|
|
2021-11-01 15:14:52 -08:00
|
|
|
window.onload = () => {
|
2021-12-13 15:37:01 -08:00
|
|
|
ReactDOM.render(<ReportLoader />, document.querySelector('#root'));
|
2021-11-01 15:14:52 -08:00
|
|
|
};
|
2021-12-13 15:37:01 -08:00
|
|
|
|
|
|
|
class ZipReport implements LoadedReport {
|
|
|
|
private _entries = new Map<string, zip.Entry>();
|
2022-05-02 16:28:14 -07:00
|
|
|
private _json!: HTMLReport;
|
2023-02-07 14:22:10 -08:00
|
|
|
private _loaderError: string | undefined;
|
2021-12-13 15:37:01 -08:00
|
|
|
|
2023-02-07 10:21:26 -08:00
|
|
|
async loadFromBase64(reportBase64: string) {
|
|
|
|
const zipReader = new zipjs.ZipReader(new zipjs.Data64URIReader(reportBase64), { useWebWorkers: false }) as zip.ZipReader;
|
|
|
|
this._json = await this._readReportAndTestEntries(zipReader);
|
|
|
|
}
|
|
|
|
|
|
|
|
async loadFromShards(shardTotal: number) {
|
|
|
|
const readers = [];
|
|
|
|
const paddedLen = String(shardTotal).length;
|
|
|
|
for (let i = 0; i < shardTotal; i++) {
|
|
|
|
const paddedNumber = String(i + 1).padStart(paddedLen, '0');
|
|
|
|
const fileName = `report-${paddedNumber}-of-${shardTotal}.zip`;
|
|
|
|
const zipReader = new zipjs.ZipReader(new zipjs.HttpReader(fileName), { useWebWorkers: false }) as zip.ZipReader;
|
2023-02-07 14:22:10 -08:00
|
|
|
readers.push(this._readReportAndTestEntries(zipReader).catch(e => {
|
|
|
|
// eslint-disable-next-line no-console
|
|
|
|
console.warn(e);
|
|
|
|
return undefined;
|
|
|
|
}));
|
2023-02-07 10:21:26 -08:00
|
|
|
}
|
2023-02-07 14:22:10 -08:00
|
|
|
const reportsOrErrors = await Promise.all(readers);
|
|
|
|
const reports = reportsOrErrors.filter(Boolean) as HTMLReport[];
|
|
|
|
if (reports.length < readers.length)
|
|
|
|
this._loaderError = `Only ${reports.length} of ${shardTotal} report shards loaded`;
|
|
|
|
this._json = mergeReports(reports);
|
2023-02-07 10:21:26 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
private async _readReportAndTestEntries(zipReader: zip.ZipReader): Promise<HTMLReport> {
|
2021-12-13 15:37:01 -08:00
|
|
|
for (const entry of await zipReader.getEntries())
|
|
|
|
this._entries.set(entry.filename, entry);
|
2023-02-07 10:21:26 -08:00
|
|
|
return await this.entry('report.json') as HTMLReport;
|
2021-12-13 15:37:01 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
json(): HTMLReport {
|
|
|
|
return this._json;
|
|
|
|
}
|
|
|
|
|
|
|
|
async entry(name: string): Promise<Object> {
|
|
|
|
const reportEntry = this._entries.get(name);
|
|
|
|
const writer = new zipjs.TextWriter() as zip.TextWriter;
|
|
|
|
await reportEntry!.getData!(writer);
|
|
|
|
return JSON.parse(await writer.getData());
|
|
|
|
}
|
2023-02-07 14:22:10 -08:00
|
|
|
|
|
|
|
loaderError(): string | undefined {
|
|
|
|
return this._loaderError;
|
|
|
|
}
|
2021-12-13 15:37:01 -08:00
|
|
|
}
|
2023-02-07 10:21:26 -08:00
|
|
|
|