diff --git a/packages/playwright-core/src/server/trace/viewer/traceViewer.ts b/packages/playwright-core/src/server/trace/viewer/traceViewer.ts index 0e83a15f387f7..39ea55ee0f026 100644 --- a/packages/playwright-core/src/server/trace/viewer/traceViewer.ts +++ b/packages/playwright-core/src/server/trace/viewer/traceViewer.ts @@ -55,7 +55,7 @@ export type TraceViewerAppOptions = { const tracesDirMarker = 'traces.dir'; -function validateTraceUrl(traceFileOrUrl: string | undefined): string | undefined { +function validateTraceUrlOrPath(traceFileOrUrl: string | undefined): string | undefined { if (!traceFileOrUrl) return traceFileOrUrl; @@ -152,7 +152,7 @@ export async function installRootRedirect(server: HttpServer, traceUrl: string | } export async function runTraceViewerApp(traceUrl: string | undefined, browserName: string, options: TraceViewerServerOptions & { headless?: boolean }, exitOnClose?: boolean) { - traceUrl = validateTraceUrl(traceUrl); + traceUrl = validateTraceUrlOrPath(traceUrl); const server = await startTraceViewerServer(options); await installRootRedirect(server, traceUrl, options); const page = await openTraceViewerApp(server.urlPrefix('precise'), browserName, options); @@ -162,7 +162,7 @@ export async function runTraceViewerApp(traceUrl: string | undefined, browserNam } export async function runTraceInBrowser(traceUrl: string | undefined, options: TraceViewerServerOptions) { - traceUrl = validateTraceUrl(traceUrl); + traceUrl = validateTraceUrlOrPath(traceUrl); const server = await startTraceViewerServer(options); await installRootRedirect(server, traceUrl, options); await openTraceInBrowser(server.urlPrefix('human-readable')); @@ -216,8 +216,8 @@ class StdinServer implements Transport { constructor() { process.stdin.on('data', data => { - const url = data.toString().trim(); - if (url === this._traceUrl) + const url = validateTraceUrlOrPath(data.toString().trim()); + if (!url || url === this._traceUrl) return; if (url.endsWith('.json')) this._pollLoadTrace(url); diff --git a/packages/playwright-core/src/server/utils/httpServer.ts b/packages/playwright-core/src/server/utils/httpServer.ts index 92a46aac1762f..cb08f27eb2e36 100644 --- a/packages/playwright-core/src/server/utils/httpServer.ts +++ b/packages/playwright-core/src/server/utils/httpServer.ts @@ -115,7 +115,7 @@ export class HttpServer { this._port = address.port; const resolvedHost = address.family === 'IPv4' ? address.address : `[${address.address}]`; this._urlPrefixPrecise = `http://${resolvedHost}:${address.port}`; - this._urlPrefixHumanReadable = `http://${host}:${address.port}`; + this._urlPrefixHumanReadable = `http://${host ?? 'localhost'}:${address.port}`; } } diff --git a/tests/library/trace-viewer.spec.ts b/tests/library/trace-viewer.spec.ts index 0e03f7fb1d094..706197fb0e1d6 100644 --- a/tests/library/trace-viewer.spec.ts +++ b/tests/library/trace-viewer.spec.ts @@ -2248,3 +2248,16 @@ test('should capture iframe with srcdoc', async ({ page, server, runAndTrace }) const frame = await traceViewer.snapshotFrame('Evaluate'); await expect(frame.frameLocator('iframe').getByRole('button')).toHaveText('Hello iframe'); }); + +test('take trace paths via stdin', async ({ childProcess, page }) => { + const cliEntrypoint = path.join(__dirname, '../../packages/playwright-core/cli.js'); + const cp = childProcess({ command: ['node', cliEntrypoint, 'show-trace', '--port', '0', '--stdin'] }); + await cp.waitForOutput('Listening on'); + const url = cp.output.match(/Listening on (http:\/\/[^\s]+)/)![1]; + await page.goto(url); + await expect(page).toHaveTitle('Playwright Trace Viewer'); + cp.write(traceFile); + await expect(page.locator('.action-title')).toContainText([ + /Create page/, + ]); +});