@@ -10,6 +10,7 @@ import { runCmdStreaming } from '../utils/exec.ts';
1010import {
1111 AGENT_CDP_PACKAGE ,
1212 buildAgentCdpNpmExecArgs ,
13+ buildAgentCdpPassthroughArgs ,
1314 runAgentCdpCommand ,
1415} from '../cli/commands/agent-cdp.ts' ;
1516
@@ -71,3 +72,111 @@ test('agent-cdp streams through npm exec and returns downstream exit code', asyn
7172 assert . equal ( vi . mocked ( runCmdStreaming ) . mock . calls [ 0 ] ?. [ 2 ] ?. env , env ) ;
7273 assert . equal ( vi . mocked ( runCmdStreaming ) . mock . calls [ 0 ] ?. [ 2 ] ?. allowFailure , true ) ;
7374} ) ;
75+
76+ test ( 'agent-cdp injects remote Metro public url for target discovery' , async ( ) => {
77+ const args = buildAgentCdpPassthroughArgs ( [ 'target' , 'list' ] , {
78+ flags : {
79+ leaseBackend : 'android-instance' ,
80+ metroProxyBaseUrl : 'https://bridge.example.test' ,
81+ metroPublicBaseUrl : 'http://127.0.0.1:8081/' ,
82+ } ,
83+ runtime : {
84+ platform : 'android' ,
85+ bundleUrl :
86+ 'https://bridge.example.test/api/metro/runtimes/runtime-1/index.bundle?platform=android&dev=true' ,
87+ } ,
88+ } ) ;
89+
90+ assert . deepEqual ( args , [ 'target' , 'list' , '--url' , 'http://127.0.0.1:8081' ] ) ;
91+ } ) ;
92+
93+ test ( 'agent-cdp falls back to prepared remote runtime url for target discovery' , ( ) => {
94+ const args = buildAgentCdpPassthroughArgs ( [ 'target' , 'list' ] , {
95+ flags : {
96+ leaseBackend : 'android-instance' ,
97+ metroProxyBaseUrl : 'https://bridge.example.test' ,
98+ } ,
99+ runtime : {
100+ platform : 'android' ,
101+ bundleUrl :
102+ 'https://bridge.example.test/api/metro/runtimes/runtime-1/index.bundle?platform=android&dev=true' ,
103+ } ,
104+ } ) ;
105+
106+ assert . deepEqual ( args , [
107+ 'target' ,
108+ 'list' ,
109+ '--url' ,
110+ 'https://bridge.example.test/api/metro/runtimes/runtime-1' ,
111+ ] ) ;
112+ } ) ;
113+
114+ test ( 'agent-cdp preserves explicit target url for remote sessions' , ( ) => {
115+ const args = buildAgentCdpPassthroughArgs (
116+ [ 'target' , 'select' , 'react-native:a:b' , '--url' , 'https://custom.example.test' ] ,
117+ {
118+ flags : {
119+ leaseBackend : 'ios-instance' ,
120+ metroProxyBaseUrl : 'https://bridge.example.test' ,
121+ } ,
122+ runtime : {
123+ platform : 'ios' ,
124+ bundleUrl : 'https://bridge.example.test/api/metro/runtimes/runtime-1/index.bundle' ,
125+ } ,
126+ } ,
127+ ) ;
128+
129+ assert . deepEqual ( args , [
130+ 'target' ,
131+ 'select' ,
132+ 'react-native:a:b' ,
133+ '--url' ,
134+ 'https://custom.example.test' ,
135+ ] ) ;
136+ } ) ;
137+
138+ test ( 'agent-cdp rejects remote bridge target discovery without runtime url' , ( ) => {
139+ assert . throws (
140+ ( ) =>
141+ buildAgentCdpPassthroughArgs ( [ 'target' , 'list' ] , {
142+ flags : {
143+ leaseBackend : 'android-instance' ,
144+ metroProxyBaseUrl : 'https://bridge.example.test' ,
145+ } ,
146+ } ) ,
147+ / a g e n t - c d p r e m o t e b r i d g e t a r g e t d i s c o v e r y r e q u i r e s a p r e p a r e d M e t r o r u n t i m e / ,
148+ ) ;
149+ } ) ;
150+
151+ test ( 'agent-cdp passes injected remote target url to npm exec' , async ( ) => {
152+ vi . mocked ( runCmdStreaming ) . mockResolvedValueOnce ( {
153+ exitCode : 0 ,
154+ stdout : '' ,
155+ stderr : '' ,
156+ } ) ;
157+
158+ const exitCode = await runAgentCdpCommand ( [ 'target' , 'list' ] , {
159+ flags : {
160+ leaseBackend : 'ios-instance' ,
161+ metroProxyBaseUrl : 'https://bridge.example.test' ,
162+ } ,
163+ runtime : {
164+ platform : 'ios' ,
165+ bundleUrl : 'https://bridge.example.test/api/metro/runtimes/runtime-2/index.bundle' ,
166+ } ,
167+ } ) ;
168+
169+ assert . equal ( exitCode , 0 ) ;
170+ assert . deepEqual ( vi . mocked ( runCmdStreaming ) . mock . calls [ 0 ] ?. [ 1 ] , [
171+ 'exec' ,
172+ '--yes' ,
173+ '--package' ,
174+ 'agent-cdp@1.6.0' ,
175+ '--' ,
176+ 'agent-cdp' ,
177+ 'target' ,
178+ 'list' ,
179+ '--url' ,
180+ 'https://bridge.example.test/api/metro/runtimes/runtime-2' ,
181+ ] ) ;
182+ } ) ;
0 commit comments