Describe the bug
Empty Flutter TextField widgets are invisible to mobile_list_elements_on_screen on Android. The underlying android.widget.EditText nodes exist in the accessibility tree and are usable via TalkBack, but they do not appear in mobile-mcp's element list, so they cannot be tapped, typed into, or asserted against.
Root cause is the standard adb shell uiautomator dump API used at src/android.ts:481. Since Flutter 3.7+, InputDecoration.labelText is rendered via Android's setHintText() rather than setText() (this was done intentionally to improve TalkBack support — see flutter/flutter#119326). UiAutomator's standard XML dump does not include hintText. The resulting node has empty text, empty content-desc, no resource-id, and is not checkable, so it fails the filter at src/android.ts:337 and is dropped from the elements list.
The same failure mode affects vanilla adb shell uiautomator dump, pre-#897 Maestro, and stock Appium UiAutomator2.
To Reproduce
Minimal Flutter app:
import 'package:flutter/material.dart';
void main() => runApp(const MaterialApp(home: Repro()));
class Repro extends StatelessWidget {
const Repro({super.key});
@override
Widget build(BuildContext ctx) => const Scaffold(
body: Padding(
padding: EdgeInsets.all(24),
child: TextField(decoration: InputDecoration(labelText: 'Name')),
),
);
}
flutter run on a real Android device or emulator (Android 9+, any Flutter 3.7+).
- Call
mobile_list_elements_on_screen via the MCP.
- Observe no
EditText node in the returned list.
- Call
mobile_click_on_screen_at_coordinates on the field's pixel centroid → tap lands but no programmatic way to discover the field first.
Expected behavior
mobile_list_elements_on_screen returns the EditText with a label of "Name" (the value of InputDecoration.labelText), so it can be discovered and acted on by name rather than pixel coordinates.
Actual behavior
The EditText does not appear in the element list at all. The only nearby nodes that survive the filter are siblings carrying content-desc (e.g. suffix icons or external Text labels), none of which are tappable for text input.
Comparison with Maestro (works)
Maestro patched their own dumper in mobile-dev-inc/maestro#897 (merged March 2023). Their serializer at maestro-android/src/androidTest/java/dev/mobile/maestro/ViewHierarchy.kt reads getHintText() via AccessibilityNodeInfo and emits it as a hintText attribute on each node, alongside text and accessibilityText.
Against the same Flutter screen, maestro hierarchy returns the EditText with hintText populated:
{
"attributes": {
"text": "",
"accessibilityText": "",
"hintText": "Name",
"clickable": "true",
"bounds": "[104,670][976,850]",
"enabled": "true",
"class": "android.widget.EditText",
"important-for-accessibility": "true"
},
"children": []
}
mobile-mcp's getUiAutomatorXml() on the same device, same app state, returns no node at those bounds.
Configuration
- mobile-mcp: latest
main
- Flutter: any 3.7+
- Android: physical Samsung Galaxy A52s, Android 14 (also reproduces on Pixel emulators)
Suggested fix
Two options, in order of robustness:
- Mirror Maestro's approach. Bundle a small
androidTest APK (or APK-less instrumentation) that uses AccessibilityNodeInfo.getHintText() to build the hierarchy, then surface hintText as a queryable attribute. collectElements at src/android.ts:337 already checks node.hint — the filter is correct; only the source data is missing. See Maestro's ViewHierarchy.kt as a working reference.
- Lower bar: in
collectElements, also accept nodes where className === "android.widget.EditText" regardless of text/content-desc, so empty EditTexts at least surface as coordinate-tappable. Doesn't give a label, but prevents the node from disappearing entirely.
Happy to open a PR for (2) if useful as a stopgap.
References
Describe the bug
Empty Flutter
TextFieldwidgets are invisible tomobile_list_elements_on_screenon Android. The underlyingandroid.widget.EditTextnodes exist in the accessibility tree and are usable via TalkBack, but they do not appear in mobile-mcp's element list, so they cannot be tapped, typed into, or asserted against.Root cause is the standard
adb shell uiautomator dumpAPI used atsrc/android.ts:481. Since Flutter 3.7+,InputDecoration.labelTextis rendered via Android'ssetHintText()rather thansetText()(this was done intentionally to improve TalkBack support — see flutter/flutter#119326). UiAutomator's standard XML dump does not includehintText. The resulting node has emptytext, emptycontent-desc, noresource-id, and is notcheckable, so it fails the filter atsrc/android.ts:337and is dropped from the elements list.The same failure mode affects vanilla
adb shell uiautomator dump, pre-#897 Maestro, and stock Appium UiAutomator2.To Reproduce
Minimal Flutter app:
flutter runon a real Android device or emulator (Android 9+, any Flutter 3.7+).mobile_list_elements_on_screenvia the MCP.EditTextnode in the returned list.mobile_click_on_screen_at_coordinateson the field's pixel centroid → tap lands but no programmatic way to discover the field first.Expected behavior
mobile_list_elements_on_screenreturns theEditTextwith alabelof"Name"(the value ofInputDecoration.labelText), so it can be discovered and acted on by name rather than pixel coordinates.Actual behavior
The
EditTextdoes not appear in the element list at all. The only nearby nodes that survive the filter are siblings carryingcontent-desc(e.g. suffix icons or externalTextlabels), none of which are tappable for text input.Comparison with Maestro (works)
Maestro patched their own dumper in mobile-dev-inc/maestro#897 (merged March 2023). Their serializer at
maestro-android/src/androidTest/java/dev/mobile/maestro/ViewHierarchy.ktreadsgetHintText()viaAccessibilityNodeInfoand emits it as ahintTextattribute on each node, alongsidetextandaccessibilityText.Against the same Flutter screen,
maestro hierarchyreturns the EditText withhintTextpopulated:{ "attributes": { "text": "", "accessibilityText": "", "hintText": "Name", "clickable": "true", "bounds": "[104,670][976,850]", "enabled": "true", "class": "android.widget.EditText", "important-for-accessibility": "true" }, "children": [] }mobile-mcp's
getUiAutomatorXml()on the same device, same app state, returns no node at those bounds.Configuration
mainSuggested fix
Two options, in order of robustness:
androidTestAPK (or APK-less instrumentation) that usesAccessibilityNodeInfo.getHintText()to build the hierarchy, then surfacehintTextas a queryable attribute.collectElementsatsrc/android.ts:337already checksnode.hint— the filter is correct; only the source data is missing. See Maestro'sViewHierarchy.ktas a working reference.collectElements, also accept nodes whereclassName === "android.widget.EditText"regardless of text/content-desc, so empty EditTexts at least surface as coordinate-tappable. Doesn't give a label, but prevents the node from disappearing entirely.Happy to open a PR for (2) if useful as a stopgap.
References
b/267640877