From eb1d8e918b4c554e600155f6c47a9a814984ee66 Mon Sep 17 00:00:00 2001 From: Pavel Feldman Date: Wed, 3 Apr 2024 10:24:52 -0700 Subject: [PATCH] chore: migrate to the testserver.initialize --- .../src/server/trace/viewer/traceViewer.ts | 2 +- .../src/isomorphic/testServerConnection.ts | 28 ++++++--------- .../src/isomorphic/testServerInterface.ts | 11 +++--- packages/playwright/src/runner/testServer.ts | 35 +++++++++++-------- packages/trace-viewer/src/ui/uiModeView.tsx | 6 ++-- .../trace-viewer/src/ui/workbenchLoader.tsx | 1 + 6 files changed, 42 insertions(+), 41 deletions(-) diff --git a/packages/playwright-core/src/server/trace/viewer/traceViewer.ts b/packages/playwright-core/src/server/trace/viewer/traceViewer.ts index 3f1511cef694f..3de6bec1b828f 100644 --- a/packages/playwright-core/src/server/trace/viewer/traceViewer.ts +++ b/packages/playwright-core/src/server/trace/viewer/traceViewer.ts @@ -216,7 +216,7 @@ class StdinServer implements Transport { } async dispatch(method: string, params: any) { - if (method === 'ready') { + if (method === 'initialize') { if (this._traceUrl) this._loadTrace(this._traceUrl); } diff --git a/packages/playwright/src/isomorphic/testServerConnection.ts b/packages/playwright/src/isomorphic/testServerConnection.ts index af181abda68ff..36b4683d95e55 100644 --- a/packages/playwright/src/isomorphic/testServerConnection.ts +++ b/packages/playwright/src/isomorphic/testServerConnection.ts @@ -64,10 +64,7 @@ export class TestServerConnection implements TestServerInterface, TestServerInte }); const pingInterval = setInterval(() => this._sendMessage('ping').catch(() => {}), 30000); this._connectedPromise = new Promise((f, r) => { - this._ws.addEventListener('open', () => { - f(); - this._ws.send(JSON.stringify({ id: -1, method: 'ready' })); - }); + this._ws.addEventListener('open', () => f()); this._ws.addEventListener('error', r); }); this._ws.addEventListener('close', () => { @@ -76,10 +73,6 @@ export class TestServerConnection implements TestServerInterface, TestServerInte }); } - connect() { - return this._connectedPromise; - } - private async _sendMessage(method: string, params?: any): Promise { const logForTest = (globalThis as any).__logForTest; logForTest?.({ method, params }); @@ -110,8 +103,8 @@ export class TestServerConnection implements TestServerInterface, TestServerInte this._onLoadTraceRequestedEmitter.fire(params); } - async setSerializer(params: { serializer: string; }): Promise { - await this._sendMessage('setSerializer', params); + async initialize(params: Parameters[0]): ReturnType { + await this._sendMessage('initialize', params); } async ping(params: Parameters[0]): ReturnType { @@ -130,10 +123,6 @@ export class TestServerConnection implements TestServerInterface, TestServerInte this._sendMessageNoReply('watch', params); } - async watchTestDir(params: Parameters[0]): ReturnType { - await this._sendMessage('watchTestDir', params); - } - async open(params: Parameters[0]): ReturnType { await this._sendMessage('open', params); } @@ -190,11 +179,14 @@ export class TestServerConnection implements TestServerInterface, TestServerInte this._sendMessageNoReply('stopTests', params); } - async setInterceptStdio(params: Parameters[0]): ReturnType { - await this._sendMessage('setInterceptStdio', params); - } - async closeGracefully(params: Parameters[0]): ReturnType { await this._sendMessage('closeGracefully', params); } + + close() { + try { + this._ws.close(); + } catch { + } + } } diff --git a/packages/playwright/src/isomorphic/testServerInterface.ts b/packages/playwright/src/isomorphic/testServerInterface.ts index 8acfcb4543058..34571513b454b 100644 --- a/packages/playwright/src/isomorphic/testServerInterface.ts +++ b/packages/playwright/src/isomorphic/testServerInterface.ts @@ -21,7 +21,12 @@ import type { JsonEvent } from './teleReceiver'; export type ReportEntry = JsonEvent; export interface TestServerInterface { - setSerializer(params: { serializer: string }): Promise; + initialize(params: { + serializer?: string, + closeOnDisconnect?: boolean, + interceptStdio?: boolean, + watchTestDirs?: boolean, + }): Promise; ping(params: {}): Promise; @@ -29,8 +34,6 @@ export interface TestServerInterface { fileNames: string[]; }): Promise; - watchTestDir(params: {}): Promise; - open(params: { location: reporterTypes.Location }): Promise; resizeTerminal(params: { cols: number, rows: number }): Promise; @@ -90,8 +93,6 @@ export interface TestServerInterface { stopTests(params: {}): Promise; - setInterceptStdio(params: { intercept: boolean }): Promise; - closeGracefully(params: {}): Promise; } diff --git a/packages/playwright/src/runner/testServer.ts b/packages/playwright/src/runner/testServer.ts index dc9c2ef49c000..7bfec4a583fdf 100644 --- a/packages/playwright/src/runner/testServer.ts +++ b/packages/playwright/src/runner/testServer.ts @@ -56,7 +56,7 @@ class TestServer { } async stop() { - await this._dispatcher?.setInterceptStdio({ intercept: false }); + await this._dispatcher?._setInterceptStdio(false); await this._dispatcher?.runGlobalTeardown(); } } @@ -72,13 +72,17 @@ class TestServerDispatcher implements TestServerInterface { readonly _dispatchEvent: TestServerInterfaceEventEmitters['dispatchEvent']; private _plugins: TestRunnerPluginRegistration[] | undefined; private _serializer = require.resolve('./uiModeReporter'); - private _watchTestDir = false; + private _watchTestDirs = false; + private _closeOnDisconnect = false; constructor(configFile: string | undefined) { this._configFile = configFile; this.transport = { dispatch: (method, params) => (this as any)[method](params), - onclose: () => {}, + onclose: () => { + if (this._closeOnDisconnect) + gracefullyProcessExitDoNotHang(0); + }, }; this._globalWatcher = new Watcher('deep', () => this._dispatchEvent('listChanged', {})); this._testWatcher = new Watcher('flat', events => { @@ -89,10 +93,6 @@ class TestServerDispatcher implements TestServerInterface { this._dispatchEvent = (method, params) => this.transport.sendEvent?.(method, params); } - async setSerializer(params: { serializer: string; }): Promise { - this._serializer = params.serializer; - } - private async _wireReporter(messageSink: (message: any) => void) { return await createReporterForTestServer(this._serializer, messageSink); } @@ -104,7 +104,16 @@ class TestServerDispatcher implements TestServerInterface { return { reporter, report }; } - async ready() {} + async initialize(params: Parameters[0]): ReturnType { + if (params.serializer) + this._serializer = params.serializer; + if (params.closeOnDisconnect) + this._closeOnDisconnect = true; + if (params.interceptStdio) + await this._setInterceptStdio(true); + if (params.watchTestDirs) + this._watchTestDirs = true; + } async ping() {} @@ -226,7 +235,7 @@ class TestServerDispatcher implements TestServerInterface { projectOutputs.add(result.outDir); } - if (this._watchTestDir) + if (this._watchTestDirs) this._globalWatcher.update([...projectDirs], [...projectOutputs], false); return { report, status }; } @@ -295,10 +304,6 @@ class TestServerDispatcher implements TestServerInterface { return { status: await run }; } - async watchTestDir() { - this._watchTestDir = true; - } - async watch(params: { fileNames: string[]; }) { const files = new Set(); for (const fileName of params.fileNames) { @@ -321,10 +326,10 @@ class TestServerDispatcher implements TestServerInterface { await this._testRun?.run; } - async setInterceptStdio(params: Parameters[0]): ReturnType { + async _setInterceptStdio(intercept: boolean) { if (process.env.PWTEST_DEBUG) return; - if (params.intercept) { + if (intercept) { process.stdout.write = (chunk: string | Buffer) => { this._dispatchEvent('stdio', chunkToPayload('stdout', chunk)); return true; diff --git a/packages/trace-viewer/src/ui/uiModeView.tsx b/packages/trace-viewer/src/ui/uiModeView.tsx index 3ff40639f0551..03abb468ab6df 100644 --- a/packages/trace-viewer/src/ui/uiModeView.tsx +++ b/packages/trace-viewer/src/ui/uiModeView.tsx @@ -172,8 +172,10 @@ export const UIModeView: React.FC<{}> = ({ setIsLoading(true); setWatchedTreeIds({ value: new Set() }); (async () => { - await testServerConnection.setInterceptStdio({ intercept: true }); - await testServerConnection.watchTestDir({}); + await testServerConnection.initialize({ + interceptStdio: true, + watchTestDirs: true + }); const { status } = await testServerConnection.runGlobalSetup({}); if (status !== 'passed') return; diff --git a/packages/trace-viewer/src/ui/workbenchLoader.tsx b/packages/trace-viewer/src/ui/workbenchLoader.tsx index 8efa265ae3e2b..1038d8ac99f52 100644 --- a/packages/trace-viewer/src/ui/workbenchLoader.tsx +++ b/packages/trace-viewer/src/ui/workbenchLoader.tsx @@ -93,6 +93,7 @@ export const WorkbenchLoader: React.FunctionComponent<{ setDragOver(false); setProcessingErrorMessage(null); }); + testServerConnection.initialize({}).catch(() => {}); } else if (!newTraceURLs.some(url => url.startsWith('blob:'))) { // Don't re-use blob file URLs on page load (results in Fetch error) setTraceURLs(newTraceURLs);