Skip to content

Commit

Permalink
chore: implement server-base list files (#424)
Browse files Browse the repository at this point in the history
  • Loading branch information
pavelfeldman authored Feb 23, 2024
1 parent 28d3b6b commit 3c03c45
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 62 deletions.
42 changes: 28 additions & 14 deletions src/playwrightTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,16 +94,12 @@ export class PlaywrightTest {
}

async listFiles(config: TestConfig): Promise<ConfigListFilesReport> {
const configFolder = path.dirname(config.configFile);
const configFile = path.basename(config.configFile);
const allArgs = [config.cli, 'list-files', '-c', configFile];
{
// For tests.
this._log(`${escapeRegex(path.relative(config.workspaceFolder, configFolder))}> playwright list-files -c ${configFile}`);
}
try {
const output = await this._runNode(allArgs, configFolder);
const result = JSON.parse(output) as ConfigListFilesReport;
let result: ConfigListFilesReport;
if (this._useTestServer(config))
result = await this._listFilesServer(config);
else
result = await this._listFilesCLI(config);
// TODO: merge getPlaywrightInfo and listFiles to avoid this.
// Override the cli entry point with the one obtained from the config.
if (result.cliEntryPoint)
Expand All @@ -112,14 +108,34 @@ export class PlaywrightTest {
} catch (error: any) {
return {
error: {
location: { file: configFile, line: 0, column: 0 },
location: { file: config.configFile, line: 0, column: 0 },
message: error.message,
},
projects: [],
};
}
}

private async _listFilesCLI(config: TestConfig): Promise<ConfigListFilesReport> {
const configFolder = path.dirname(config.configFile);
const configFile = path.basename(config.configFile);
const allArgs = [config.cli, 'list-files', '-c', configFile];
{
// For tests.
this._log(`${escapeRegex(path.relative(config.workspaceFolder, configFolder))}> playwright list-files -c ${configFile}`);
}
const output = await this._runNode(allArgs, configFolder);
const result = JSON.parse(output) as ConfigListFilesReport;
return result;
}

private async _listFilesServer(config: TestConfig): Promise<ConfigListFilesReport> {
const testServer = await this._testServerController.testServerFor(config);
if (!testServer)
throw new Error('Internal error: unable to connect to the test server');
return await testServer.listFiles({ configFile: config.configFile });
}

async runTests(config: TestConfig, projectNames: string[], locations: string[] | null, listener: TestListener, parametrizedTestTitle: string | undefined, token: vscodeTypes.CancellationToken) {
const locationArg = locations ? locations : [];
if (token?.isCancellationRequested)
Expand Down Expand Up @@ -252,13 +268,11 @@ export class PlaywrightTest {
if (token?.isCancellationRequested)
return;
if (!testServer)
return this._testWithCLI(config, locations, mode, options, listener, token);
if (token?.isCancellationRequested)
return;
const env = await reporterServer.env({ selfDestruct: false });
const reporter = reporterServer.reporterFile();
if (mode === 'list')
testServer.list({ configFile: config.configFile, locations, reporter, env });
testServer.listTests({ configFile: config.configFile, locations, reporter, env });
if (mode === 'run') {
testServer.test({ configFile: config.configFile, locations, reporter, env, ...options });
token.onCancellationRequested(() => {
Expand Down Expand Up @@ -308,7 +322,7 @@ export class PlaywrightTest {
async _findRelatedTestFilesServer(config: TestConfig, files: string[]): Promise<ConfigFindRelatedTestFilesReport> {
const testServer = await this._testServerController.testServerFor(config);
if (!testServer)
return await this._findRelatedTestFilesCLI(config, files);
return { testFiles: files, errors: [{ message: 'Internal error: unable to connect to the test server' }] };
return await testServer.findRelatedTestFiles({ configFile: config.configFile, files });
}

Expand Down
51 changes: 7 additions & 44 deletions src/testServerController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,12 @@
import { BackendClient, BackendServer } from './backend';
import { ConfigFindRelatedTestFilesReport } from './listTests';
import { TestConfig } from './playwrightTest';
import type { TestError } from './reporter';
import type { TestServerEvents, TestServerInterface } from './testServerInterface';
import * as vscodeTypes from './vscodeTypes';

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

constructor(vscode: vscodeTypes.VSCode, envProvider: () => NodeJS.ProcessEnv) {
Expand Down Expand Up @@ -53,7 +52,6 @@ export class TestServerController implements vscodeTypes.Disposable {
dumpIO: false,
});
const testServer = await testServerBackend.start();
this._instance = testServer;
return testServer;
}

Expand All @@ -65,54 +63,19 @@ export class TestServerController implements vscodeTypes.Disposable {
if (this._instancePromise)
this._instancePromise.then(server => server?.closeGracefully());
this._instancePromise = undefined;
this._instance = null;
}
}

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> {
}

async list(params: any) {
await this.send('list', params);
async listFiles(params: any) {
return await this.send('listFiles', params);
}

async listTests(params: any) {
await this.send('listTests', params);
}

findRelatedTestFiles(params: { files: string[]; }): Promise<ConfigFindRelatedTestFilesReport> {
Expand Down
68 changes: 68 additions & 0 deletions src/testServerInterface.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/**
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import type { TestError } from './reporter';

export interface TestServerInterface {
listFiles(params: {
configFile: string;
}): Promise<{
projects: {
name: string;
testDir: string;
use: { testIdAttribute?: string };
files: string[];
}[];
cliEntryPoint?: string;
error?: TestError;
}>;

listTests(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>;
}

export interface TestServerEvents {
on(event: 'stdio', listener: (params: { type: 'stdout' | 'stderr', text?: string, buffer?: string }) => void): void;
}
7 changes: 4 additions & 3 deletions tests/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,6 @@ export const test = baseTest.extend<TestFixtures, WorkerOptions>({
} else {
await vscode.addWorkspaceFolder(options?.rootDir || testInfo.outputDir, files);
}
const extension = new Extension(vscode);
vscode.extensions.push(extension);
await vscode.activate();

if (showBrowser) {
const configuration = vscode.workspace.getConfiguration('playwright');
Expand All @@ -96,6 +93,10 @@ export const test = baseTest.extend<TestFixtures, WorkerOptions>({
configuration.update('useTestServer', true);
}

const extension = new Extension(vscode);
vscode.extensions.push(extension);
await vscode.activate();

instances.push(vscode);
return {
vscode,
Expand Down
2 changes: 1 addition & 1 deletion tests/watch.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ test('should unwatch all tests', async ({ activate }) => {

expect(testRuns).toHaveLength(0);

expect(vscode.renderExecLog(' ')).toBe(`
expect(vscode).toHaveExecLog(`
> playwright list-files -c playwright.config.js
`);
});
Expand Down

0 comments on commit 3c03c45

Please sign in to comment.