@@ -22,6 +22,20 @@ const SHUTDOWN_JSON = JSON.stringify({
2222} ) ;
2323
2424const EMPTY_JSON = JSON . stringify ( { devices : { } } ) ;
25+ const ESCAPED_NAME_JSON = JSON . stringify ( {
26+ devices : {
27+ 'com.apple.CoreSimulator.SimRuntime.iOS-17-0' : [
28+ { udid : 'escaped-uuid' , name : 'Test\\Device"' , state : 'Booted' } ,
29+ ] ,
30+ } ,
31+ } ) ;
32+ const PREFIX_NAME_JSON = JSON . stringify ( {
33+ devices : {
34+ 'com.apple.CoreSimulator.SimRuntime.iOS-17-0' : [
35+ { udid : 'prefix-uuid' , name : 'iPhone 15' , state : 'Booted' } ,
36+ ] ,
37+ } ,
38+ } ) ;
2539
2640type Call = { command : string [ ] } ;
2741
@@ -87,6 +101,36 @@ describe('sendKeyboardShortcut', () => {
87101 expect ( keystrokeScript ) . toContain ( 'shift down' ) ;
88102 } ) ;
89103
104+ it ( 'escapes backslashes before embedding simulator names in the focus AppleScript' , async ( ) => {
105+ const { executor, calls } = makeFifoExecutor ( [
106+ { success : true , output : ESCAPED_NAME_JSON } ,
107+ { success : true , output : '' } ,
108+ { success : true , output : 'OK' } ,
109+ { success : true , output : '' } ,
110+ ] ) ;
111+
112+ const result = await sendKeyboardShortcut ( 'escaped-uuid' , 'software-keyboard' , executor ) ;
113+
114+ expect ( result . success ) . toBe ( true ) ;
115+ expect ( calls [ 2 ] . command [ 2 ] ) . toContain ( 'Test\\\\Device\\"' ) ;
116+ } ) ;
117+
118+ it ( 'matches the simulator window by exact title or runtime suffix instead of substring contains' , async ( ) => {
119+ const { executor, calls } = makeFifoExecutor ( [
120+ { success : true , output : PREFIX_NAME_JSON } ,
121+ { success : true , output : '' } ,
122+ { success : true , output : 'OK' } ,
123+ { success : true , output : '' } ,
124+ ] ) ;
125+
126+ const result = await sendKeyboardShortcut ( 'prefix-uuid' , 'software-keyboard' , executor ) ;
127+
128+ expect ( result . success ) . toBe ( true ) ;
129+ expect ( calls [ 2 ] . command [ 2 ] ) . toContain ( 'title is "iPhone 15"' ) ;
130+ expect ( calls [ 2 ] . command [ 2 ] ) . toContain ( 'title starts with "iPhone 15 –"' ) ;
131+ expect ( calls [ 2 ] . command [ 2 ] ) . not . toContain ( 'title contains' ) ;
132+ } ) ;
133+
90134 it ( 'errors when simulator UUID is not found' , async ( ) => {
91135 const { executor, calls } = makeFifoExecutor ( [ { success : true , output : EMPTY_JSON } ] ) ;
92136
0 commit comments