@@ -301,6 +301,185 @@ test('formatSnapshotText keeps zero-height visible nodes out of off-screen summa
301301 assert . match ( text , / \[ o f f - s c r e e n b e l o w \] 1 i n t e r a c t i v e i t e m : " L a t e r " / ) ;
302302} ) ;
303303
304+ test ( 'formatSnapshotText collapses inactive Android helper nodes in human output' , ( ) => {
305+ const nodes = [
306+ {
307+ ref : 'e1' ,
308+ index : 0 ,
309+ depth : 0 ,
310+ type : 'Window' ,
311+ rect : { x : 0 , y : 0 , width : 390 , height : 844 } ,
312+ } ,
313+ {
314+ ref : 'e2' ,
315+ index : 1 ,
316+ depth : 1 ,
317+ parentIndex : 0 ,
318+ type : 'android.widget.Button' ,
319+ label : 'Alice, Today, filed the expense' ,
320+ rect : { x : 0 , y : 420 , width : 390 , height : 96 } ,
321+ hittable : true ,
322+ } ,
323+ {
324+ ref : 'e3' ,
325+ index : 2 ,
326+ depth : 2 ,
327+ parentIndex : 1 ,
328+ type : 'android.widget.Button' ,
329+ label : 'alice@example.com' ,
330+ rect : { x : 16 , y : 432 , width : 48 , height : 48 } ,
331+ hittable : true ,
332+ } ,
333+ {
334+ ref : 'e4' ,
335+ index : 3 ,
336+ depth : 2 ,
337+ parentIndex : 1 ,
338+ type : 'android.widget.Button' ,
339+ label : 'alice@example.com' ,
340+ rect : { x : 80 , y : 432 , width : 120 , height : 48 } ,
341+ hittable : true ,
342+ } ,
343+ {
344+ ref : 'e5' ,
345+ index : 4 ,
346+ depth : 3 ,
347+ parentIndex : 3 ,
348+ type : 'android.widget.TextView' ,
349+ label : 'Alice' ,
350+ rect : { x : 80 , y : 432 , width : 120 , height : 48 } ,
351+ } ,
352+ {
353+ ref : 'e6' ,
354+ index : 5 ,
355+ depth : 1 ,
356+ parentIndex : 0 ,
357+ type : 'android.widget.Button' ,
358+ label : 'Invisible stale action' ,
359+ rect : { x : 0 , y : 160 , width : 390 , height : 0 } ,
360+ hittable : true ,
361+ } ,
362+ {
363+ ref : 'e7' ,
364+ index : 6 ,
365+ depth : 1 ,
366+ parentIndex : 0 ,
367+ type : 'android.widget.EditText' ,
368+ label : 'Write something...' ,
369+ identifier : 'composer' ,
370+ rect : { x : 72 , y : 760 , width : 240 , height : 44 } ,
371+ hittable : true ,
372+ } ,
373+ {
374+ ref : 'e8' ,
375+ index : 7 ,
376+ depth : 1 ,
377+ parentIndex : 0 ,
378+ type : 'android.view.View' ,
379+ label : 'Dashboard' ,
380+ rect : { x : 0 , y : 720 , width : 78 , height : 96 } ,
381+ hittable : true ,
382+ } ,
383+ {
384+ ref : 'e9' ,
385+ index : 8 ,
386+ depth : 2 ,
387+ parentIndex : 7 ,
388+ type : 'android.widget.TextView' ,
389+ label : 'Dashboard' ,
390+ rect : { x : 20 , y : 780 , width : 40 , height : 24 } ,
391+ } ,
392+ {
393+ ref : 'e10' ,
394+ index : 9 ,
395+ depth : 1 ,
396+ parentIndex : 0 ,
397+ type : 'android.view.View' ,
398+ label : 'Messages. Your review is required' ,
399+ rect : { x : 78 , y : 720 , width : 78 , height : 96 } ,
400+ hittable : true ,
401+ } ,
402+ {
403+ ref : 'e11' ,
404+ index : 10 ,
405+ depth : 2 ,
406+ parentIndex : 9 ,
407+ type : 'android.widget.TextView' ,
408+ label : 'Messages' ,
409+ rect : { x : 98 , y : 780 , width : 40 , height : 24 } ,
410+ } ,
411+ {
412+ ref : 'e12' ,
413+ index : 11 ,
414+ depth : 1 ,
415+ parentIndex : 0 ,
416+ type : 'android.view.View' ,
417+ label : 'Billing' ,
418+ rect : { x : 156 , y : 720 , width : 78 , height : 96 } ,
419+ hittable : true ,
420+ } ,
421+ {
422+ ref : 'e13' ,
423+ index : 12 ,
424+ depth : 2 ,
425+ parentIndex : 11 ,
426+ type : 'android.widget.TextView' ,
427+ label : 'Billing' ,
428+ rect : { x : 176 , y : 780 , width : 40 , height : 24 } ,
429+ } ,
430+ {
431+ ref : 'e14' ,
432+ index : 13 ,
433+ depth : 1 ,
434+ parentIndex : 0 ,
435+ type : 'android.view.View' ,
436+ label : 'Profile, My settings.' ,
437+ rect : { x : 312 , y : 720 , width : 78 , height : 96 } ,
438+ hittable : true ,
439+ } ,
440+ {
441+ ref : 'e15' ,
442+ index : 14 ,
443+ depth : 2 ,
444+ parentIndex : 13 ,
445+ type : 'android.widget.TextView' ,
446+ label : 'Profile' ,
447+ rect : { x : 332 , y : 780 , width : 40 , height : 24 } ,
448+ } ,
449+ ] ;
450+ const text = withNoColor ( ( ) =>
451+ formatSnapshotText ( {
452+ nodes,
453+ truncated : false ,
454+ androidSnapshot : { backend : 'android-helper' } ,
455+ } ) ,
456+ ) ;
457+
458+ assert . match ( text , / S n a p s h o t : 4 v i s i b l e n o d e s \( 1 5 t o t a l \) / ) ;
459+ assert . match ( text , / C o l l a p s e d 1 1 i n a c t i v e A n d r o i d h e l p e r n o d e s f r o m t e x t o u t p u t / ) ;
460+ assert . match ( text , / @ e 3 \[ b u t t o n \] " a l i c e @ e x a m p l e \. c o m " / ) ;
461+ assert . doesNotMatch ( text , / @ e 4 \[ b u t t o n \] " a l i c e @ e x a m p l e \. c o m " / ) ;
462+ assert . doesNotMatch ( text , / I n v i s i b l e s t a l e a c t i o n / ) ;
463+ assert . doesNotMatch ( text , / \[ g r o u p \] " D a s h b o a r d " / ) ;
464+ assert . doesNotMatch ( text , / \[ g r o u p \] " M e s s a g e s / ) ;
465+ assert . doesNotMatch ( text , / \[ g r o u p \] " B i l l i n g " / ) ;
466+ assert . doesNotMatch ( text , / \[ g r o u p \] " P r o f i l e / ) ;
467+ assert . doesNotMatch ( text , / p o s s i b l e r e p e a t e d n a v s u b t r e e / ) ;
468+
469+ const raw = withNoColor ( ( ) =>
470+ formatSnapshotText (
471+ {
472+ nodes,
473+ truncated : false ,
474+ androidSnapshot : { backend : 'android-helper' } ,
475+ } ,
476+ { raw : true } ,
477+ ) ,
478+ ) ;
479+ assert . match ( raw , / " I n v i s i b l e s t a l e a c t i o n " / ) ;
480+ assert . match ( raw , / " M e s s a g e s \. Y o u r r e v i e w i s r e q u i r e d " / ) ;
481+ } ) ;
482+
304483test ( 'formatSnapshotText renders explicit hidden scroll-area content hints' , ( ) => {
305484 const text = withNoColor ( ( ) =>
306485 formatSnapshotText ( {
0 commit comments