From 676d424ff5dc846bf352abbee080bfdeb0bb6d6b Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa <4232207+hi-ogawa@users.noreply.github.com> Date: Thu, 3 Sep 2026 18:14:32 +0900 Subject: [PATCH] refactor: scope trace report to run Co-authored-by: OpenCode (gpt-5.6-sol) --- packages/extension/src/api.ts | 7 +---- packages/extension/src/apiProcess.ts | 13 +------- packages/extension/src/runner.ts | 38 +++++++++++++----------- packages/extension/src/spawn/terminal.ts | 1 - packages/extension/src/spawn/ws.ts | 1 - packages/extension/src/worker/index.ts | 9 ++++-- packages/shared/src/emitter.ts | 10 +------ packages/shared/src/index.ts | 2 +- packages/worker/src/index.ts | 10 ------- packages/worker/src/reporter.ts | 16 +++++++++- 10 files changed, 45 insertions(+), 62 deletions(-) diff --git a/packages/extension/src/api.ts b/packages/extension/src/api.ts index 3a3ba91..60ce8cd 100644 --- a/packages/extension/src/api.ts +++ b/packages/extension/src/api.ts @@ -193,12 +193,7 @@ async function createVitestProcessAPI( } }) const files = await meta.rpc.getFiles() - const config = new VitestProjectConfig( - pkg, - meta.projects, - meta.workspaceSource, - meta.htmlReportPath, - ) + const config = new VitestProjectConfig(pkg, meta.projects, meta.workspaceSource) const api = new VitestProcessAPI(config) return { api, files } }) diff --git a/packages/extension/src/apiProcess.ts b/packages/extension/src/apiProcess.ts index e8c1086..b4799fe 100644 --- a/packages/extension/src/apiProcess.ts +++ b/packages/extension/src/apiProcess.ts @@ -24,7 +24,6 @@ export class VitestProjectConfig { readonly pkg: VitestPackage, readonly projects: SerializedProject[], readonly workspaceSource: string | false, - readonly htmlReportPath?: string, ) { this.id = normalize(pkg.id) this.workspaceFolder = pkg.folder @@ -112,12 +111,7 @@ export class VitestProcessAPI { * a handle wrapping the existing process (without closing it). */ static forDebug(pkg: VitestPackage, meta: ResolvedMeta): VitestProcessAPI { - const config = new VitestProjectConfig( - pkg, - meta.projects, - meta.workspaceSource, - meta.htmlReportPath, - ) + const config = new VitestProjectConfig(pkg, meta.projects, meta.workspaceSource) const api = new VitestProcessAPI(config) api.currentMeta = meta return api @@ -149,10 +143,6 @@ export class VitestProcessAPI { return this.config.workspaceSource } - get htmlReportPath() { - return this.config.htmlReportPath - } - get package() { return this.config.package } @@ -333,7 +323,6 @@ export interface ResolvedMeta { rpc: VitestExtensionRPC process: ExtensionWorkerProcess workspaceSource: string | false - htmlReportPath?: string pkg: VitestPackage projects: SerializedProject[] handlers: { diff --git a/packages/extension/src/runner.ts b/packages/extension/src/runner.ts index 1089d4a..57a6b95 100644 --- a/packages/extension/src/runner.ts +++ b/packages/extension/src/runner.ts @@ -111,28 +111,30 @@ export class TestRunner extends vscode.Disposable { }) }) - handle.handlers.onTestRunEnd(async (files, unhandledError, collecting, coverage) => { - if (!collecting && this.api.htmlReportPath) { - this.traceReports?.update(this.api.id, this.api.htmlReportPath, files, this.tree) - } - const testRun = this.testRun + handle.handlers.onTestRunEnd( + async (files, unhandledError, collecting, coverage, htmlReportPath) => { + if (!collecting && htmlReportPath) { + this.traceReports?.update(this.api.id, htmlReportPath, files, this.tree) + } + const testRun = this.testRun - if (!testRun) { - if (unhandledError) log.error(unhandledError) - this.endTestRun() - return - } + if (!testRun) { + if (unhandledError) log.error(unhandledError) + this.endTestRun() + return + } - if (coverage) { - await this.reportCoverage(coverage).catch((err) => { - showVitestError(`Failed to report coverage. ${err.message}`, err) - }) - } + if (coverage) { + await this.reportCoverage(coverage).catch((err) => { + showVitestError(`Failed to report coverage. ${err.message}`, err) + }) + } - if (unhandledError) testRun.appendOutput(formatTestOutput(unhandledError)) + if (unhandledError) testRun.appendOutput(formatTestOutput(unhandledError)) - if (!collecting) this.endTestRun() - }) + if (!collecting) this.endTestRun() + }, + ) handle.handlers.onConsoleLog((consoleLog) => { const testRun = this.testRun diff --git a/packages/extension/src/spawn/terminal.ts b/packages/extension/src/spawn/terminal.ts index 03aad80..793efc4 100644 --- a/packages/extension/src/spawn/terminal.ts +++ b/packages/extension/src/spawn/terminal.ts @@ -96,7 +96,6 @@ export async function createVitestTerminalProcess( handlers: meta.handlers, pkg, workspaceSource: meta.workspaceSource, - htmlReportPath: meta.htmlReportPath, process: vitestProcess, projects: meta.projects, dispose: meta.dispose, diff --git a/packages/extension/src/spawn/ws.ts b/packages/extension/src/spawn/ws.ts index 09db351..b25b20a 100644 --- a/packages/extension/src/spawn/ws.ts +++ b/packages/extension/src/spawn/ws.ts @@ -115,7 +115,6 @@ export function onWsConnection( onStart({ rpc: api, workspaceSource: message.workspaceSource, - htmlReportPath: message.htmlReportPath, handlers, projects: message.projects.map((p) => { if (p.dir) { diff --git a/packages/extension/src/worker/index.ts b/packages/extension/src/worker/index.ts index d47d5da..91ca4b2 100644 --- a/packages/extension/src/worker/index.ts +++ b/packages/extension/src/worker/index.ts @@ -39,8 +39,11 @@ emitter.on('message', async function onMessage(message: any) { const workerPath = pathToFileURL(join(__dirname, workerName)) const initModule = await import(workerPath.toString()) - const { createWorker, reporter, projects, workspaceSource, htmlReportPath } = - await initModule.initVitest(vitestModule, data, emitter) + const { createWorker, reporter, projects, workspaceSource } = await initModule.initVitest( + vitestModule, + data, + emitter, + ) const worker = createWorker() @@ -70,7 +73,7 @@ emitter.on('message', async function onMessage(message: any) { }) worker.initRpc(rpc) reporter.initRpc(rpc) - emitter.ready(projects, workspaceSource, htmlReportPath, isLegacy, vitestModule.version) + emitter.ready(projects, workspaceSource, isLegacy, vitestModule.version) await worker.vitest.report('onInit', worker.vitest) } catch (err: any) { diff --git a/packages/shared/src/emitter.ts b/packages/shared/src/emitter.ts index b1379f3..14e3ea2 100644 --- a/packages/shared/src/emitter.ts +++ b/packages/shared/src/emitter.ts @@ -11,18 +11,10 @@ abstract class WorkerEventEmitter { ready( projects: SerializedProject[], workspaceSource: string | false, - htmlReportPath: string | undefined, legacy: boolean, version: string | undefined, ) { - this.sendWorkerEvent({ - type: 'ready', - projects, - workspaceSource, - htmlReportPath, - legacy, - version, - }) + this.sendWorkerEvent({ type: 'ready', projects, workspaceSource, legacy, version }) } error(err: any) { diff --git a/packages/shared/src/index.ts b/packages/shared/src/index.ts index 957cc9e..7c21589 100644 --- a/packages/shared/src/index.ts +++ b/packages/shared/src/index.ts @@ -90,6 +90,7 @@ export interface ExtensionWorkerEvents { unhandledError: string, collecting?: boolean, coverage?: unknown, + htmlReportPath?: string, ) => void onCollected: (file: RunnerTestFile, collecting?: boolean) => void onTestRunStart: (files: string[]) => void @@ -193,7 +194,6 @@ export interface EventReady { type: 'ready' projects: SerializedProject[] workspaceSource: string | false - htmlReportPath?: string legacy: boolean // the actual runtime version, unlike VitestPackage.version // this is also defined when vitest is resolved via yarn pnp diff --git a/packages/worker/src/index.ts b/packages/worker/src/index.ts index 5a197ea..d5c5583 100644 --- a/packages/worker/src/index.ts +++ b/packages/worker/src/index.ts @@ -7,7 +7,6 @@ import type { Reporter, TestUserConfig } from 'vitest/node' import { Console } from 'node:console' import { Writable } from 'node:stream' import { toArray } from '@vitest/utils/helpers' -import { resolve } from 'pathe' import { VSCodeReporter } from './reporter' import { ExtensionWorker } from './worker' @@ -168,19 +167,10 @@ export async function initVitest( const workspaceSource: string | false = vitest.config.projects != null ? vitest.vite.config.configFile || false : false - let htmlReportPath: string | undefined - for (const reporter of vitest.config.reporters) { - if (Array.isArray(reporter) && reporter[0] === 'html') { - const options = reporter[1] as { outputDir?: string } - htmlReportPath = resolve(vitest.config.root, options.outputDir || '.vitest', 'index.html') - break - } - } return { vitest, reporter, workspaceSource, - htmlReportPath, projects, meta, createWorker() { diff --git a/packages/worker/src/reporter.ts b/packages/worker/src/reporter.ts index d91536a..1ca785e 100644 --- a/packages/worker/src/reporter.ts +++ b/packages/worker/src/reporter.ts @@ -16,6 +16,7 @@ import type { Vitest as VitestCore, } from 'vitest/node' import { parseErrorStacktrace } from '@vitest/utils/source-map' +import { resolve } from 'pathe' import { ExtensionWorker } from './worker' export class VSCodeReporter implements Reporter { @@ -29,6 +30,7 @@ export class VSCodeReporter implements Reporter { private debuggerAttached: boolean | undefined = undefined private coverageData: Record | undefined = undefined private silent: boolean | 'passed-only' = false + private htmlReportPath: string | undefined constructor(meta: WorkerInitMetadata, debug: WorkerRunnerOptions['debug']) { this.setupFilePaths = meta.setupFilePaths @@ -43,6 +45,18 @@ export class VSCodeReporter implements Reporter { this.configureAttachDebugging(vitest) this.silent = vitest.config.silent + for (const reporter of vitest.config.reporters) { + if (Array.isArray(reporter) && reporter[0] === 'html') { + const options = reporter[1] as { outputDir?: string } + this.htmlReportPath = resolve( + vitest.config.root, + options.outputDir || '.vitest', + 'index.html', + ) + break + } + } + vitest.projects.forEach((project) => { this.ensureSetupFileIsAllowed(project.vite.config) this.ensurePnpSuported(project.config) @@ -189,7 +203,7 @@ export class VSCodeReporter implements Reporter { // as any because Vitest types are different between v3 and v4, // and shared packages uses the lowest Vitest version - this.rpc.onTestRunEnd(files as any, '', false, coverage) + this.rpc.onTestRunEnd(files as any, '', false, coverage, this.htmlReportPath) } onTestModuleCollected(testModule: TestModule) { -- 2.51.2