@@ -3,21 +3,41 @@ import type { CoverageProviderModule } from 'vitest/node'
33import type { ScriptCoverageWithOffset , V8CoverageProvider } from './provider'
44import inspector from 'node:inspector/promises'
55import { fileURLToPath } from 'node:url'
6+ import { getPort } from 'get-port-please'
67import { normalize } from 'pathe'
78import { provider } from 'std-env'
9+ import { WebSocketServer } from 'ws'
810import { loadProvider } from './load-provider'
911
10- const session = new inspector . Session ( )
12+ let session : inspector . Session | null = null
1113let enabled = false
1214
13- const mod : CoverageProviderModule = {
14- async startCoverage ( { isolate } ) {
15+ const mod : CoverageProviderModule & { wss : WebSocketServer | undefined ; extendedContextCoverage : Profiler . ScriptCoverage [ ] } = {
16+ wss : undefined ,
17+ extendedContextCoverage : [ ] ,
18+
19+ async startCoverage ( { isolate, trackProcessAndWorker } ) {
1520 if ( isolate === false && enabled ) {
1621 return
1722 }
1823
1924 enabled = true
2025
26+ if ( trackProcessAndWorker ) {
27+ const port = await getPort ( )
28+ this . wss = new WebSocketServer ( { port } )
29+
30+ this . wss . on ( 'connection' , socket => socket . on ( 'message' , ( raw ) => {
31+ const result : ScriptCoverageWithOffset [ ] = JSON . parse ( raw . toString ( ) )
32+ this . extendedContextCoverage . push ( ...( result || [ ] ) )
33+ } ) )
34+
35+ process . env . NODE_OPTIONS ||= ''
36+ process . env . NODE_OPTIONS += ' --import @vitest/coverage-v8/intercept-new-run-context'
37+ process . env . VITEST_WS_PORT = `${ port } `
38+ }
39+
40+ session ||= new inspector . Session ( )
2141 session . connect ( )
2242 await session . post ( 'Profiler.enable' )
2343 await session . post ( 'Profiler.startPreciseCoverage' , { callCount : true , detailed : true } )
@@ -28,11 +48,16 @@ const mod: CoverageProviderModule = {
2848 return { result : [ ] }
2949 }
3050
51+ if ( ! session ) {
52+ throw new Error ( 'V8 provider missing inspector session.' )
53+ }
54+
55+ this . wss ?. clients . forEach ( client => client . send ( 'take-coverage' ) )
3156 const coverage = await session . post ( 'Profiler.takePreciseCoverage' )
3257 const result : ScriptCoverageWithOffset [ ] = [ ]
3358
3459 // Reduce amount of data sent over rpc by doing some early result filtering
35- for ( const entry of coverage . result ) {
60+ for ( const entry of [ ... coverage . result , ... this . extendedContextCoverage . splice ( 0 ) ] ) {
3661 if ( filterResult ( entry ) ) {
3762 result . push ( {
3863 ...entry ,
@@ -49,9 +74,14 @@ const mod: CoverageProviderModule = {
4974 return
5075 }
5176
77+ if ( ! session ) {
78+ throw new Error ( 'V8 provider missing inspector session.' )
79+ }
80+
5281 await session . post ( 'Profiler.stopPreciseCoverage' )
5382 await session . post ( 'Profiler.disable' )
5483 session . disconnect ( )
84+ this . wss ?. close ( )
5585 } ,
5686
5787 async getProvider ( ) : Promise < V8CoverageProvider > {
0 commit comments