@@ -56,7 +56,25 @@ describe('createUnifiedLogEvent', () => {
5656 } ) ;
5757 } ) ;
5858
59- it ( 'detects Swift fatal errors as crash signals' , ( ) => {
59+ it ( 'detects Swift fatal errors from idevicesyslog with library-qualified process name' , ( ) => {
60+ const event = createUnifiedLogEvent ( {
61+ line : 'Mar 13 12:27:13.724837 HarnessPlayground(libswiftCore.dylib)[21675] <Notice>: HarnessPlayground/AppDelegate.swift:31: Fatal error: Intentional pre-RN startup crash' ,
62+ processNames : [ 'HarnessPlayground' , 'com.harnessplayground' ] ,
63+ } ) ;
64+
65+ expect ( event ) . toMatchObject ( {
66+ type : 'possible_crash' ,
67+ source : 'logs' ,
68+ isConfirmed : true ,
69+ crashDetails : {
70+ source : 'logs' ,
71+ processName : 'HarnessPlayground' ,
72+ pid : 21675 ,
73+ } ,
74+ } ) ;
75+ } ) ;
76+
77+ it ( 'detects Swift fatal errors from simulator logs' , ( ) => {
6078 const event = createUnifiedLogEvent ( {
6179 line : '2026-03-13 10:29:13.868 Df HarnessPlayground[34784:8f92b3] (libswiftCore.dylib) HarnessPlayground/AppDelegate.swift:31: Fatal error: Intentional pre-RN startup crash' ,
6280 processNames : [ 'HarnessPlayground' , 'com.harnessplayground' ] ,
@@ -201,10 +219,10 @@ describe('createIosSimulatorAppMonitor', () => {
201219 vi . spyOn ( simctl , 'collectCrashReports' ) . mockImplementation (
202220 async ( { crashArtifactWriter } ) => [
203221 {
204- artifactType : 'ios-simulator- crash-report' ,
222+ artifactType : 'ios-crash-report' ,
205223 artifactPath :
206224 crashArtifactWriter ?. persistArtifact ( {
207- artifactKind : 'ios-simulator- crash-report' ,
225+ artifactKind : 'ios-crash-report' ,
208226 source : {
209227 kind : 'file' ,
210228 path : sourcePath ,
@@ -251,7 +269,7 @@ describe('createIosSimulatorAppMonitor', () => {
251269 await monitor . stop ( ) ;
252270
253271 expect ( details ) . toMatchObject ( {
254- artifactType : 'ios-simulator- crash-report' ,
272+ artifactType : 'ios-crash-report' ,
255273 summary : 'simulator crash report' ,
256274 } ) ;
257275 expect ( details ?. artifactPath ) . toContain ( '/.harness/crash-reports/' ) ;
@@ -285,7 +303,7 @@ describe('createIosSimulatorAppMonitor', () => {
285303
286304 return [
287305 {
288- artifactType : 'ios-simulator- crash-report' ,
306+ artifactType : 'ios-crash-report' ,
289307 artifactPath : '/tmp/HarnessPlayground.ips' ,
290308 occurredAt : Date . now ( ) ,
291309 processName : 'HarnessPlayground' ,
@@ -315,7 +333,7 @@ describe('createIosSimulatorAppMonitor', () => {
315333
316334 expect ( calls ) . toBe ( 2 ) ;
317335 expect ( details ) . toMatchObject ( {
318- artifactType : 'ios-simulator- crash-report' ,
336+ artifactType : 'ios-crash-report' ,
319337 stackTrace : [ '0 AppDelegate.crashIfRequested() (AppDelegate.swift:31)' ] ,
320338 } ) ;
321339 } ) ;
@@ -402,19 +420,67 @@ describe('createIosDeviceAppMonitor', () => {
402420
403421 const monitor = createIosDeviceAppMonitor ( {
404422 deviceId : 'device-udid' ,
423+ libimobiledeviceUdid : 'hardware-udid' ,
405424 bundleId : 'com.harnessplayground' ,
406425 } ) ;
407426
408427 await monitor . start ( ) ;
409428 await monitor . stop ( ) ;
410429
411- expect ( targetSpy ) . toHaveBeenCalledWith ( 'device -udid' ) ;
430+ expect ( targetSpy ) . toHaveBeenCalledWith ( 'hardware -udid' ) ;
412431 expect ( syslogSpy ) . toHaveBeenCalledWith ( {
413- targetId : 'device -udid' ,
432+ targetId : 'hardware -udid' ,
414433 processNames : [ 'com.harnessplayground' , 'HarnessPlayground' ] ,
415434 } ) ;
416435 } ) ;
417436
437+ it ( 'detects idevicesyslog crash lines with library-qualified process names' , async ( ) => {
438+ vi . spyOn ( libimobiledevice , 'assertLibimobiledeviceTargetAvailable' ) . mockResolvedValue (
439+ undefined
440+ ) ;
441+ vi . spyOn ( libimobiledevice , 'createSyslogProcess' ) . mockReturnValue (
442+ createStreamingSubprocess ( [
443+ {
444+ line : 'Mar 13 12:27:13.724837 HarnessPlayground(libswiftCore.dylib)[21675] <Notice>: HarnessPlayground/AppDelegate.swift:31: Fatal error: Intentional pre-RN startup crash' ,
445+ } ,
446+ ] )
447+ ) ;
448+ vi . spyOn ( libimobiledevice , 'collectCrashReports' ) . mockResolvedValue ( [ ] ) ;
449+ vi . spyOn ( devicectl , 'getAppInfo' ) . mockResolvedValue ( {
450+ bundleIdentifier : 'com.harnessplayground' ,
451+ name : 'HarnessPlayground' ,
452+ version : '1.0' ,
453+ url : '/private/var/HarnessPlayground.app' ,
454+ } ) ;
455+
456+ const events : Array < { type : string } > = [ ] ;
457+ const monitor = createIosDeviceAppMonitor ( {
458+ deviceId : 'device-udid' ,
459+ libimobiledeviceUdid : 'hardware-udid' ,
460+ bundleId : 'com.harnessplayground' ,
461+ } ) ;
462+ monitor . addListener ( ( event ) => {
463+ events . push ( event ) ;
464+ } ) ;
465+
466+ await monitor . start ( ) ;
467+ await new Promise ( ( resolve ) => setTimeout ( resolve , 10 ) ) ;
468+
469+ const details = await monitor . getCrashDetails ( {
470+ pid : 21675 ,
471+ occurredAt : Date . now ( ) ,
472+ } ) ;
473+
474+ await monitor . stop ( ) ;
475+
476+ expect ( events . some ( ( event ) => event . type === 'possible_crash' ) ) . toBe ( true ) ;
477+ expect ( details ) . toMatchObject ( {
478+ source : 'logs' ,
479+ processName : 'HarnessPlayground' ,
480+ pid : 21675 ,
481+ } ) ;
482+ } ) ;
483+
418484 it ( 'still enriches device crashes with pulled crash reports' , async ( ) => {
419485 vi . spyOn ( libimobiledevice , 'assertLibimobiledeviceTargetAvailable' ) . mockResolvedValue (
420486 undefined
@@ -431,10 +497,10 @@ describe('createIosDeviceAppMonitor', () => {
431497 vi . spyOn ( libimobiledevice , 'collectCrashReports' ) . mockImplementation (
432498 async ( { crashArtifactWriter } ) => [
433499 {
434- artifactType : 'ios-libimobiledevice- crash-report' ,
500+ artifactType : 'ios-crash-report' ,
435501 artifactPath :
436502 crashArtifactWriter ?. persistArtifact ( {
437- artifactKind : 'ios-libimobiledevice- crash-report' ,
503+ artifactKind : 'ios-crash-report' ,
438504 source : {
439505 kind : 'file' ,
440506 path : sourcePath ,
@@ -459,6 +525,7 @@ describe('createIosDeviceAppMonitor', () => {
459525
460526 const monitor = createIosDeviceAppMonitor ( {
461527 deviceId : 'device-udid' ,
528+ libimobiledeviceUdid : 'hardware-udid' ,
462529 bundleId : 'com.harnessplayground' ,
463530 crashArtifactWriter : createCrashArtifactWriter ( {
464531 runnerName : 'ios-device' ,
@@ -479,7 +546,7 @@ describe('createIosDeviceAppMonitor', () => {
479546 await monitor . stop ( ) ;
480547
481548 expect ( details ) . toMatchObject ( {
482- artifactType : 'ios-libimobiledevice- crash-report' ,
549+ artifactType : 'ios-crash-report' ,
483550 summary : 'full crash report' ,
484551 } ) ;
485552 expect ( details ?. artifactPath ) . toContain ( '/.harness/crash-reports/' ) ;
0 commit comments