diff --git a/src/playwrightTestCLI.ts b/src/playwrightTestCLI.ts index 4d51a4811..9352d2fc1 100644 --- a/src/playwrightTestCLI.ts +++ b/src/playwrightTestCLI.ts @@ -54,46 +54,55 @@ export class PlaywrightTestCLI { }; } - async test(locations: string[], mode: 'list' | 'test', options: PlaywrightTestRunOptions, reporter: reporterTypes.ReporterV2, token: vscodeTypes.CancellationToken): Promise { + async listTests(locations: string[], reporter: reporterTypes.ReporterV2, token: vscodeTypes.CancellationToken): Promise { + const args = []; + args.push('--list', '--reporter=null'); + await this._innerSpawn(locations, args, {}, reporter, token); + } + + async runTests(locations: string[], options: PlaywrightTestRunOptions, reporter: reporterTypes.ReporterV2, token: vscodeTypes.CancellationToken): Promise { + const args = []; + if (options.projects) + options.projects.forEach(p => args.push(`--project=${p}`)); + if (options.grep) + args.push(`--grep=${escapeRegex(options.grep)}`); + args.push('--repeat-each=1'); + args.push('--retries=0'); + if (options.headed) + args.push('--headed'); + if (options.workers) + args.push(`--workers=${options.workers}`); + if (options.trace) + args.push(`--trace=${options.trace}`); + await this._innerSpawn(locations, args, options, reporter, token); + } + + async _innerSpawn(locations: string[], extraArgs: string[], options: PlaywrightTestRunOptions, reporter: reporterTypes.ReporterV2, token: vscodeTypes.CancellationToken) { + if (token?.isCancellationRequested) + return; + // Playwright will restart itself as child process in the ESM mode and won't inherit the 3/4 pipes. // Always use ws transport to mitigate it. const reporterServer = new ReporterServer(this._vscode); const node = await findNode(this._vscode, this._config.workspaceFolder); - if (token?.isCancellationRequested) - return; const configFolder = path.dirname(this._config.configFile); const configFile = path.basename(this._config.configFile); const escapedLocations = locations.map(escapeRegex).sort(); - const args = []; - if (mode === 'list') - args.push('--list', '--reporter=null'); - - if (options.projects) - options.projects.forEach(p => args.push(`--project=${p}`)); - if (options.grep) - args.push(`--grep=${escapeRegex(options.grep)}`); { // For tests. const relativeLocations = locations.map(f => path.relative(configFolder, f)).map(escapeRegex).sort(); - this._log(`${escapeRegex(path.relative(this._config.workspaceFolder, configFolder))}> playwright test -c ${configFile}${args.length ? ' ' + args.join(' ') : ''}${relativeLocations.length ? ' ' + relativeLocations.join(' ') : ''}`); + const printArgs = extraArgs.filter(a => !a.includes('--repeat-each') && !a.includes('--retries') && !a.includes('--workers') && !a.includes('--trace')); + this._log(`${escapeRegex(path.relative(this._config.workspaceFolder, configFolder))}> playwright test -c ${configFile}${printArgs.length ? ' ' + printArgs.join(' ') : ''}${relativeLocations.length ? ' ' + relativeLocations.join(' ') : ''}`); } - const allArgs = [this._config.cli, 'test', + + const childProcess = spawn(node, [ + this._config.cli, + 'test', '-c', configFile, - ...args, + ...extraArgs, ...escapedLocations, - '--repeat-each', '1', - '--retries', '0', - ]; - - if (options.headed) - allArgs.push('--headed'); - if (options.workers) - allArgs.push('--workers', String(options.workers)); - if (options.trace) - allArgs.push('--trace', options.trace); - - const childProcess = spawn(node, allArgs, { + ], { cwd: configFolder, stdio: ['pipe', 'pipe', 'pipe', 'pipe', 'pipe'], env: { @@ -116,7 +125,7 @@ export class PlaywrightTestCLI { const stdio = childProcess.stdio; stdio[1].on('data', data => reporter.onStdOut?.(data)); stdio[2].on('data', data => reporter.onStdErr?.(data)); - await reporterServer.wireTestListener(mode, reporter, token); + await reporterServer.wireTestListener(reporter, token); } async findRelatedTestFiles(files: string[]): Promise { diff --git a/src/playwrightTestServer.ts b/src/playwrightTestServer.ts index 5c25671c7..acd7c8654 100644 --- a/src/playwrightTestServer.ts +++ b/src/playwrightTestServer.ts @@ -79,14 +79,7 @@ export class PlaywrightTestServer { return result; } - async test(locations: string[], mode: 'list' | 'test', options: PlaywrightTestRunOptions, reporter: reporterTypes.ReporterV2, token: vscodeTypes.CancellationToken): Promise { - if (mode === 'test') - await this._test(locations, options, reporter, token); - else - await this._list(locations, reporter, token); - } - - private async _list(locations: string[], reporter: reporterTypes.ReporterV2, token: vscodeTypes.CancellationToken): Promise { + async listTests(locations: string[], reporter: reporterTypes.ReporterV2, token: vscodeTypes.CancellationToken): Promise { const testServer = await this._testServer(); if (token?.isCancellationRequested) return; @@ -104,7 +97,7 @@ export class PlaywrightTestServer { teleReceiver.dispatch(message); } - private async _test(locations: string[], options: PlaywrightTestRunOptions, reporter: reporterTypes.ReporterV2, token: vscodeTypes.CancellationToken): Promise { + async runTests(locations: string[], options: PlaywrightTestRunOptions, reporter: reporterTypes.ReporterV2, token: vscodeTypes.CancellationToken): Promise { const testServer = await this._testServer(); if (token?.isCancellationRequested) return; diff --git a/src/reporterServer.ts b/src/reporterServer.ts index 6bf2bff06..84f6ebd0b 100644 --- a/src/reporterServer.ts +++ b/src/reporterServer.ts @@ -66,7 +66,7 @@ export class ReporterServer { return wsEndpoint; } - async wireTestListener(mode: 'test' | 'list', listener: reporterTypes.ReporterV2, token: vscodeTypes.CancellationToken) { + async wireTestListener(listener: reporterTypes.ReporterV2, token: vscodeTypes.CancellationToken) { let timeout: NodeJS.Timeout | undefined; const transport = await this._waitForTransport(); diff --git a/src/testModel.ts b/src/testModel.ts index aaf8d16ad..c2b464583 100644 --- a/src/testModel.ts +++ b/src/testModel.ts @@ -281,7 +281,7 @@ export class TestModel { private async _listTests(files: string[]) { const errors: reporterTypes.TestError[] = []; let rootSuite: reporterTypes.Suite | undefined; - await this._playwrightTest.test(files, 'list', {}, { + await this._playwrightTest.listTests(files, { onBegin: (suite: reporterTypes.Suite) => { rootSuite = suite; }, @@ -378,7 +378,7 @@ export class TestModel { try { if (token?.isCancellationRequested) return; - await this._playwrightTest.test(locationArg, 'test', options, reporter, token); + await this._playwrightTest.runTests(locationArg, options, reporter, token); } finally { await this._options.runHooks.onDidRunTests(false); } @@ -435,7 +435,7 @@ export class TestModel { program: this.config.cli, args, }); - await reporterServer.wireTestListener('test', reporter, token); + await reporterServer.wireTestListener(reporter, token); } finally { await this._options.runHooks.onDidRunTests(true); }