11import type { CDPSession } from '@vitest/browser-playwright'
22import type { BrowserCommand , BrowserCommandContext } from 'vitest/node'
3+ import type { V8CoverageProvider } from './provider'
4+ import { randomUUID } from 'node:crypto'
5+ import { existsSync } from 'node:fs'
6+ import { writeFile } from 'node:fs/promises'
7+ import { resolve } from 'pathe'
38
4- export const commands : Record < string , BrowserCommand > = {
9+ export const commands : Record < string , BrowserCommand < any [ ] > > = {
510 startV8Coverage,
611 takeV8Coverage,
712}
@@ -15,7 +20,77 @@ async function startV8Coverage(context: BrowserCommandContext): Promise<void> {
1520 } )
1621}
1722
18- async function takeV8Coverage ( context : BrowserCommandContext ) : Promise < any > {
23+ async function takeV8Coverage ( context : BrowserCommandContext , pageUrl : string ) : Promise < string > {
1924 const session : CDPSession = await context . __ensureCDPHandler ( )
20- return session . send ( 'Profiler.takePreciseCoverage' )
25+ const coverage = await session . send ( 'Profiler.takePreciseCoverage' )
26+
27+ const origin = new URL ( pageUrl ) . origin
28+ const result : typeof coverage . result = [ ]
29+
30+ for ( const entry of coverage . result ) {
31+ if ( filterResult ( entry . url , origin , pageUrl ) ) {
32+ entry . url = decodeURIComponent ( entry . url . replace ( origin , '' ) )
33+ result . push ( entry )
34+ }
35+ }
36+
37+ const provider = context . project . vitest . coverageProvider as V8CoverageProvider
38+
39+ return await writeCoverageFile ( provider . coverageFilesDirectory , { result } )
40+ }
41+
42+ export async function writeCoverageFile ( coverageFilesDirectory : string , coverage : unknown ) : Promise < string > {
43+ // Write results on file system directly and transfer only the filename over RPC
44+ const filename = resolve (
45+ coverageFilesDirectory ,
46+ `coverage-${ randomUUID ( ) } .json` ,
47+ )
48+
49+ try {
50+ await writeFile ( filename , JSON . stringify ( coverage ) , 'utf-8' )
51+ }
52+ catch ( error ) {
53+ if ( ! existsSync ( coverageFilesDirectory ) ) {
54+ throw new Error (
55+ `Something removed the coverage directory "${ coverageFilesDirectory } " Vitest created earlier. Make sure you are not running multiple Vitests with the same "coverage.reportsDirectory" at the same time.` ,
56+ { cause : error } ,
57+ )
58+ }
59+
60+ throw error
61+ }
62+
63+ return filename
64+ }
65+
66+ function filterResult ( url : string , origin : string , pageUrl : string ) : boolean {
67+ if ( ! url . startsWith ( origin ) ) {
68+ return false
69+ }
70+
71+ if ( url . includes ( '/node_modules/' ) ) {
72+ return false
73+ }
74+
75+ if ( url . includes ( '__vitest_browser__' ) ) {
76+ return false
77+ }
78+
79+ if ( url . includes ( '__vitest__/assets' ) ) {
80+ return false
81+ }
82+
83+ if ( url === pageUrl ) {
84+ return false
85+ }
86+
87+ if ( url . includes ( '/@id/@vitest/' ) ) {
88+ return false
89+ }
90+
91+ if ( url . includes ( '/@vite/client' ) ) {
92+ return false
93+ }
94+
95+ return true
2196}
0 commit comments