@@ -151,6 +151,85 @@ test('invokeMaestroAssertVisible uses snapshot resolution for short iOS assertio
151151 assert . deepEqual ( calls , [ [ 'snapshot' , [ ] ] ] ) ;
152152} ) ;
153153
154+ test ( 'invokeMaestroAssertVisible falls back to raw snapshot shaping when optimized snapshot misses' , async ( ) => {
155+ const snapshotFlags : Array < DaemonRequest [ 'flags' ] > = [ ] ;
156+ const response = await invokeMaestroAssertVisible ( {
157+ baseReq : {
158+ token : 't' ,
159+ session : 's' ,
160+ flags : { platform : 'ios' } ,
161+ } ,
162+ positionals : [ 'id="chat"' , '1000' ] ,
163+ invoke : async ( req ) : Promise < DaemonResponse > => {
164+ if ( req . command === 'snapshot' ) {
165+ snapshotFlags . push ( req . flags ) ;
166+ return {
167+ ok : true ,
168+ data :
169+ req . flags ?. snapshotRaw === true
170+ ? snapshot ( [ node ( 'Chat' , { identifier : 'chat' } ) ] )
171+ : snapshot ( [ ] ) ,
172+ } ;
173+ }
174+ return { ok : false , error : { code : 'UNEXPECTED_COMMAND' , message : req . command } } ;
175+ } ,
176+ } ) ;
177+
178+ assert . equal ( response . ok , true ) ;
179+ assert . equal ( snapshotFlags . length , 2 ) ;
180+ assert . equal ( snapshotFlags [ 0 ] ?. snapshotRaw , undefined ) ;
181+ assert . equal ( snapshotFlags [ 1 ] ?. snapshotRaw , true ) ;
182+ assert . equal ( snapshotFlags [ 1 ] ?. snapshotForceFull , undefined ) ;
183+ } ) ;
184+
185+ test ( 'invokeMaestroAssertVisible does not use raw fallback for Android identifiers' , async ( ) => {
186+ const snapshotFlags : Array < DaemonRequest [ 'flags' ] > = [ ] ;
187+ const response = await invokeMaestroAssertVisible ( {
188+ baseReq : {
189+ token : 't' ,
190+ session : 's' ,
191+ flags : { platform : 'android' } ,
192+ } ,
193+ positionals : [ 'id="album-0"' , '1000' ] ,
194+ invoke : async ( req ) : Promise < DaemonResponse > => {
195+ if ( req . command === 'snapshot' ) {
196+ snapshotFlags . push ( req . flags ) ;
197+ return {
198+ ok : true ,
199+ data : snapshot ( [ node ( 'Album item' , { identifier : 'album-0' } ) ] ) ,
200+ } ;
201+ }
202+ return { ok : false , error : { code : 'UNEXPECTED_COMMAND' , message : req . command } } ;
203+ } ,
204+ } ) ;
205+
206+ assert . equal ( response . ok , true ) ;
207+ assert . equal ( snapshotFlags . length , 1 ) ;
208+ assert . equal ( snapshotFlags [ 0 ] ?. snapshotRaw , undefined ) ;
209+ } ) ;
210+
211+ test ( 'invokeMaestroAssertVisible does not use Android raw fallback for generated text selectors' , async ( ) => {
212+ const snapshotFlags : Array < DaemonRequest [ 'flags' ] > = [ ] ;
213+ const response = await invokeMaestroAssertVisible ( {
214+ baseReq : {
215+ token : 't' ,
216+ session : 's' ,
217+ flags : { platform : 'android' } ,
218+ } ,
219+ positionals : [ 'label="Chat" || text="Chat" || id="Chat"' , '0' ] ,
220+ invoke : async ( req ) : Promise < DaemonResponse > => {
221+ if ( req . command === 'snapshot' ) {
222+ snapshotFlags . push ( req . flags ) ;
223+ return { ok : true , data : snapshot ( [ ] ) } ;
224+ }
225+ return { ok : false , error : { code : 'UNEXPECTED_COMMAND' , message : req . command } } ;
226+ } ,
227+ } ) ;
228+
229+ assert . equal ( response . ok , false ) ;
230+ assert . equal ( snapshotFlags . some ( ( flags ) => flags ?. snapshotRaw === true ) , false ) ;
231+ } ) ;
232+
154233test ( 'invokeMaestroAssertVisible treats an elapsed ellipsis loading gate as already past loading' , async ( ) => {
155234 vi . spyOn ( Date , 'now' ) . mockReturnValueOnce ( 0 ) . mockReturnValueOnce ( 0 ) . mockReturnValueOnce ( 250 ) ;
156235
0 commit comments