Skip to content

Commit

Permalink
chore: use test server as a singleton (#423)
Browse files Browse the repository at this point in the history
  • Loading branch information
pavelfeldman authored Feb 22, 2024
1 parent 64de0fe commit 28d3b6b
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 16 deletions.
8 changes: 4 additions & 4 deletions src/playwrightTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -258,11 +258,11 @@ export class PlaywrightTest {
const env = await reporterServer.env({ selfDestruct: false });
const reporter = reporterServer.reporterFile();
if (mode === 'list')
testServer.list({ locations, reporter, env });
testServer.list({ configFile: config.configFile, locations, reporter, env });
if (mode === 'run') {
testServer.test({ locations, reporter, env, options });
testServer.test({ configFile: config.configFile, locations, reporter, env, ...options });
token.onCancellationRequested(() => {
testServer.stop();
testServer.stop({ configFile: config.configFile });
});
testServer.on('stdio', params => {
if (params.type === 'stdout')
Expand Down Expand Up @@ -309,7 +309,7 @@ export class PlaywrightTest {
const testServer = await this._testServerController.testServerFor(config);
if (!testServer)
return await this._findRelatedTestFilesCLI(config, files);
return await testServer.findRelatedTestFiles({ files });
return await testServer.findRelatedTestFiles({ configFile: config.configFile, files });
}

async debugTests(vscode: vscodeTypes.VSCode, config: TestConfig, projectNames: string[], testDirs: string[], settingsEnv: NodeJS.ProcessEnv, locations: string[] | null, listener: TestListener, parametrizedTestTitle: string | undefined, token: vscodeTypes.CancellationToken) {
Expand Down
72 changes: 60 additions & 12 deletions src/testServerController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,22 +17,28 @@
import { BackendClient, BackendServer } from './backend';
import { ConfigFindRelatedTestFilesReport } from './listTests';
import { TestConfig } from './playwrightTest';
import type { TestError } from './reporter';
import * as vscodeTypes from './vscodeTypes';

export class TestServerController implements vscodeTypes.Disposable {
private _vscode: vscodeTypes.VSCode;
private _testServers = new Map<TestConfig, TestServer>();
private _instancePromise: Promise<TestServer | null> | undefined;
private _instance: TestServer | null = null;
private _envProvider: () => NodeJS.ProcessEnv;

constructor(vscode: vscodeTypes.VSCode, envProvider: () => NodeJS.ProcessEnv) {
this._vscode = vscode;
this._envProvider = envProvider;
}

async testServerFor(config: TestConfig): Promise<TestServer | null> {
const existing = this._testServers.get(config);
if (existing)
return existing;
async testServerFor(config: TestConfig): Promise<TestServerInterface & TestServerEvents | null> {
if (this._instancePromise)
return this._instancePromise;
this._instancePromise = this._createTestServer(config);
return this._instancePromise;
}

private async _createTestServer(config: TestConfig): Promise<TestServer | null> {
const args = [config.cli, 'test-server'];
const testServerBackend = new BackendServer<TestServer>(this._vscode, {
args,
Expand All @@ -47,9 +53,7 @@ export class TestServerController implements vscodeTypes.Disposable {
dumpIO: false,
});
const testServer = await testServerBackend.start();
if (!testServer)
return null;
this._testServers.set(config, testServer);
this._instance = testServer;
return testServer;
}

Expand All @@ -58,13 +62,52 @@ export class TestServerController implements vscodeTypes.Disposable {
}

reset() {
for (const backend of this._testServers.values())
backend.close();
this._testServers.clear();
if (this._instancePromise)
this._instancePromise.then(server => server?.closeGracefully());
this._instancePromise = undefined;
this._instance = null;
}
}

class TestServer extends BackendClient {
interface TestServerInterface {
list(params: {
configFile: string;
locations: string[];
reporter: string;
env: NodeJS.ProcessEnv;
}): Promise<void>;

test(params: {
configFile: string;
locations: string[];
reporter: string;
env: NodeJS.ProcessEnv;
headed?: boolean;
oneWorker?: boolean;
trace?: 'on' | 'off';
projects?: string[];
grep?: string;
reuseContext?: boolean;
connectWsEndpoint?: string;
}): Promise<void>;

findRelatedTestFiles(params: {
configFile: string;
files: string[];
}): Promise<{ testFiles: string[]; errors?: TestError[]; }>;

stop(params: {
configFile: string;
}): Promise<void>;

closeGracefully(): Promise<void>;
}

interface TestServerEvents {
on(event: 'stdio', listener: (params: { type: 'stdout' | 'stderr', text?: string, buffer?: string }) => void): void;
}

class TestServer extends BackendClient implements TestServerInterface, TestServerEvents {
override async initialize(): Promise<void> {
}

Expand All @@ -83,4 +126,9 @@ class TestServer extends BackendClient {
async stop() {
await this.send('stop', {});
}

async closeGracefully() {
await this.send('closeGracefully', {});
this.close();
}
}

0 comments on commit 28d3b6b

Please sign in to comment.