@@ -121,6 +121,98 @@ test('boot succeeds for supported device in session', async () => {
121121 }
122122} ) ;
123123
124+ test ( 'open URL on existing iOS session clears stale app bundle id' , async ( ) => {
125+ const sessionStore = makeSessionStore ( ) ;
126+ const sessionName = 'ios-session' ;
127+ sessionStore . set (
128+ sessionName ,
129+ {
130+ ...makeSession ( sessionName , {
131+ platform : 'ios' ,
132+ id : 'sim-1' ,
133+ name : 'iPhone 15' ,
134+ kind : 'simulator' ,
135+ booted : true ,
136+ } ) ,
137+ appBundleId : 'com.example.old' ,
138+ appName : 'Old App' ,
139+ } ,
140+ ) ;
141+
142+ let dispatchedContext : Record < string , unknown > | undefined ;
143+ const response = await handleSessionCommands ( {
144+ req : {
145+ token : 't' ,
146+ session : sessionName ,
147+ command : 'open' ,
148+ positionals : [ 'https://example.com/path' ] ,
149+ flags : { } ,
150+ } ,
151+ sessionName,
152+ logPath : path . join ( os . tmpdir ( ) , 'daemon.log' ) ,
153+ sessionStore,
154+ invoke : noopInvoke ,
155+ dispatch : async ( _device , _command , _positionals , _out , context ) => {
156+ dispatchedContext = context as Record < string , unknown > | undefined ;
157+ return { } ;
158+ } ,
159+ ensureReady : async ( ) => { } ,
160+ } ) ;
161+
162+ assert . ok ( response ) ;
163+ assert . equal ( response ?. ok , true ) ;
164+ const updated = sessionStore . get ( sessionName ) ;
165+ assert . equal ( updated ?. appBundleId , undefined ) ;
166+ assert . equal ( updated ?. appName , 'https://example.com/path' ) ;
167+ assert . equal ( dispatchedContext ?. appBundleId , undefined ) ;
168+ } ) ;
169+
170+ test ( 'open app on existing iOS session resolves and stores bundle id' , async ( ) => {
171+ const sessionStore = makeSessionStore ( ) ;
172+ const sessionName = 'ios-session' ;
173+ sessionStore . set (
174+ sessionName ,
175+ {
176+ ...makeSession ( sessionName , {
177+ platform : 'ios' ,
178+ id : 'sim-1' ,
179+ name : 'iPhone 15' ,
180+ kind : 'simulator' ,
181+ booted : true ,
182+ } ) ,
183+ appBundleId : 'com.example.old' ,
184+ appName : 'Old App' ,
185+ } ,
186+ ) ;
187+
188+ let dispatchedContext : Record < string , unknown > | undefined ;
189+ const response = await handleSessionCommands ( {
190+ req : {
191+ token : 't' ,
192+ session : sessionName ,
193+ command : 'open' ,
194+ positionals : [ 'settings' ] ,
195+ flags : { } ,
196+ } ,
197+ sessionName,
198+ logPath : path . join ( os . tmpdir ( ) , 'daemon.log' ) ,
199+ sessionStore,
200+ invoke : noopInvoke ,
201+ dispatch : async ( _device , _command , _positionals , _out , context ) => {
202+ dispatchedContext = context as Record < string , unknown > | undefined ;
203+ return { } ;
204+ } ,
205+ ensureReady : async ( ) => { } ,
206+ } ) ;
207+
208+ assert . ok ( response ) ;
209+ assert . equal ( response ?. ok , true ) ;
210+ const updated = sessionStore . get ( sessionName ) ;
211+ assert . equal ( updated ?. appBundleId , 'com.apple.Preferences' ) ;
212+ assert . equal ( updated ?. appName , 'settings' ) ;
213+ assert . equal ( dispatchedContext ?. appBundleId , 'com.apple.Preferences' ) ;
214+ } ) ;
215+
124216test ( 'open --relaunch closes and reopens active session app' , async ( ) => {
125217 const sessionStore = makeSessionStore ( ) ;
126218 const sessionName = 'android-session' ;
@@ -164,6 +256,30 @@ test('open --relaunch closes and reopens active session app', async () => {
164256 assert . deepEqual ( calls [ 1 ] , { command : 'open' , positionals : [ 'com.example.app' ] } ) ;
165257} ) ;
166258
259+ test ( 'open --relaunch rejects URL targets' , async ( ) => {
260+ const sessionStore = makeSessionStore ( ) ;
261+ const response = await handleSessionCommands ( {
262+ req : {
263+ token : 't' ,
264+ session : 'default' ,
265+ command : 'open' ,
266+ positionals : [ 'https://example.com/path' ] ,
267+ flags : { relaunch : true } ,
268+ } ,
269+ sessionName : 'default' ,
270+ logPath : path . join ( os . tmpdir ( ) , 'daemon.log' ) ,
271+ sessionStore,
272+ invoke : noopInvoke ,
273+ } ) ;
274+
275+ assert . ok ( response ) ;
276+ assert . equal ( response ?. ok , false ) ;
277+ if ( response && ! response . ok ) {
278+ assert . equal ( response . error . code , 'INVALID_ARGS' ) ;
279+ assert . match ( response . error . message , / d o e s n o t s u p p o r t U R L t a r g e t s / i) ;
280+ }
281+ } ) ;
282+
167283test ( 'open --relaunch fails without app when no session exists' , async ( ) => {
168284 const sessionStore = makeSessionStore ( ) ;
169285 const response = await handleSessionCommands ( {
0 commit comments