flutternaut
A concise Semantics wrapper for Flutter test automation. Wrap your widgets with Flutternaut to make them discoverable by the test engine. Named constructors auto-configure the right semantics flags for common UI patterns.
Installation
dependencies:
flutternaut: ^0.0.1import 'package:flutternaut/flutternaut.dart';Constructors
Flutternaut.button
For interactive controls: ElevatedButton, IconButton, GestureDetector.
Flutternaut.button(
label: 'login_button',
child: ElevatedButton(onPressed: _login, child: Text('Login')),
)Flutternaut.input
For text input fields: TextField, TextFormField.
Flutternaut.input(
label: 'email_input',
child: TextField(controller: _emailController),
)Flutternaut.text
For dynamic text displays: counters, status labels, error messages. Pass value so the test engine can read the current text content.
Flutternaut.text(
label: 'todo_count',
value: '${todos.length} items',
child: Text('${todos.length} items'),
)Flutternaut.item
For list items: ListTile, list rows.
Flutternaut.item(
label: 'todo_text_$index',
value: todo.text,
child: ListTile(title: Text(todo.text)),
)Flutternaut.checkbox
For checkable items: Checkbox, Switch.
Flutternaut.checkbox(
label: 'check_$index',
checked: todo.completed,
child: Checkbox(value: todo.completed, onChanged: _toggle),
)Default constructor
For elements that don't fit other categories: drag targets, scroll containers, generic wrappers.
Flutternaut(
label: 'drag_target',
container: true,
child: DragTarget<String>(...),
)Reference
| Constructor | Semantics flags | Use for |
|---|---|---|
| Flutternaut(...) | Manual control | Drag targets, scroll containers, generic wrappers |
| Flutternaut.input(...) | — | TextField, TextFormField |
| Flutternaut.button(...) | button: true | ElevatedButton, IconButton, GestureDetector |
| Flutternaut.text(...) | — | Counters, status labels, error messages |
| Flutternaut.item(...) | container: true | ListTile, list items |
| Flutternaut.checkbox(...) | container: true, checked | Checkbox, Switch |
All constructors set excludeSemantics: true to prevent child semantics from polluting accessibility IDs.
The description parameter
All constructors accept an optional description for AI context. It is not passed to Semantics — it exists purely as metadata for the generator and AI test authoring.
Flutternaut.text(
label: 'flow_item_count',
description: 'Shows total number of items in the list',
value: '${items.length} items',
child: Text('${items.length} items'),
)Most elements don't need it — labels like login_button or email_input are self-explanatory. Use description for ambiguous labels where the AI might not understand the element's purpose.
How it works
Flutternaut wraps Flutter's native Semantics widget:
label→Semantics.label— the accessibility ID used by Appium to find elementsvalue→Semantics.value— dynamic text readable by the test enginebutton→Semantics.button— marks interactive controlscontainer→Semantics.container— marks semantic containerschecked→Semantics.checked— tracks checkbox/toggle stateexcludeSemantics: true— always set, prevents child semantics from merging
Requirements
- Flutter ≥ 3.27.0
- Dart ≥ 3.6.0
- App must be built in debug mode — release mode strips the semantics tree