@@ -14,10 +14,10 @@ import type {
1414import { normalize } from '@sentry/core' ;
1515import { createBasicSentryServer } from '@sentry-internal/test-utils' ;
1616import { execSync , spawn , spawnSync } from 'child_process' ;
17- import { existsSync , mkdirSync , readFileSync , rmSync , unlinkSync , writeFileSync } from 'fs' ;
17+ import { existsSync , mkdirSync , readFileSync , rmSync , writeFileSync } from 'fs' ;
1818import { basename , join } from 'path' ;
1919import { inspect } from 'util' ;
20- import { afterAll , beforeAll , describe , test } from 'vitest' ;
20+ import { afterAll , describe , test } from 'vitest' ;
2121import {
2222 assertEnvelopeHeader ,
2323 assertSentryCheckIn ,
@@ -187,38 +187,29 @@ export function createEsmAndCjsTests(
187187 throw new Error ( `Instrument file not found: ${ mjsInstrumentPath } ` ) ;
188188 }
189189
190- // If additionalDependencies are provided, we create a dedicated tmp directory that includes
191- // copied ESM & CJS scenario/instrument files and a nested package.json with those dependencies installed.
192- const useTmpDir = Boolean ( options ?. additionalDependencies && Object . keys ( options . additionalDependencies ) . length > 0 ) ;
193-
194- let tmpDirPath : string | undefined ;
195- let esmScenarioPathForRun = mjsScenarioPath ;
196- let esmInstrumentPathForRun = mjsInstrumentPath ;
197- let cjsScenarioPath = join ( cwd , `tmp_${ scenarioPath . replace ( '.mjs' , '.cjs' ) } ` ) ;
198- let cjsInstrumentPath = join ( cwd , `tmp_${ instrumentPath . replace ( '.mjs' , '.cjs' ) } ` ) ;
199-
200- if ( useTmpDir ) {
201- // Create unique tmp directory within the suite folder
202- const uniqueId = `${ Date . now ( ) . toString ( 36 ) } _${ Math . random ( ) . toString ( 36 ) . slice ( 2 , 8 ) } ` ;
203- tmpDirPath = join ( cwd , `tmp_${ uniqueId } ` ) ;
204- mkdirSync ( tmpDirPath ) ;
205-
206- // Copy ESM files as-is into tmp dir
207- const esmScenarioBasename = basename ( scenarioPath ) ;
208- const esmInstrumentBasename = basename ( instrumentPath ) ;
209- esmScenarioPathForRun = join ( tmpDirPath , esmScenarioBasename ) ;
210- esmInstrumentPathForRun = join ( tmpDirPath , esmInstrumentBasename ) ;
211- writeFileSync ( esmScenarioPathForRun , readFileSync ( mjsScenarioPath , 'utf8' ) ) ;
212- writeFileSync ( esmInstrumentPathForRun , readFileSync ( mjsInstrumentPath , 'utf8' ) ) ;
213-
214- // Pre-create CJS converted files inside tmp dir
215- cjsScenarioPath = join ( tmpDirPath , esmScenarioBasename . replace ( '.mjs' , '.cjs' ) ) ;
216- cjsInstrumentPath = join ( tmpDirPath , esmInstrumentBasename . replace ( '.mjs' , '.cjs' ) ) ;
217- convertEsmFileToCjs ( esmScenarioPathForRun , cjsScenarioPath ) ;
218- convertEsmFileToCjs ( esmInstrumentPathForRun , cjsInstrumentPath ) ;
219-
220- // Create a minimal package.json with requested dependencies
221- const additionalDependencies = options ?. additionalDependencies ?? { } ;
190+ // Create a dedicated tmp directory that includes copied ESM & CJS scenario/instrument files.
191+ // If additionalDependencies are provided, we also create a nested package.json and install them there.
192+ const uniqueId = `${ Date . now ( ) . toString ( 36 ) } _${ Math . random ( ) . toString ( 36 ) . slice ( 2 , 8 ) } ` ;
193+ const tmpDirPath = join ( cwd , `tmp_${ uniqueId } ` ) ;
194+ mkdirSync ( tmpDirPath ) ;
195+
196+ // Copy ESM files as-is into tmp dir
197+ const esmScenarioBasename = basename ( scenarioPath ) ;
198+ const esmInstrumentBasename = basename ( instrumentPath ) ;
199+ const esmScenarioPathForRun = join ( tmpDirPath , esmScenarioBasename ) ;
200+ const esmInstrumentPathForRun = join ( tmpDirPath , esmInstrumentBasename ) ;
201+ writeFileSync ( esmScenarioPathForRun , readFileSync ( mjsScenarioPath , 'utf8' ) ) ;
202+ writeFileSync ( esmInstrumentPathForRun , readFileSync ( mjsInstrumentPath , 'utf8' ) ) ;
203+
204+ // Pre-create CJS converted files inside tmp dir
205+ const cjsScenarioPath = join ( tmpDirPath , esmScenarioBasename . replace ( '.mjs' , '.cjs' ) ) ;
206+ const cjsInstrumentPath = join ( tmpDirPath , esmInstrumentBasename . replace ( '.mjs' , '.cjs' ) ) ;
207+ convertEsmFileToCjs ( esmScenarioPathForRun , cjsScenarioPath ) ;
208+ convertEsmFileToCjs ( esmInstrumentPathForRun , cjsInstrumentPath ) ;
209+
210+ // Create a minimal package.json with requested dependencies (if any) and install them
211+ const additionalDependencies = options ?. additionalDependencies ?? { } ;
212+ if ( Object . keys ( additionalDependencies ) . length > 0 ) {
222213 const packageJson = {
223214 name : 'tmp-integration-test' ,
224215 private : true ,
@@ -228,7 +219,6 @@ export function createEsmAndCjsTests(
228219
229220 writeFileSync ( join ( tmpDirPath , 'package.json' ) , JSON . stringify ( packageJson , null , 2 ) ) ;
230221
231- // Install the requested dependencies using yarn
232222 try {
233223 const deps = Object . entries ( additionalDependencies ) . map ( ( [ name , range ] ) => {
234224 if ( ! range || typeof range !== 'string' ) {
@@ -238,11 +228,30 @@ export function createEsmAndCjsTests(
238228 } ) ;
239229
240230 if ( deps . length > 0 ) {
241- // Run yarn add non-interactively, keep output visible when DEBUG is set
242- spawnSync ( 'yarn' , [ 'add' , '--non-interactive' , ...deps ] , {
231+ const result = spawnSync ( 'yarn' , [ 'add' , '--non-interactive' , ...deps ] , {
243232 cwd : tmpDirPath ,
244- stdio : process . env . DEBUG ? 'inherit' : 'ignore ',
233+ encoding : 'utf8 ',
245234 } ) ;
235+
236+ if ( process . env . DEBUG ) {
237+ // eslint-disable-next-line no-console
238+ console . log ( '[additionalDependencies]' , deps . join ( ' ' ) ) ;
239+ // eslint-disable-next-line no-console
240+ console . log ( '[yarn stdout]' , result . stdout ) ;
241+ // eslint-disable-next-line no-console
242+ console . log ( '[yarn stderr]' , result . stderr ) ;
243+ }
244+
245+ if ( result . error ) {
246+ throw new Error ( `Failed to install additionalDependencies in tmp dir ${ tmpDirPath } : ${ result . error . message } ` ) ;
247+ }
248+ if ( typeof result . status === 'number' && result . status !== 0 ) {
249+ throw new Error (
250+ `Failed to install additionalDependencies in tmp dir ${ tmpDirPath } (exit ${ result . status } ):\n${
251+ result . stderr || result . stdout || '(no output)'
252+ } `,
253+ ) ;
254+ }
246255 }
247256 } catch ( e ) {
248257 // eslint-disable-next-line no-console
@@ -257,40 +266,17 @@ export function createEsmAndCjsTests(
257266 } ) ;
258267
259268 describe ( 'cjs' , ( ) => {
260- if ( ! useTmpDir ) {
261- beforeAll ( ( ) => {
262- // For the CJS runner, we create some temporary files...
263- convertEsmFileToCjs ( mjsScenarioPath , cjsScenarioPath ) ;
264- convertEsmFileToCjs ( mjsInstrumentPath , cjsInstrumentPath ) ;
265- } ) ;
266-
267- afterAll ( ( ) => {
268- try {
269- unlinkSync ( cjsInstrumentPath ) ;
270- } catch {
271- // Ignore errors here
272- }
273- try {
274- unlinkSync ( cjsScenarioPath ) ;
275- } catch {
276- // Ignore errors here
269+ // Clean up the tmp directory once CJS tests are finished
270+ afterAll ( ( ) => {
271+ try {
272+ rmSync ( tmpDirPath , { recursive : true , force : true } ) ;
273+ } catch {
274+ if ( process . env . DEBUG ) {
275+ // eslint-disable-next-line no-console
276+ console . error ( `Failed to remove tmp dir: ${ tmpDirPath } ` ) ;
277277 }
278- } ) ;
279- } else {
280- // When using a tmp dir, clean up the entire directory once CJS tests are finished
281- afterAll ( ( ) => {
282- if ( tmpDirPath ) {
283- try {
284- rmSync ( tmpDirPath , { recursive : true , force : true } ) ;
285- } catch {
286- if ( process . env . DEBUG ) {
287- // eslint-disable-next-line no-console
288- console . error ( `Failed to remove tmp dir: ${ tmpDirPath } ` ) ;
289- }
290- }
291- }
292- } ) ;
293- }
278+ }
279+ } ) ;
294280
295281 const testFn = options ?. failsOnCjs ? test . fails : test ;
296282 callback ( ( ) => createRunner ( cjsScenarioPath ) . withFlags ( '--require' , cjsInstrumentPath ) , testFn , 'cjs' ) ;
0 commit comments