.agents/goals/biolift-android-full-e2e.md
| Flow | What it proves | Run-id | Risk |
|---|---|---|---|
| 30-onboarding-v2-happy | Full v2 onboarding — 12 screens, ends on Daily Readiness | 1779443983-d91e7fa | Low |
| 31-skip-global | Global "do this later" Skip from goal → home | 1779450095-d91e7fa | Low |
| 32-skip-parq | PAR-Q Skip → Notifications, parqSkipped audit flag set | 1779450156-d91e7fa | Low |
| 33-skip-signup | Signup "Skip for now" → home (skipForNow finalize path) | 1779450234-d91e7fa | Low |
| 50-home-readiness | Daily Readiness card — HRV / Sleep / RHR all rendering | 1779449483-d91e7fa | Low |
| 52-plan-tab | Plan tab — Training Plan + Schedule & Programming + MAKE MY LIFT | 1779450038-d91e7fa | Med |
| 54-catalog | Catalog tab — Legs / Back / Chest categories | 1779449622-d91e7fa | Low |
| 55-progress-tab | Progress — Analytics & Insights + Total Volume + Active Days | 1779449887-d91e7fa | Low |
| 56-profile-theme | Profile — ACCOUNT SETTINGS + Dark Neon / AMOLED swatches | 1779449828-d91e7fa | Low |
| 57-nutrition | Nutrition — Breakfast / Lunch / Dinner meal slots | 1779449559-d91e7fa | Low |
eventDate, injuries, and
notificationsEnabled were written as
undefined to users/<uid>/profile/preferences.
Firestore setDoc rejects undefined — the commit
failed with "Could not save".
Fix — strip optional undefined fields before setDoc in mobile/services/onboardingService.ts.
ensureAnonymousAuth created a real anonymous UID, but the
FirebaseProvider gate checked a hardcoded
dev-mock-uid-000001. Profile writes landed in the wrong
doc tree; onboarding never appeared complete.
Fix — both sides now read auth.currentUser.uid.
getAuth(app) defaulted to in-memory persistence in
React Native. Every cold-start created a new anonymous UID,
voiding any seeded onboarding state.
Fix — initializeAuth(app, { persistence: getReactNativePersistence(AsyncStorage) }) in mobile/services/firebase.ts.
Under DEV_MOCK_AUTH, the gate bypassed Firestore
entirely — commitOnboarding wrote the profile
but hasCompletedOnboarding never flipped, so the
user stayed stuck on the onboarding flow.
Fix — always read Firestore in checkOnboarding; mock flag only affects auto-sign-in.
+--------------------------------------------------------------------+
| run-all.sh (--repeat=N · adb stabilisation · run-id namespace) |
+----------------------------+---------------------------------------+
|
v
+--------------------------------------------------------------------+
| runner.sh <flow> --preset=fresh|onboarded |
| |
| 1. emu_full_setup AVD up · firebase emu · metro · adb fwd |
| 2. preset state wipe auth + firestore + pm clear |
| 3. pre snapshot screencap + ui.xml under pre/ |
| 4. drive maestro test YAML flow against real UI |
| 5. post snapshot screencap + ui.xml + logcat |
| 6. flow.json pass/fail + run-id + timestamps |
+--------------------+-----------------------------------------------+
|
+-----------------+-----------------+
v v v
+--------+ +-------------+ +-------------------+
| adb | | maestro | | firebase-admin |
| + | | test | | seed scripts |
| adb | | (gRPC) | | (FIRESTORE_ |
| shell | | | | EMULATOR_HOST) |
+----+---+ +-----+-------+ +---------+---------+
| | |
+-------+ | |
v v v
+-------------------+ +-------------------------+
| Android AVD | | Firebase emulator |
| Medium_Phone | | auth :9099 |
| _API_35 | | firestore :8080 |
| com.stevengon.. | | rules from prod |
| jstlft (debug) | | |
+-------------------+ +-------------------------+
--repeat=3 end-to-end run not yet executed.
Per-flow re-run determinism shown (30 + 50 each passed twice).
· needs a fresh AVD + the adb-ping gap (already wired)
tcp:7001 closed, DEADLINE_EXCEEDED).
Mitigated by adb shell echo ping + 3s gap;
running flows sequentially with rests is fully reliable.
· future: re-warm maestro driver per flow
# Single flow with full state reset bash e2e/android/runner.sh \ e2e/android/flows/30-onboarding-v2-happy.yaml \ --preset=fresh # Single flow inheriting onboarded state bash e2e/android/runner.sh \ e2e/android/flows/50-home-readiness.yaml \ --preset=onboarded # Determinism gate (criterion 2): three consecutive clean-AVD passes bash e2e/android/run-all.sh --repeat=3
artifacts/<run-id>/<flow>/
with flow.json, maestro.log,
pre/, and post/ (screenshot + ui.xml + logcat).
Re-running is idempotent — emulator boot, metro, and firebase
emulator are all wired with detect-or-start logic.