11import type { Envelope , EnvelopeItemType } from '@sentry/core' ;
22import { normalize } from '@sentry/core' ;
33import { createBasicSentryServer } from '@sentry-internal/test-utils' ;
4- import { spawn } from 'child_process' ;
5- import { existsSync } from 'fs' ;
4+ import { spawn , spawnSync } from 'child_process' ;
5+ import { existsSync , readdirSync , readFileSync } from 'fs' ;
66import { join } from 'path' ;
77import { inspect } from 'util' ;
88import { expect } from 'vitest' ;
@@ -18,6 +18,60 @@ export function cleanupChildProcesses(): void {
1818
1919process . on ( 'exit' , cleanupChildProcesses ) ;
2020
21+ /**
22+ * Resolve the wrangler config `wrangler dev` should serve for a worker.
23+ *
24+ * Most suites run straight from source (`wrangler dev --config <name>.jsonc`).
25+ * A suite that opts into the Sentry Vite plugin instead ships a `vite.config.*`
26+ * (and no top-level `main` in its wrangler config): for those we run `vite build`
27+ * first — so the plugin's build-time auto-instrumentation transform runs — and
28+ * point wrangler at the generated config under `dist/<worker>/wrangler.json`.
29+ *
30+ * `wranglerConfigName` selects which source config the Vite build corresponds to
31+ * (`wrangler.jsonc` for the main worker, `wrangler-sub-worker.jsonc` for a sub),
32+ * so a Vite suite's generated output is matched to the right worker.
33+ */
34+ function resolveWorkerConfig ( testPath : string , wranglerConfigName : string ) : string {
35+ const sourceConfig = join ( testPath , wranglerConfigName ) ;
36+ const viteConfig = [ 'vite.config.ts' , 'vite.config.mts' , 'vite.config.js' , 'vite.config.mjs' ]
37+ . map ( name => join ( testPath , name ) )
38+ . find ( existsSync ) ;
39+
40+ // No Vite config → serve the source wrangler config unchanged (existing path).
41+ if ( ! viteConfig ) {
42+ return sourceConfig ;
43+ }
44+
45+ const result = spawnSync ( 'vite' , [ 'build' ] , { cwd : testPath , stdio : process . env . DEBUG ? 'inherit' : 'ignore' } ) ;
46+ if ( result . status !== 0 ) {
47+ throw new Error ( `vite build failed for ${ testPath } (exit code ${ result . status } )` ) ;
48+ }
49+
50+ // `@cloudflare/vite-plugin` emits one directory per worker under `dist/`, each
51+ // containing a resolved `wrangler.json`. Match the one whose original config is
52+ // this worker's source config so multi-worker suites map correctly.
53+ const distDir = join ( testPath , 'dist' ) ;
54+ const builtConfig = readdirSync ( distDir , { withFileTypes : true } )
55+ . filter ( entry => entry . isDirectory ( ) )
56+ . map ( entry => join ( distDir , entry . name , 'wrangler.json' ) )
57+ . find ( configPath => existsSync ( configPath ) && builtFromSource ( configPath , sourceConfig ) ) ;
58+
59+ if ( ! builtConfig ) {
60+ throw new Error ( `Could not locate a Vite-built wrangler config for ${ sourceConfig } under ${ distDir } ` ) ;
61+ }
62+ return builtConfig ;
63+ }
64+
65+ /** Whether a generated `wrangler.json` was built from the given source config. */
66+ function builtFromSource ( builtConfigPath : string , sourceConfigPath : string ) : boolean {
67+ try {
68+ const built = JSON . parse ( readFileSync ( builtConfigPath , 'utf8' ) ) as { userConfigPath ?: string ; configPath ?: string } ;
69+ return built . userConfigPath === sourceConfigPath || built . configPath === sourceConfigPath ;
70+ } catch {
71+ return false ;
72+ }
73+ }
74+
2175// Wrangler can report "Ready" before it can actually handle requests.
2276// This retries fetch on connection errors and transient 500 responses to handle this race condition.
2377// The budget (maxRetries * retryDelayMs) must cover the "ready-but-not-serving" window, which can be
@@ -299,7 +353,7 @@ export function createRunner(...paths: string[]) {
299353 [
300354 'dev' ,
301355 '--config' ,
302- join ( testPath , 'wrangler-sub-worker.jsonc' ) ,
356+ resolveWorkerConfig ( testPath , 'wrangler-sub-worker.jsonc' ) ,
303357 '--show-interactive-dev-session' ,
304358 'false' ,
305359 '--var' ,
@@ -325,7 +379,7 @@ export function createRunner(...paths: string[]) {
325379 [
326380 'dev' ,
327381 '--config' ,
328- join ( testPath , 'wrangler.jsonc' ) ,
382+ resolveWorkerConfig ( testPath , 'wrangler.jsonc' ) ,
329383 '--show-interactive-dev-session' ,
330384 'false' ,
331385 '--var' ,
0 commit comments