Write a Flutter login test
This tutorial writes an end-to-end test for a login screen: the happy path, a validation error, and a reusable login step. It takes about ten minutes if the CLI is installed.
1. Give the widgets keys
Section titled “1. Give the widgets keys”Text selectors work, but a key does not change when the copy or the language does. Add a ValueKey to the widgets the test touches:
TextField(key: const ValueKey('email')),TextField(key: const ValueKey('password'), obscureText: true),ElevatedButton(key: const ValueKey('loginButton'), onPressed: _submit, child: const Text('Log in')),In a test, #email selects the widget with ValueKey('email').
2. Add the agent and build with the flag
Section titled “2. Add the agent and build with the flag”dev_dependencies: flutter_probe_agent: ^0.26.0const probeEnabled = bool.fromEnvironment('PROBE_AGENT', defaultValue: false);if (probeEnabled) { await ProbeAgent.start();}Run the app with flutter run --dart-define=PROBE_AGENT=true. A normal build without the flag does not start the agent.
3. Write the happy path
Section titled “3. Write the happy path”Run probe init in the project, then create tests/login.probe:
test "a user can log in" open the app wait until "Log in" appears type "user@example.com" into #email type "secret123" into #password tap #loginButton wait until "Dashboard" appearsCheck it parses, then run it:
probe lint tests/login.probeprobe device listprobe test tests/login.probe --device <id> -v4. Add a failure case
Section titled “4. Add a failure case”test "login shows an error for a wrong password" open the app wait until "Log in" appears type "user@example.com" into #email type "wrong" into #password tap #loginButton wait until "Invalid email or password" appears don't see "Dashboard"A failed step reports which line failed, what it was waiting for, and saves a screenshot.
5. Share the login steps
Section titled “5. Share the login steps”Move the repeated steps into a recipe in tests/recipes/auth.probe:
recipe "log in as" (email, password) open the app wait until "Log in" appears type "<email>" into #email type "<password>" into #password tap #loginButton wait until "Dashboard" appearsUse it from any test:
use "recipes/auth.probe"
test "a logged-in user sees their profile" log in as "user@example.com" with "secret123" tap "Profile" see "user@example.com"Placeholders must be quoted ("<email>"); probe lint rejects an unquoted one.
- Text selectors match substrings. For a zero-state such as
0 ml, add an anchored check:see "0 ml" matching "^0 ml$". - Prefer
wait until "X" appearsafter a navigation. A tap returns before the next screen has finished building. - Run every test file with
probe test tests/ --device <id>.
Run the tests in GitHub Actions, or read the ProbeScript syntax.
The CLI and everything on this page is free. Probe Cloud, hosted report storage, is a design-partner preview and is not live yet.