chore(trace viewer): always format trace location as URL, not file path (#33344)

This commit is contained in:
Simon Knott 2024-11-04 16:25:44 +01:00 committed by GitHub
parent 4560686427
commit edf1eb154d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 48 additions and 22 deletions

View File

@ -106,8 +106,17 @@ export async function installRootRedirect(server: HttpServer, traceUrls: string[
const params = new URLSearchParams();
if (path.sep !== path.posix.sep)
params.set('pathSeparator', path.sep);
for (const traceUrl of traceUrls)
params.append('trace', traceUrl);
for (const traceUrl of traceUrls) {
if (traceUrl.startsWith('http://') || traceUrl.startsWith('https://')) {
params.append('trace', traceUrl);
continue;
}
// <testServerOrigin>/trace/file?path=/path/to/trace.zip
const url = new URL('/trace/file', server.urlPrefix('precise'));
url.searchParams.set('path', traceUrl);
params.append('trace', url.toString());
}
if (server.wsGuid())
params.append('ws', server.wsGuid()!);
if (options?.isServer)

View File

@ -30,9 +30,8 @@ export class ZipTraceModelBackend implements TraceModelBackend {
constructor(traceURL: string, progress: Progress) {
this._traceURL = traceURL;
zipjs.configure({ baseURL: self.location.href } as any);
this._zipReader = new zipjs.ZipReader(
new zipjs.HttpReader(formatUrl(traceURL), { mode: 'cors', preventHeadRequest: true } as any),
new zipjs.HttpReader(traceURL, { mode: 'cors', preventHeadRequest: true } as any),
{ useWebWorkers: false });
this._entriesPromise = this._zipReader.getEntries({ onprogress: progress }).then(entries => {
const map = new Map<string, zip.Entry>();
@ -87,8 +86,8 @@ export class FetchTraceModelBackend implements TraceModelBackend {
constructor(traceURL: string) {
this._traceURL = traceURL;
this._entriesPromise = fetch('/trace/file?path=' + encodeURIComponent(traceURL)).then(async response => {
const json = JSON.parse(await response.text());
this._entriesPromise = fetch(traceURL).then(async response => {
const json = await response.json();
const entries = new Map<string, string>();
for (const entry of json.entries)
entries.set(entry.name, entry.path);
@ -126,17 +125,12 @@ export class FetchTraceModelBackend implements TraceModelBackend {
private async _readEntry(entryName: string): Promise<Response | undefined> {
const entries = await this._entriesPromise;
const fileName = entries.get(entryName);
if (!fileName)
const filePath = entries.get(entryName);
if (!filePath)
return;
return fetch('/trace/file?path=' + encodeURIComponent(fileName));
const url = new URL(this.traceURL());
url.searchParams.set('path', filePath);
return fetch(url);
}
}
function formatUrl(trace: string) {
let url = trace.startsWith('http') || trace.startsWith('blob') ? trace : `file?path=${encodeURIComponent(trace)}`;
// Dropbox does not support cors.
if (url.startsWith('https://www.dropbox.com/'))
url = 'https://dl.dropboxusercontent.com/' + url.substring('https://www.dropbox.com/'.length);
return url;
}

View File

@ -21,6 +21,7 @@ import './embeddedWorkbenchLoader.css';
import { Workbench } from './workbench';
import { currentTheme, toggleTheme } from '@web/theme';
import type { SourceLocation } from './modelUtil';
import { filePathToTraceURL } from './uiModeTraceView';
function openPage(url: string, target?: string) {
if (url)
@ -40,7 +41,15 @@ export const EmbeddedWorkbenchLoader: React.FunctionComponent = () => {
React.useEffect(() => {
window.addEventListener('message', async ({ data: { method, params } }) => {
if (method === 'loadTraceRequested') {
setTraceURLs(params.traceUrl ? [params.traceUrl] : []);
if (params.traceUrl) {
// the param is called URL, but VS Code sends a path
const url = params.traceUrl.startsWith('http')
? params.traceUrl
: filePathToTraceURL(params.traceUrl).toString();
setTraceURLs([url]);
} else {
setTraceURLs([]);
}
setProcessingErrorMessage(null);
} else if (method === 'applyTheme') {
if (currentTheme() !== params.theme)

View File

@ -54,7 +54,7 @@ export const TraceView: React.FC<{
// Test finished.
const attachment = result && result.duration >= 0 && result.attachments.find(a => a.name === 'trace');
if (attachment && attachment.path) {
loadSingleTraceFile(attachment.path).then(model => setModel({ model, isLive: false }));
loadSingleTraceFile(filePathToTraceURL(attachment.path)).then(model => setModel({ model, isLive: false }));
return;
}
@ -72,7 +72,7 @@ export const TraceView: React.FC<{
// Start polling running test.
pollTimer.current = setTimeout(async () => {
try {
const model = await loadSingleTraceFile(traceLocation);
const model = await loadSingleTraceFile(filePathToTraceURL(traceLocation));
setModel({ model, isLive: true });
} catch {
setModel(undefined);
@ -108,11 +108,25 @@ const outputDirForTestCase = (testCase: reporterTypes.TestCase): string | undefi
return undefined;
};
async function loadSingleTraceFile(url: string): Promise<MultiTraceModel> {
async function loadSingleTraceFile(traceURL: URL): Promise<MultiTraceModel> {
const params = new URLSearchParams();
params.set('trace', url);
params.set('trace', formatUrl(traceURL).toString());
params.set('limit', '1');
const response = await fetch(`contexts?${params.toString()}`);
const contextEntries = await response.json() as ContextEntry[];
return new MultiTraceModel(contextEntries);
}
function formatUrl(traceURL: URL) {
// Dropbox does not support cors.
if (traceURL.hostname === 'dropbox.com')
traceURL.hostname = 'dl.dropboxusercontent.com';
return traceURL;
}
export function filePathToTraceURL(path: string) {
const url = new URL('file', location.href);
url.searchParams.set('path', path);
return url;
}