@@ -1169,10 +1169,11 @@ test('snapshotAndroid re-probes helper install after helper capture failure', as
11691169} ) ;
11701170
11711171test ( 'snapshotAndroid preserves hidden scroll content hints in interactive snapshots' , async ( ) => {
1172+ // Mid-scroll: Android offers both scroll actions, so the helper reports both directions.
11721173 const xml = `<?xml version="1.0" encoding="UTF-8"?>
11731174<hierarchy rotation="0">
11741175 <node class="android.widget.FrameLayout" bounds="[0,0][390,844]" clickable="false" focusable="false">
1175- <node class="android.widget.ScrollView" content-desc="Messages" bounds="[0,100][390,600]" clickable="false" focusable="false">
1176+ <node class="android.widget.ScrollView" content-desc="Messages" scrollable="true" can-scroll-forward="true" can-scroll-backward="true" bounds="[0,100][390,600]" clickable="false" focusable="false">
11761177 <node class="android.view.ViewGroup" bounds="[0,100][390,600]" clickable="false" focusable="false">
11771178 <node class="android.widget.Button" text="Earlier message" bounds="[0,100][390,268]" clickable="true" focusable="true" />
11781179 <node class="android.widget.Button" text="Visible message" bounds="[0,268][390,436]" clickable="true" focusable="true" />
@@ -1181,15 +1182,8 @@ test('snapshotAndroid preserves hidden scroll content hints in interactive snaps
11811182 </node>
11821183 </node>
11831184</hierarchy>` ;
1184- const dump = [
1185- ' com.facebook.react.views.scroll.ReactScrollView{d32a800 VFED.V... ........ 0,0-390,500 #4b2}' ,
1186- ' com.facebook.react.views.view.ReactViewGroup{77d31ae V.E...... ........ 0,0-390,1000 #4b0}' ,
1187- ' com.facebook.react.views.view.ReactViewGroup{a V.E...... ........ 0,300-390,468 #1}' ,
1188- ' com.facebook.react.views.view.ReactViewGroup{b V.E...... ........ 0,468-390,636 #2}' ,
1189- ' com.facebook.react.views.view.ReactViewGroup{c V.E...... ........ 0,636-390,804 #3}' ,
1190- ] . join ( '\n' ) ;
11911185
1192- const result = await snapshotAndroidWithHelper ( androidSnapshotHelperAdb ( xml , dump ) , {
1186+ const result = await snapshotAndroidWithHelper ( androidSnapshotHelperAdb ( xml ) , {
11931187 interactiveOnly : true ,
11941188 } ) ;
11951189 const scrollArea = result . nodes . find ( ( node ) => node . type === 'android.widget.ScrollView' ) ;
@@ -1240,7 +1234,11 @@ test('snapshotAndroid skips activity dump when snapshot has no scrollable nodes'
12401234 assert . equal ( result . nodes [ 0 ] ?. label , 'Continue' ) ;
12411235} ) ;
12421236
1243- test ( 'snapshotAndroid caps the activity-top scroll-hint probe at 1.5s' , async ( ) => {
1237+ // A scrollable-typed node that Android does not report as scrollable (a list short enough to fit)
1238+ // is the one shape that still reached `dumpsys activity top` after #1288 capped it. The probe can
1239+ // only ever run when the helper reported no scroll actions at all — which is exactly when there is
1240+ // no scrollable content to describe — so it must not run, at any budget (#1270).
1241+ test ( 'snapshotAndroid never probes the activity dump for scroll hints' , async ( ) => {
12441242 const xml = `<?xml version="1.0" encoding="UTF-8"?>
12451243<hierarchy rotation="0">
12461244 <node class="android.widget.FrameLayout" bounds="[0,0][390,844]" clickable="false" focusable="false">
@@ -1249,41 +1247,19 @@ test('snapshotAndroid caps the activity-top scroll-hint probe at 1.5s', async ()
12491247 </node>
12501248 </node>
12511249</hierarchy>` ;
1252- const activityTimeouts : Array < number | undefined > = [ ] ;
1253- const helperAdb = createHelperAdb ( {
1254- instrument : async ( ) => ( { exitCode : 0 , stdout : helperOutput ( xml ) , stderr : '' } ) ,
1255- activity : async ( _args , options ) => {
1256- activityTimeouts . push ( options ?. timeoutMs ) ;
1257- return { exitCode : 0 , stdout : '' , stderr : '' } ;
1258- } ,
1259- } ) ;
1260-
1261- await snapshotAndroidWithHelper ( helperAdb ) ;
1262-
1263- assert . deepEqual ( activityTimeouts , [ 1500 ] ) ;
1264- } ) ;
1265-
1266- test ( 'snapshotAndroid skips the activity-top probe when the helper XML already carries scroll-action attributes' , async ( ) => {
1267- const xml = `<?xml version="1.0" encoding="UTF-8"?>
1268- <hierarchy rotation="0">
1269- <node class="android.widget.FrameLayout" bounds="[0,0][390,844]" clickable="false" focusable="false">
1270- <node class="android.widget.ScrollView" scrollable="true" can-scroll-forward="true" can-scroll-backward="false" bounds="[0,100][390,600]" clickable="false" focusable="false">
1271- <node class="android.widget.Button" text="Continue" bounds="[20,120][200,180]" clickable="true" focusable="true" />
1272- </node>
1273- </node>
1274- </hierarchy>` ;
1275- let activityDumpCalled = false ;
1250+ const activityDumpCalls : string [ ] [ ] = [ ] ;
12761251 const helperAdb = createHelperAdb ( {
12771252 instrument : async ( ) => ( { exitCode : 0 , stdout : helperOutput ( xml ) , stderr : '' } ) ,
1278- activity : async ( ) => {
1279- activityDumpCalled = true ;
1253+ activity : async ( args ) => {
1254+ activityDumpCalls . push ( args ) ;
12801255 return { exitCode : 0 , stdout : '' , stderr : '' } ;
12811256 } ,
12821257 } ) ;
12831258
12841259 await snapshotAndroidWithHelper ( helperAdb ) ;
1260+ await snapshotAndroidWithHelper ( helperAdb , { interactiveOnly : true } ) ;
12851261
1286- assert . equal ( activityDumpCalled , false ) ;
1262+ assert . deepEqual ( activityDumpCalls , [ ] ) ;
12871263} ) ;
12881264
12891265test ( 'snapshotAndroid skips hidden content hints when disabled' , async ( ) => {
@@ -1412,24 +1388,20 @@ test('snapshotAndroid omits zero-area interactive nodes from interactive snapsho
14121388 ) ;
14131389} ) ;
14141390
1415- test ( 'snapshotAndroid preserves bottomed-out hidden-above hints in interactive snapshots from a single aligned block' , async ( ) => {
1391+ test ( 'snapshotAndroid preserves bottomed-out hidden-above hints in interactive snapshots' , async ( ) => {
1392+ // Scrolled to the bottom: only the backward action remains, so nothing is hidden below.
14161393 const xml = `<?xml version="1.0" encoding="UTF-8"?>
14171394<hierarchy rotation="0">
14181395 <node class="android.widget.FrameLayout" bounds="[0,0][390,844]" clickable="false" focusable="false">
1419- <node class="android.widget.ScrollView" content-desc="Messages" bounds="[0,100][390,600]" clickable="false" focusable="false">
1396+ <node class="android.widget.ScrollView" content-desc="Messages" scrollable="true" can-scroll-forward="false" can-scroll-backward="true" bounds="[0,100][390,600]" clickable="false" focusable="false">
14201397 <node class="android.view.ViewGroup" bounds="[0,100][390,600]" clickable="false" focusable="false">
14211398 <node class="android.widget.Button" text="Last message" bounds="[0,432][390,600]" clickable="true" focusable="true" />
14221399 </node>
14231400 </node>
14241401 </node>
14251402</hierarchy>` ;
1426- const dump = [
1427- ' com.facebook.react.views.scroll.ReactScrollView{d32a800 VFED.V... ........ 0,0-390,500 #4b2}' ,
1428- ' com.facebook.react.views.view.ReactViewGroup{77d31ae V.E...... ........ 0,0-390,804 #4b0}' ,
1429- ' com.facebook.react.views.view.ReactViewGroup{c V.E...... ........ 0,636-390,804 #3}' ,
1430- ] . join ( '\n' ) ;
14311403
1432- const result = await snapshotAndroidWithHelper ( androidSnapshotHelperAdb ( xml , dump ) , {
1404+ const result = await snapshotAndroidWithHelper ( androidSnapshotHelperAdb ( xml ) , {
14331405 interactiveOnly : true ,
14341406 } ) ;
14351407 const scrollArea = result . nodes . find (
0 commit comments