From 1e95b6d906964e7eddd7212a000c355874f140e2 Mon Sep 17 00:00:00 2001 From: Pavel Feldman Date: Thu, 25 May 2023 15:38:47 -0700 Subject: [PATCH] chore: allow sending trace URLs over stdin (#23288) --- packages/playwright-core/src/cli/program.ts | 3 +- .../src/server/trace/viewer/traceViewer.ts | 29 ++++++++++++++++++- .../trace-viewer/src/ui/workbenchLoader.tsx | 3 ++ 3 files changed, 33 insertions(+), 2 deletions(-) diff --git a/packages/playwright-core/src/cli/program.ts b/packages/playwright-core/src/cli/program.ts index 3726810c72..fb55f8d4d9 100644 --- a/packages/playwright-core/src/cli/program.ts +++ b/packages/playwright-core/src/cli/program.ts @@ -275,6 +275,7 @@ program .option('-b, --browser ', 'browser to use, one of cr, chromium, ff, firefox, wk, webkit', 'chromium') .option('-h, --host ', 'Host to serve trace on', 'localhost') .option('-p, --port ', 'Port to serve trace on', '9322') + .option('--stdin', 'Accept trace URLs over stdin to update the viewer') .description('show trace viewer') .action(function(traces, options) { if (options.browser === 'cr') @@ -284,7 +285,7 @@ program if (options.browser === 'wk') options.browser = 'webkit'; - showTraceViewer(traces, options.browser, { headless: false, host: options.host, port: +options.port }).catch(logErrorAndExit); + showTraceViewer(traces, options.browser, { headless: false, host: options.host, port: +options.port, isServer: !!options.stdin }).catch(logErrorAndExit); }).addHelpText('afterAll', ` Examples: diff --git a/packages/playwright-core/src/server/trace/viewer/traceViewer.ts b/packages/playwright-core/src/server/trace/viewer/traceViewer.ts index bd3b6b9e79..4a02157cfd 100644 --- a/packages/playwright-core/src/server/trace/viewer/traceViewer.ts +++ b/packages/playwright-core/src/server/trace/viewer/traceViewer.ts @@ -25,7 +25,7 @@ import { createPlaywright } from '../../playwright'; import { ProgressController } from '../../progress'; import type { Page } from '../../page'; -type Options = { app?: string, headless?: boolean, host?: string, port?: number }; +type Options = { app?: string, headless?: boolean, host?: string, port?: number, isServer?: boolean }; export async function showTraceViewer(traceUrls: string[], browserName: string, options?: Options): Promise { const { headless = false, host, port, app } = options || {}; @@ -115,9 +115,36 @@ export async function showTraceViewer(traceUrls: string[], browserName: string, const searchQuery = params.length ? '?' + params.join('&') : ''; await page.mainFrame().goto(serverSideCallMetadata(), urlPrefix + `/trace/${app || 'index.html'}${searchQuery}`); + + if (options?.isServer) + runServer(page); + return page; } +function runServer(page: Page) { + let liveTraceTimer: NodeJS.Timeout | undefined; + const loadTrace = (url: string) => { + clearTimeout(liveTraceTimer); + page.mainFrame().evaluateExpression(`window.setTraceURL(${JSON.stringify(url)})`, false, undefined).catch(() => {}); + }; + + const pollLoadTrace = (url: string) => { + loadTrace(url); + liveTraceTimer = setTimeout(() => { + pollLoadTrace(url); + }, 500); + }; + + process.stdin.on('data', data => { + const url = data.toString().trim(); + if (url.endsWith('.json')) + pollLoadTrace(url); + else + loadTrace(url); + }); +} + function traceDescriptor(traceName: string) { const result: { entries: { name: string, path: string }[] } = { entries: [] diff --git a/packages/trace-viewer/src/ui/workbenchLoader.tsx b/packages/trace-viewer/src/ui/workbenchLoader.tsx index 36d6fb1a87..4917201a90 100644 --- a/packages/trace-viewer/src/ui/workbenchLoader.tsx +++ b/packages/trace-viewer/src/ui/workbenchLoader.tsx @@ -78,6 +78,9 @@ export const WorkbenchLoader: React.FunctionComponent<{ } } + (window as any).setTraceURL = (url: string) => { + setTraceURLs([url]); + }; // Don't re-use blob file URLs on page load (results in Fetch error) if (!newTraceURLs.some(url => url.startsWith('blob:'))) setTraceURLs(newTraceURLs);