A mock e-commerce Flutter app used as a QA benchmark for AI testing agents. Nothing talks to a network: every product, order, address and card is local mock data, and every mutation lives in memory for the life of the process.
flutter pub get
flutter run # any device or simulator
flutter test # widget tests
flutter analyze # static analysis (expected: no issues)| Screen | File | Notes |
|---|---|---|
| Login | lib/screens/login_screen.dart |
Email + password validation, show/hide password, remember-me, guest shortcut; signs in straight to the shop |
| Home shell | lib/screens/home_shell.dart |
5-tab NavigationBar over an IndexedStack |
| Shop | lib/screens/product_list_screen.dart |
Category chips, sort/filter sheet, promo banner, pull-to-refresh |
| Search | lib/screens/search_screen.dart |
Live filtering, sort dropdown, recent searches, empty state |
| Wishlist | lib/screens/wishlist_screen.dart |
Swipe-to-remove, add-to-cart, clear-all confirm |
| Product detail | lib/screens/product_detail_screen.dart |
Image carousel, size/quantity, stock states, reviews, related items |
| Cart | lib/screens/cart_screen.dart |
Quantity steppers, swipe-to-delete, promo codes, free-shipping progress, totals |
| Checkout | lib/screens/checkout_screen.dart |
4 steps: address, payment, delivery options, summary |
| Orders | lib/screens/orders_screen.dart |
Status filters, order history |
| Order detail | lib/screens/order_detail_screen.dart |
Line items, reorder, track |
| Profile | lib/screens/profile_screen.dart |
Stats, menu groups, logout confirm |
| Edit profile | lib/screens/edit_profile_screen.dart |
Name / email / phone validation |
| Addresses | lib/screens/addresses_screen.dart |
Add via bottom sheet, set default, delete confirm |
| Payment methods | lib/screens/payment_methods_screen.dart |
Set default / remove via overflow menu |
| Settings | lib/screens/settings_screen.dart |
Dark mode, notification switches, data resets |
State lives in two ChangeNotifiers exposed through InheritedNotifier scopes:
CartController (lib/state/cart_controller.dart) and AccountController
(lib/state/account_controller.dart). Design tokens and the light/dark themes
are in lib/theme/app_theme.dart.
The app deliberately ships no test ids — no semantic Keys on interactive
widgets. An agent has to drive it the way a person would: by visible labels,
icons, tooltips and position. The only Keys in the tree are the two
ValueKeys that Dismissible requires to identify a swiped row.
Rules the UI enforces:
- Any email (containing
@and.) plus a 6+ character password logs in. - The session is saved to the device, so reopening the app resumes signed in. Logging out from the Profile tab clears it.
- Promo codes:
SAVE10(10% off) andWELCOME20(20% off). Anything else is rejected with an inline error. - Free shipping applies once the discounted subtotal reaches
$75.00; otherwise shipping is$6.99. Tax is a flat 8%. - Deliberate edge cases:
Linen ShirtandDesk Lampare out of stock,Throw Pillowhas 2 left,Denim Jackethas 4,Leather Loafershas 3. - Seeded orders:
ORD-4821(delivered),ORD-4655(shipped),ORD-4390(cancelled).
- Happy path purchase — log in, open a product, pick a size and quantity,
add to cart, apply
SAVE10, check out, place the order, then confirm it appears at the top of the Orders tab as Processing. - Totals arithmetic — watch subtotal, discount, shipping, tax and total as
quantities change, and that shipping flips to Free at
$75. - Out-of-stock handling — open
Linen ShirtorDesk Lamp; Add to Cart and Buy Now should be disabled and the grid card shows an overlay. - Validation — submit the login, edit-profile and add-address forms empty and with malformed values; each field reports its own error.
- Wishlist round trip — heart a product on the grid, check the tab badge, remove it by swiping, then clear all.
- Filters and sort — combine a category chip with a sort option and the in-stock / on-sale switches, and verify the count and ordering.
- Search — a term with results, a term without, a recent-search chip, then clear recent searches from Settings.
- Address management — add an address, make it default, use it at checkout, delete it, and confirm the default moves.
- Dark mode — toggle it in Settings and re-walk the main screens.
- Reorder — open
ORD-4655and tap Reorder; both lines land in the cart.