@@ -69,6 +69,9 @@ async function parseXcresultBundle(
6969 if ( ! result . success ) {
7070 throw new Error ( result . error ?? 'Failed to execute xcresulttool' ) ;
7171 }
72+ if ( ! result . output || result . output . trim ( ) . length === 0 ) {
73+ throw new Error ( 'xcresulttool returned no output' ) ;
74+ }
7275
7376 // Parse JSON response and format as human-readable
7477 const summaryData = JSON . parse ( result . output ) as Record < string , unknown > ;
@@ -163,9 +166,19 @@ export async function testDeviceLogic(
163166 `Starting test run for scheme ${ params . scheme } on platform ${ params . platform ?? 'iOS' } (internal)` ,
164167 ) ;
165168
169+ let tempDir : string | undefined ;
170+ const cleanup = async ( ) : Promise < void > => {
171+ if ( ! tempDir ) return ;
172+ try {
173+ await fileSystemExecutor . rm ( tempDir , { recursive : true , force : true } ) ;
174+ } catch ( cleanupError ) {
175+ log ( 'warn' , `Failed to clean up temporary directory: ${ cleanupError } ` ) ;
176+ }
177+ } ;
178+
166179 try {
167180 // Create temporary directory for xcresult bundle
168- const tempDir = await fileSystemExecutor . mkdtemp (
181+ tempDir = await fileSystemExecutor . mkdtemp (
169182 join ( fileSystemExecutor . tmpdir ( ) , 'xcodebuild-test-' ) ,
170183 ) ;
171184 const resultBundlePath = join ( tempDir , 'TestResults.xcresult' ) ;
@@ -214,7 +227,7 @@ export async function testDeviceLogic(
214227 log ( 'info' , 'Successfully parsed xcresult bundle' ) ;
215228
216229 // Clean up temporary directory
217- await fileSystemExecutor . rm ( tempDir , { recursive : true , force : true } ) ;
230+ await cleanup ( ) ;
218231
219232 // Return combined result - preserve isError from testResult (test failures should be marked as errors)
220233 return {
@@ -231,19 +244,16 @@ export async function testDeviceLogic(
231244 // If parsing fails, return original test result
232245 log ( 'warn' , `Failed to parse xcresult bundle: ${ parseError } ` ) ;
233246
234- // Clean up temporary directory even if parsing fails
235- try {
236- await fileSystemExecutor . rm ( tempDir , { recursive : true , force : true } ) ;
237- } catch ( cleanupError ) {
238- log ( 'warn' , `Failed to clean up temporary directory: ${ cleanupError } ` ) ;
239- }
247+ await cleanup ( ) ;
240248
241249 return testResult ;
242250 }
243251 } catch ( error ) {
244252 const errorMessage = error instanceof Error ? error . message : String ( error ) ;
245253 log ( 'error' , `Error during test run: ${ errorMessage } ` ) ;
246254 return createTextResponse ( `Error during test run: ${ errorMessage } ` , true ) ;
255+ } finally {
256+ await cleanup ( ) ;
247257 }
248258}
249259
@@ -254,13 +264,13 @@ export default {
254264 schema : baseSchemaObject . shape ,
255265 handler : createTypedTool < TestDeviceParams > (
256266 testDeviceSchema as z . ZodType < TestDeviceParams > ,
257- ( params : TestDeviceParams ) => {
267+ ( params : TestDeviceParams , executor : CommandExecutor ) => {
258268 return testDeviceLogic (
259269 {
260270 ...params ,
261271 platform : params . platform ?? 'iOS' ,
262272 } ,
263- getDefaultCommandExecutor ( ) ,
273+ executor ,
264274 getDefaultFileSystemExecutor ( ) ,
265275 ) ;
266276 } ,
0 commit comments