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

yaml
dependencies:
  flutternaut: ^0.0.1
dart
import 'package:flutternaut/flutternaut.dart';

Constructors

Flutternaut.button

For interactive controls: ElevatedButton, IconButton, GestureDetector.

dart
Flutternaut.button(
  label: 'login_button',
  child: ElevatedButton(onPressed: _login, child: Text('Login')),
)

Flutternaut.input

For text input fields: TextField, TextFormField.

dart
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.

dart
Flutternaut.text(
  label: 'todo_count',
  value: '${todos.length} items',
  child: Text('${todos.length} items'),
)

Flutternaut.item

For list items: ListTile, list rows.

dart
Flutternaut.item(
  label: 'todo_text_$index',
  value: todo.text,
  child: ListTile(title: Text(todo.text)),
)

Flutternaut.checkbox

For checkable items: Checkbox, Switch.

dart
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.

dart
Flutternaut(
  label: 'drag_target',
  container: true,
  child: DragTarget<String>(...),
)

Reference

ConstructorSemantics flagsUse for
Flutternaut(...)Manual controlDrag targets, scroll containers, generic wrappers
Flutternaut.input(...)TextField, TextFormField
Flutternaut.button(...)button: trueElevatedButton, IconButton, GestureDetector
Flutternaut.text(...)Counters, status labels, error messages
Flutternaut.item(...)container: trueListTile, list items
Flutternaut.checkbox(...)container: true, checkedCheckbox, 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.

dart
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:

  • labelSemantics.label — the accessibility ID used by Appium to find elements
  • valueSemantics.value — dynamic text readable by the test engine
  • buttonSemantics.button — marks interactive controls
  • containerSemantics.container — marks semantic containers
  • checkedSemantics.checked — tracks checkbox/toggle state
  • excludeSemantics: 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