maestra testcases
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
import 'dart:io' show Platform;
|
||||
|
||||
import 'package:client_authentication/client_authentication.dart'
|
||||
as client_authentication;
|
||||
import 'package:client_create_order/client_create_order.dart'
|
||||
@@ -10,6 +12,7 @@ import 'package:design_system/design_system.dart';
|
||||
import 'package:firebase_core/firebase_core.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:marionette_flutter/marionette_flutter.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_localizations/flutter_localizations.dart';
|
||||
import 'package:flutter_modular/flutter_modular.dart';
|
||||
@@ -20,7 +23,23 @@ import 'firebase_options.dart';
|
||||
import 'src/widgets/session_listener.dart';
|
||||
|
||||
void main() async {
|
||||
final bool isFlutterTest =
|
||||
!kIsWeb ? Platform.environment.containsKey('FLUTTER_TEST') : false;
|
||||
if (kDebugMode && !isFlutterTest) {
|
||||
MarionetteBinding.ensureInitialized(
|
||||
MarionetteConfiguration(
|
||||
isInteractiveWidget: (Type type) =>
|
||||
type == UiButton || type == UiTextField,
|
||||
extractText: (Widget widget) {
|
||||
if (widget is UiTextField) return widget.label;
|
||||
if (widget is UiButton) return widget.text;
|
||||
return null;
|
||||
},
|
||||
),
|
||||
);
|
||||
} else {
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
}
|
||||
await Firebase.initializeApp(
|
||||
options: kIsWeb ? DefaultFirebaseOptions.currentPlatform : null,
|
||||
);
|
||||
|
||||
42
apps/mobile/apps/client/maestro/README.md
Normal file
42
apps/mobile/apps/client/maestro/README.md
Normal file
@@ -0,0 +1,42 @@
|
||||
# Maestro Integration Tests — Client App
|
||||
|
||||
Login and signup flows for the KROW Client app.
|
||||
See [docs/research/flutter-testing-tools.md](/docs/research/flutter-testing-tools.md) for the evaluation report.
|
||||
**Full run instructions:** [docs/research/maestro-test-run-instructions.md](/docs/research/maestro-test-run-instructions.md)
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- [Maestro CLI](https://maestro.dev/docs/getting-started/installation) installed
|
||||
- Client app built and installed on device/emulator:
|
||||
```bash
|
||||
cd apps/mobile && flutter build apk
|
||||
adb install build/app/outputs/flutter-apk/app-debug.apk
|
||||
```
|
||||
|
||||
## Credentials
|
||||
|
||||
| Flow | Credentials |
|
||||
|------|-------------|
|
||||
| **Client login** | legendary@krowd.com / Demo2026! |
|
||||
| **Staff login** | 5557654321 / OTP 123456 |
|
||||
| **Client signup** | Env vars: `MAESTRO_CLIENT_EMAIL`, `MAESTRO_CLIENT_PASSWORD`, `MAESTRO_CLIENT_COMPANY` |
|
||||
| **Staff signup** | Env var: `MAESTRO_STAFF_SIGNUP_PHONE` (must be new Firebase test phone) |
|
||||
|
||||
## Run
|
||||
|
||||
From the project root:
|
||||
|
||||
```bash
|
||||
# Login
|
||||
maestro test apps/mobile/apps/client/maestro/login.yaml
|
||||
|
||||
# Signup
|
||||
maestro test apps/mobile/apps/client/maestro/signup.yaml
|
||||
```
|
||||
|
||||
## Flows
|
||||
|
||||
| File | Flow | Description |
|
||||
|------------|-------------|--------------------------------------------|
|
||||
| login.yaml | Client Login| Get Started → Sign In → Home |
|
||||
| signup.yaml| Client Signup| Get Started → Create Account → Home |
|
||||
18
apps/mobile/apps/client/maestro/login.yaml
Normal file
18
apps/mobile/apps/client/maestro/login.yaml
Normal file
@@ -0,0 +1,18 @@
|
||||
# Client App - Login Flow
|
||||
# Prerequisites: App built and installed (debug or release)
|
||||
# Run: maestro test apps/mobile/apps/client/maestro/login.yaml
|
||||
# Test credentials: legendary@krowd.com / Demo2026!
|
||||
# Note: Auth uses Firebase/Data Connect
|
||||
|
||||
appId: com.krowwithus.client
|
||||
---
|
||||
- launchApp
|
||||
- assertVisible: "Sign In"
|
||||
- tapOn: "Sign In"
|
||||
- assertVisible: "Email"
|
||||
- tapOn: "Email"
|
||||
- inputText: "legendary@krowd.com"
|
||||
- tapOn: "Password"
|
||||
- inputText: "Demo2026!"
|
||||
- tapOn: "Sign In"
|
||||
- assertVisible: "Home"
|
||||
23
apps/mobile/apps/client/maestro/signup.yaml
Normal file
23
apps/mobile/apps/client/maestro/signup.yaml
Normal file
@@ -0,0 +1,23 @@
|
||||
# Client App - Sign Up Flow
|
||||
# Prerequisites: App built and installed
|
||||
# Run: maestro test apps/mobile/apps/client/maestro/signup.yaml
|
||||
# Use NEW credentials for signup (creates new account)
|
||||
# Env: MAESTRO_CLIENT_EMAIL, MAESTRO_CLIENT_PASSWORD, MAESTRO_CLIENT_COMPANY
|
||||
|
||||
appId: com.krowwithus.client
|
||||
---
|
||||
- launchApp
|
||||
- assertVisible: "Create Account"
|
||||
- tapOn: "Create Account"
|
||||
- assertVisible: "Company"
|
||||
- tapOn: "Company"
|
||||
- inputText: "${MAESTRO_CLIENT_COMPANY}"
|
||||
- tapOn: "Email"
|
||||
- inputText: "${MAESTRO_CLIENT_EMAIL}"
|
||||
- tapOn: "Password"
|
||||
- inputText: "${MAESTRO_CLIENT_PASSWORD}"
|
||||
- tapOn:
|
||||
text: "Confirm Password"
|
||||
- inputText: "${MAESTRO_CLIENT_PASSWORD}"
|
||||
- tapOn: "Create Account"
|
||||
- assertVisible: "Home"
|
||||
@@ -42,6 +42,7 @@ dependencies:
|
||||
sdk: flutter
|
||||
firebase_core: ^4.4.0
|
||||
krow_data_connect: ^0.0.1
|
||||
marionette_flutter: ^0.3.0
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
import 'dart:io' show Platform;
|
||||
|
||||
import 'package:core_localization/core_localization.dart' as core_localization;
|
||||
import 'package:design_system/design_system.dart';
|
||||
import 'package:firebase_core/firebase_core.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:marionette_flutter/marionette_flutter.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_localizations/flutter_localizations.dart';
|
||||
import 'package:flutter_modular/flutter_modular.dart';
|
||||
@@ -15,7 +19,23 @@ import 'package:krow_core/core.dart';
|
||||
import 'src/widgets/session_listener.dart';
|
||||
|
||||
void main() async {
|
||||
final bool isFlutterTest =
|
||||
!kIsWeb ? Platform.environment.containsKey('FLUTTER_TEST') : false;
|
||||
if (kDebugMode && !isFlutterTest) {
|
||||
MarionetteBinding.ensureInitialized(
|
||||
MarionetteConfiguration(
|
||||
isInteractiveWidget: (Type type) =>
|
||||
type == UiButton || type == UiTextField,
|
||||
extractText: (Widget widget) {
|
||||
if (widget is UiTextField) return widget.label;
|
||||
if (widget is UiButton) return widget.text;
|
||||
return null;
|
||||
},
|
||||
),
|
||||
);
|
||||
} else {
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
}
|
||||
await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
|
||||
|
||||
// Register global BLoC observer for centralized error logging
|
||||
|
||||
41
apps/mobile/apps/staff/maestro/README.md
Normal file
41
apps/mobile/apps/staff/maestro/README.md
Normal file
@@ -0,0 +1,41 @@
|
||||
# Maestro Integration Tests — Staff App
|
||||
|
||||
Login and signup flows for the KROW Staff app.
|
||||
See [docs/research/flutter-testing-tools.md](/docs/research/flutter-testing-tools.md) for the evaluation report.
|
||||
**Full run instructions:** [docs/research/maestro-test-run-instructions.md](/docs/research/maestro-test-run-instructions.md)
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- [Maestro CLI](https://maestro.dev/docs/getting-started/installation) installed
|
||||
- Staff app built and installed
|
||||
- **Firebase test phone** in Firebase Console (Auth > Sign-in method > Phone):
|
||||
- Login: +1 555-765-4321 / OTP 123456
|
||||
- Signup: add a different test number for new accounts
|
||||
|
||||
## Credentials
|
||||
|
||||
| Flow | Credentials |
|
||||
|------|-------------|
|
||||
| **Client login** | legendary@krowd.com / Demo2026! |
|
||||
| **Staff login** | 5557654321 / OTP 123456 |
|
||||
| **Client signup** | Env vars: `MAESTRO_CLIENT_EMAIL`, `MAESTRO_CLIENT_PASSWORD`, `MAESTRO_CLIENT_COMPANY` |
|
||||
| **Staff signup** | Env var: `MAESTRO_STAFF_SIGNUP_PHONE` (must be new Firebase test phone) |
|
||||
|
||||
## Run
|
||||
|
||||
From the project root:
|
||||
|
||||
```bash
|
||||
# Login
|
||||
maestro test apps/mobile/apps/staff/maestro/login.yaml
|
||||
|
||||
# Signup
|
||||
maestro test apps/mobile/apps/staff/maestro/signup.yaml
|
||||
```
|
||||
|
||||
## Flows
|
||||
|
||||
| File | Flow | Description |
|
||||
|------------|------------|-------------------------------------|
|
||||
| login.yaml | Staff Login| Get Started → Log In → Phone → OTP → Home |
|
||||
| signup.yaml| Staff Signup| Get Started → Sign Up → Phone → OTP → Profile Setup |
|
||||
18
apps/mobile/apps/staff/maestro/login.yaml
Normal file
18
apps/mobile/apps/staff/maestro/login.yaml
Normal file
@@ -0,0 +1,18 @@
|
||||
# Staff App - Login Flow (Phone + OTP)
|
||||
# Prerequisites: App built and installed; Firebase test phone configured
|
||||
# Firebase test phone: +1 555-765-4321 / OTP 123456
|
||||
# Run: maestro test apps/mobile/apps/staff/maestro/login.yaml
|
||||
|
||||
appId: com.krowwithus.staff
|
||||
---
|
||||
- launchApp
|
||||
- assertVisible: "Log In"
|
||||
- tapOn: "Log In"
|
||||
- assertVisible: "Send Code"
|
||||
- inputText: "5557654321"
|
||||
- tapOn: "Send Code"
|
||||
# Wait for OTP screen
|
||||
- assertVisible: "Continue"
|
||||
- inputText: "123456"
|
||||
- tapOn: "Continue"
|
||||
# On success: staff main. Adjust final assertion to match staff home screen.
|
||||
18
apps/mobile/apps/staff/maestro/signup.yaml
Normal file
18
apps/mobile/apps/staff/maestro/signup.yaml
Normal file
@@ -0,0 +1,18 @@
|
||||
# Staff App - Sign Up Flow (Phone + OTP)
|
||||
# Prerequisites: App built and installed; Firebase test phone for NEW number
|
||||
# Use a NEW phone number for signup (creates new account)
|
||||
# Firebase: add test phone in Auth > Phone; e.g. +1 555-555-0000 / 123456
|
||||
# Run: maestro test apps/mobile/apps/staff/maestro/signup.yaml
|
||||
|
||||
appId: com.krowwithus.staff
|
||||
---
|
||||
- launchApp
|
||||
- assertVisible: "Sign Up"
|
||||
- tapOn: "Sign Up"
|
||||
- assertVisible: "Send Code"
|
||||
- inputText: "${MAESTRO_STAFF_SIGNUP_PHONE}"
|
||||
- tapOn: "Send Code"
|
||||
- assertVisible: "Continue"
|
||||
- inputText: "123456"
|
||||
- tapOn: "Continue"
|
||||
# On success: Profile Setup. Adjust assertion to match destination.
|
||||
@@ -30,6 +30,7 @@ dependencies:
|
||||
path: ../../packages/core
|
||||
krow_data_connect:
|
||||
path: ../../packages/data_connect
|
||||
marionette_flutter: ^0.3.0
|
||||
cupertino_icons: ^1.0.8
|
||||
flutter_modular: ^6.3.0
|
||||
firebase_core: ^4.4.0
|
||||
|
||||
@@ -813,6 +813,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.257.0"
|
||||
marionette_flutter:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: marionette_flutter
|
||||
sha256: "0077073f62a8031879a91be41aa91629f741a7f1348b18feacd53443dae3819f"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.3.0"
|
||||
matcher:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
||||
@@ -68,11 +68,17 @@ Semantics(
|
||||
)
|
||||
```
|
||||
|
||||
### Phase 2: Repository Structure
|
||||
Tests will be localized within the respective app directories to maintain modularity:
|
||||
### Phase 2: Repository Structure (Implemented)
|
||||
Maestro flows are co-located with each app:
|
||||
|
||||
* `apps/mobile/apps/client/maestro/`
|
||||
* `apps/mobile/apps/staff/maestro/`
|
||||
* `apps/mobile/apps/client/maestro/login.yaml` — Client login
|
||||
* `apps/mobile/apps/client/maestro/signup.yaml` — Client signup
|
||||
* `apps/mobile/apps/staff/maestro/login.yaml` — Staff login (phone + OTP)
|
||||
* `apps/mobile/apps/staff/maestro/signup.yaml` — Staff signup (phone + OTP)
|
||||
|
||||
Each directory has a README with run instructions.
|
||||
|
||||
**Marionette MCP:** `marionette_flutter` is added to both apps; `MarionetteBinding` is initialized in debug mode. See [marionette-spike-usage.md](marionette-spike-usage.md) for prompts and workflow.
|
||||
|
||||
### Phase 3: CI/CD Integration
|
||||
The Maestro CLI will be added to our **GitHub Actions** workflow to automate quality gates.
|
||||
|
||||
84
docs/research/maestro-test-run-instructions.md
Normal file
84
docs/research/maestro-test-run-instructions.md
Normal file
@@ -0,0 +1,84 @@
|
||||
# How to Run Maestro Integration Tests
|
||||
|
||||
## Credentials
|
||||
|
||||
| Flow | Credentials |
|
||||
|------|-------------|
|
||||
| **Client login** | legendary@krowd.com / Demo2026! |
|
||||
| **Staff login** | 5557654321 / OTP 123456 |
|
||||
| **Client signup** | Env vars: `MAESTRO_CLIENT_EMAIL`, `MAESTRO_CLIENT_PASSWORD`, `MAESTRO_CLIENT_COMPANY` |
|
||||
| **Staff signup** | Env var: `MAESTRO_STAFF_SIGNUP_PHONE` (must be new Firebase test phone) |
|
||||
|
||||
---
|
||||
|
||||
## Step-by-step: Run login tests
|
||||
|
||||
### 1. Install Maestro CLI
|
||||
|
||||
```bash
|
||||
curl -Ls "https://get.maestro.mobile.dev" | bash
|
||||
```
|
||||
|
||||
Or: https://maestro.dev/docs/getting-started/installation
|
||||
|
||||
### 2. Add Firebase test phone (Staff app only)
|
||||
|
||||
In [Firebase Console](https://console.firebase.google.com) → your project → **Authentication** → **Sign-in method** → **Phone** → **Phone numbers for testing**:
|
||||
|
||||
- Add: **+1 5557654321** with verification code **123456**
|
||||
|
||||
### 3. Build and install the apps
|
||||
|
||||
From the **project root**:
|
||||
|
||||
```bash
|
||||
# Client
|
||||
make mobile-client-build PLATFORM=apk MODE=debug
|
||||
adb install apps/mobile/apps/client/build/app/outputs/flutter-apk/app-debug.apk
|
||||
|
||||
# Staff
|
||||
make mobile-staff-build PLATFORM=apk MODE=debug
|
||||
adb install apps/mobile/apps/staff/build/app/outputs/flutter-apk/app-debug.apk
|
||||
```
|
||||
|
||||
Or run the app on a connected device/emulator: `make mobile-client-dev-android DEVICE=<id>` (then Maestro can launch the already-installed app by appId).
|
||||
|
||||
### 4. Run Maestro tests
|
||||
|
||||
From the **project root** (`e:\Krow-google\krow-workforce`):
|
||||
|
||||
```bash
|
||||
# Client login (uses legendary@krowd.com / Demo2026!)
|
||||
maestro test apps/mobile/apps/client/maestro/login.yaml
|
||||
|
||||
# Staff login (uses 5557654321 / OTP 123456)
|
||||
maestro test apps/mobile/apps/staff/maestro/login.yaml
|
||||
```
|
||||
|
||||
### 5. Run signup tests (optional)
|
||||
|
||||
**Client signup** — set env vars first:
|
||||
```bash
|
||||
$env:MAESTRO_CLIENT_EMAIL="newuser@example.com"
|
||||
$env:MAESTRO_CLIENT_PASSWORD="YourPassword123!"
|
||||
$env:MAESTRO_CLIENT_COMPANY="Test Company"
|
||||
maestro test apps/mobile/apps/client/maestro/signup.yaml
|
||||
```
|
||||
|
||||
**Staff signup** — use a new Firebase test phone:
|
||||
```bash
|
||||
# Add +1 555-555-0000 / 123456 in Firebase, then:
|
||||
$env:MAESTRO_STAFF_SIGNUP_PHONE="5555550000"
|
||||
maestro test apps/mobile/apps/staff/maestro/signup.yaml
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Checklist
|
||||
|
||||
- [ ] Maestro CLI installed
|
||||
- [ ] Firebase test phone +1 5557654321 / 123456 added (for staff)
|
||||
- [ ] Client app built and installed
|
||||
- [ ] Staff app built and installed
|
||||
- [ ] Run from project root: `maestro test apps/mobile/apps/client/maestro/login.yaml`
|
||||
- [ ] Run from project root: `maestro test apps/mobile/apps/staff/maestro/login.yaml`
|
||||
58
docs/research/marionette-spike-usage.md
Normal file
58
docs/research/marionette-spike-usage.md
Normal file
@@ -0,0 +1,58 @@
|
||||
# Marionette MCP Spike — Usage Guide
|
||||
|
||||
**Issue:** #533
|
||||
**Purpose:** Document how to run the Marionette MCP spike for auth flows.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
1. **Marionette MCP server** — Install globally:
|
||||
```bash
|
||||
dart pub global activate marionette_mcp
|
||||
```
|
||||
|
||||
2. **Add Marionette to Cursor** — In `.cursor/mcp.json` or global config:
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"marionette": {
|
||||
"command": "marionette_mcp",
|
||||
"args": []
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
3. **Run app in debug mode** — The app must be running with VM Service:
|
||||
```bash
|
||||
cd apps/mobile && flutter run -d <device_id>
|
||||
```
|
||||
|
||||
4. **Get VM Service URI** — From the `flutter run` output, copy the `ws://127.0.0.1:XXXX/ws` URI (often shown in the DevTools link).
|
||||
|
||||
## Spike flows (AI agent prompts)
|
||||
|
||||
Use these prompts with the Marionette MCP connected to the running app.
|
||||
|
||||
### Client — Login
|
||||
|
||||
> Connect to the app using the VM Service URI. Navigate to the Get Started screen, tap "Sign In", enter legendary@krowd.com and Demo2026!, then tap "Sign In". Verify we land on the home screen.
|
||||
|
||||
### Client — Sign up
|
||||
|
||||
> Connect to the app. Tap "Create Account", fill in Company, Email, Password (and confirm) with new credentials, then tap "Create Account". Verify we land on the home screen.
|
||||
|
||||
### Staff — Login
|
||||
|
||||
> Connect to the app. Tap "Log In", enter phone number 5557654321, tap "Send Code", enter OTP 123456, tap "Continue". Verify we reach the staff home screen.
|
||||
> (Firebase test phone: +1 555-765-4321 / OTP 123456)
|
||||
|
||||
### Staff — Sign up
|
||||
|
||||
> Connect to the app. Tap "Sign Up", enter a NEW phone number (Firebase test phone), tap "Send Code", enter OTP, tap "Continue". Verify we reach Profile Setup or staff home.
|
||||
|
||||
## Limitations observed (from spike)
|
||||
|
||||
- **Debug only** — Marionette needs the Dart VM Service; does not work with release builds.
|
||||
- **Non-deterministic** — LLM-driven actions can vary in behavior and timing.
|
||||
- **Latency** — Each step involves API roundtrips (~45s+ for full flow vs ~5s for Maestro).
|
||||
- **Best use** — Exploratory testing, live debugging, smoke checks during development.
|
||||
Reference in New Issue
Block a user