docs: revamp AGENTS.md — canonical AI agent reference, purge obsolete TabataFit docs
This commit is contained in:
@@ -1,643 +0,0 @@
|
||||
# Maestro E2E Testing Strategy for TabataFit
|
||||
|
||||
## Executive Summary
|
||||
|
||||
**Maestro** is a mobile UI testing framework that uses YAML-based test flows. It's ideal for TabataFit because:
|
||||
- ✅ Declarative YAML syntax (no code required)
|
||||
- ✅ Built-in support for React Native
|
||||
- ✅ Handles animations and async operations gracefully
|
||||
- ✅ Excellent for regression testing critical user flows
|
||||
- ✅ Can run on physical devices and simulators
|
||||
|
||||
---
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Before implementing these tests, ensure the following features are complete:
|
||||
|
||||
### Required Features (Implement First)
|
||||
- [ ] Onboarding flow (5 screens + paywall)
|
||||
- [ ] Workout player with timer controls
|
||||
- [ ] Browse/Workouts tab with workout cards
|
||||
- [ ] Category filtering (Full Body, Core, Cardio, etc.)
|
||||
- [ ] Collections feature
|
||||
- [ ] Trainer profiles
|
||||
- [ ] Subscription/paywall integration
|
||||
- [ ] Workout completion screen
|
||||
- [ ] Profile/settings screen
|
||||
|
||||
### Nice to Have (Can Add Later)
|
||||
- [ ] Activity history tracking
|
||||
- [ ] Offline mode support
|
||||
- [ ] Deep linking
|
||||
- [ ] Push notifications
|
||||
|
||||
---
|
||||
|
||||
## Priority Test Flows
|
||||
|
||||
### **P0 - Critical Flows (Must Test Every Release)**
|
||||
1. **Onboarding → First Workout**
|
||||
2. **Browse → Select Workout → Play → Complete**
|
||||
3. **Subscription Purchase Flow**
|
||||
4. **Background/Foreground During Workout**
|
||||
|
||||
### **P1 - High Priority**
|
||||
5. **Category Filtering**
|
||||
6. **Collection Navigation**
|
||||
7. **Trainer Workout Discovery**
|
||||
8. **Profile Settings & Data Persistence**
|
||||
|
||||
### **P2 - Medium Priority**
|
||||
9. **Activity History Tracking**
|
||||
10. **Offline Mode Behavior**
|
||||
11. **Deep Linking**
|
||||
12. **Push Notifications**
|
||||
|
||||
---
|
||||
|
||||
## Test Suite Structure
|
||||
|
||||
```
|
||||
.maestro/
|
||||
├── config.yaml # Global test configuration
|
||||
├── flows/
|
||||
│ ├── critical/ # P0 flows - Run on every PR
|
||||
│ │ ├── onboarding.yaml
|
||||
│ │ ├── workoutComplete.yaml
|
||||
│ │ └── subscription.yaml
|
||||
│ ├── core/ # P1 flows - Run before release
|
||||
│ │ ├── browseAndPlay.yaml
|
||||
│ │ ├── categoryFilter.yaml
|
||||
│ │ ├── collections.yaml
|
||||
│ │ └── trainers.yaml
|
||||
│ └── regression/ # P2 flows - Run nightly
|
||||
│ ├── activityHistory.yaml
|
||||
│ ├── offlineMode.yaml
|
||||
│ └── settings.yaml
|
||||
├── helpers/
|
||||
│ ├── common.yaml # Shared test steps
|
||||
│ ├── assertions.yaml # Custom assertions
|
||||
│ └── mock-data.yaml # Test data
|
||||
└── environments/
|
||||
├── staging.yaml
|
||||
└── production.yaml
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Installation & Setup
|
||||
|
||||
### 1. Install Maestro CLI
|
||||
|
||||
```bash
|
||||
# macOS/Linux
|
||||
curl -Ls "https://get.maestro.mobile.dev" | bash
|
||||
|
||||
# Verify installation
|
||||
maestro --version
|
||||
```
|
||||
|
||||
### 2. Setup Test Directory Structure
|
||||
|
||||
```bash
|
||||
mkdir -p .maestro/flows/{critical,core,regression}
|
||||
mkdir -p .maestro/helpers
|
||||
mkdir -p .maestro/environments
|
||||
```
|
||||
|
||||
### 3. Maestro Configuration (`config.yaml`)
|
||||
|
||||
```yaml
|
||||
# .maestro/config.yaml
|
||||
appId: com.tabatafit.app
|
||||
name: TabataFit E2E Tests
|
||||
|
||||
# Timeouts
|
||||
timeout: 30000 # 30 seconds default
|
||||
retries: 2
|
||||
|
||||
# Environment variables
|
||||
env:
|
||||
TEST_USER_NAME: "Test User"
|
||||
TEST_USER_EMAIL: "test@example.com"
|
||||
|
||||
# Include flows
|
||||
include:
|
||||
- flows/critical/*.yaml
|
||||
- flows/core/*.yaml
|
||||
|
||||
# Exclude on CI
|
||||
exclude:
|
||||
- flows/regression/offlineMode.yaml # Requires airplane mode
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## P0 Critical Test Flows
|
||||
|
||||
### Test 1: Complete Onboarding Flow
|
||||
|
||||
**File:** `.maestro/flows/critical/onboarding.yaml`
|
||||
|
||||
```yaml
|
||||
appId: com.tabatafit.app
|
||||
name: Complete Onboarding & First Workout
|
||||
|
||||
onFlowStart:
|
||||
- clearState
|
||||
|
||||
steps:
|
||||
# Splash/Loading
|
||||
- waitForAnimationToEnd:
|
||||
timeout: 5000
|
||||
|
||||
# Screen 1: Problem - "Not Enough Time"
|
||||
- assertVisible: "Not enough time"
|
||||
- tapOn: "Continue"
|
||||
|
||||
# Screen 2: Empathy
|
||||
- assertVisible: "We get it"
|
||||
- tapOn: "Continue"
|
||||
|
||||
# Screen 3: Solution
|
||||
- assertVisible: "4-minute workouts"
|
||||
- tapOn: "Continue"
|
||||
|
||||
# Screen 4: Wow Moment
|
||||
- assertVisible: "Transform your body"
|
||||
- tapOn: "Get Started"
|
||||
|
||||
# Screen 5: Personalization
|
||||
- tapOn: "Name input"
|
||||
- inputText: "Test User"
|
||||
- tapOn: "Beginner"
|
||||
- tapOn: "Lose Weight"
|
||||
- tapOn: "3 times per week"
|
||||
- tapOn: "Start My Journey"
|
||||
|
||||
# Screen 6: Paywall (or skip in test env)
|
||||
- runScript: |
|
||||
if (maestro.env.SKIP_PAYWALL === 'true') {
|
||||
maestro.tapOn('Maybe Later');
|
||||
}
|
||||
|
||||
# Should land on Home
|
||||
- assertVisible: "Good morning|Good afternoon|Good evening"
|
||||
- assertVisible: "Test User"
|
||||
|
||||
onFlowComplete:
|
||||
- takeScreenshot: "onboarding-complete"
|
||||
```
|
||||
|
||||
### Test 2: Browse, Select, and Complete Workout
|
||||
|
||||
**File:** `.maestro/flows/critical/workoutComplete.yaml`
|
||||
|
||||
```yaml
|
||||
appId: com.tabatafit.app
|
||||
name: Browse, Play & Complete Workout
|
||||
|
||||
steps:
|
||||
# Navigate to Workouts tab
|
||||
- tapOn: "Workouts"
|
||||
- waitForAnimationToEnd
|
||||
|
||||
# Wait for data to load
|
||||
- assertVisible: "All|Full Body|Core|Upper Body"
|
||||
|
||||
# Select first workout
|
||||
- tapOn:
|
||||
id: "workout-card-0"
|
||||
optional: false
|
||||
|
||||
# Workout Detail Screen
|
||||
- assertVisible: "Start Workout"
|
||||
- tapOn: "Start Workout"
|
||||
|
||||
# Player Screen
|
||||
- waitForAnimationToEnd:
|
||||
timeout: 3000
|
||||
|
||||
# Verify timer is running
|
||||
- assertVisible: "Get Ready|WORK|REST"
|
||||
|
||||
# Fast-forward through workout (simulation)
|
||||
- repeat:
|
||||
times: 3
|
||||
commands:
|
||||
- waitForAnimationToEnd:
|
||||
timeout: 5000
|
||||
- assertVisible: "WORK|REST"
|
||||
|
||||
# Complete workout
|
||||
- tapOn:
|
||||
id: "done-button"
|
||||
optional: true
|
||||
|
||||
# Complete Screen
|
||||
- assertVisible: "Workout Complete|Great Job"
|
||||
- assertVisible: "Calories"
|
||||
- assertVisible: "Duration"
|
||||
|
||||
# Return to home
|
||||
- tapOn: "Done|Continue"
|
||||
- assertVisible: "Home|Workouts"
|
||||
|
||||
onFlowComplete:
|
||||
- takeScreenshot: "workout-completed"
|
||||
```
|
||||
|
||||
### Test 3: Subscription Purchase Flow
|
||||
|
||||
**File:** `.maestro/flows/critical/subscription.yaml`
|
||||
|
||||
```yaml
|
||||
appId: com.tabatafit.app
|
||||
name: Subscription Purchase Flow
|
||||
|
||||
steps:
|
||||
# Trigger paywall (via profile or workout limit)
|
||||
- tapOn: "Profile"
|
||||
- tapOn: "Upgrade to Premium"
|
||||
|
||||
# Paywall Screen
|
||||
- assertVisible: "Unlock Everything|Premium"
|
||||
- assertVisible: "yearly|monthly"
|
||||
|
||||
# Select plan
|
||||
- tapOn:
|
||||
id: "yearly-plan"
|
||||
|
||||
# Verify Apple Pay/Google Pay sheet appears
|
||||
- assertVisible: "Subscribe|Confirm"
|
||||
|
||||
# Note: Actual purchase is mocked in test env
|
||||
- runScript: |
|
||||
if (maestro.env.USE_MOCK_PURCHASE === 'true') {
|
||||
maestro.tapOn('Mock Purchase Success');
|
||||
}
|
||||
|
||||
# Verify premium activated
|
||||
- assertVisible: "Premium Active|You're all set"
|
||||
|
||||
tags:
|
||||
- purchase
|
||||
- revenue-critical
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## P1 Core Test Flows
|
||||
|
||||
### Test 4: Category Filtering
|
||||
|
||||
**File:** `.maestro/flows/core/categoryFilter.yaml`
|
||||
|
||||
```yaml
|
||||
appId: com.tabatafit.app
|
||||
name: Category Filtering
|
||||
|
||||
steps:
|
||||
- tapOn: "Workouts"
|
||||
- waitForAnimationToEnd
|
||||
|
||||
# Test each category
|
||||
- tapOn: "Full Body"
|
||||
- assertVisible: "Full Body"
|
||||
|
||||
- tapOn: "Core"
|
||||
- assertVisible: "Core"
|
||||
|
||||
- tapOn: "Cardio"
|
||||
- assertVisible: "Cardio"
|
||||
|
||||
- tapOn: "All"
|
||||
- assertVisible: "All Workouts"
|
||||
|
||||
# Verify filter changes content
|
||||
- runScript: |
|
||||
const before = maestro.getElementText('workout-count');
|
||||
maestro.tapOn('Core');
|
||||
const after = maestro.getElementText('workout-count');
|
||||
assert(before !== after, 'Filter should change workout count');
|
||||
```
|
||||
|
||||
### Test 5: Collection Navigation
|
||||
|
||||
**File:** `.maestro/flows/core/collections.yaml`
|
||||
|
||||
```yaml
|
||||
appId: com.tabatafit.app
|
||||
name: Collection Navigation
|
||||
|
||||
steps:
|
||||
- tapOn: "Browse"
|
||||
- waitForAnimationToEnd
|
||||
|
||||
# Scroll to collections
|
||||
- swipe:
|
||||
direction: UP
|
||||
duration: 1000
|
||||
|
||||
# Tap first collection
|
||||
- tapOn:
|
||||
id: "collection-card-0"
|
||||
|
||||
# Collection Detail Screen
|
||||
- assertVisible: "Collection"
|
||||
- assertVisible: "workouts"
|
||||
|
||||
# Start collection workout
|
||||
- tapOn: "Start"
|
||||
- assertVisible: "Player|Timer"
|
||||
|
||||
onFlowComplete:
|
||||
- takeScreenshot: "collection-navigation"
|
||||
```
|
||||
|
||||
### Test 6: Trainer Discovery
|
||||
|
||||
**File:** `.maestro/flows/core/trainers.yaml`
|
||||
|
||||
```yaml
|
||||
appId: com.tabatafit.app
|
||||
name: Trainer Discovery
|
||||
|
||||
steps:
|
||||
- tapOn: "Browse"
|
||||
|
||||
# Navigate to trainers section
|
||||
- swipe:
|
||||
direction: UP
|
||||
|
||||
# Select trainer
|
||||
- tapOn:
|
||||
id: "trainer-card-0"
|
||||
|
||||
# Verify trainer profile
|
||||
- assertVisible: "workouts"
|
||||
|
||||
# Select trainer's workout
|
||||
- tapOn:
|
||||
id: "workout-card-0"
|
||||
|
||||
# Should show workout detail
|
||||
- assertVisible: "Start Workout"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Reusable Test Helpers
|
||||
|
||||
### Common Actions (`helpers/common.yaml`)
|
||||
|
||||
```yaml
|
||||
# .maestro/helpers/common.yaml
|
||||
appId: com.tabatafit.app
|
||||
|
||||
# Launch app fresh
|
||||
- launchApp:
|
||||
clearState: true
|
||||
|
||||
# Wait for data loading
|
||||
- waitForDataLoad:
|
||||
commands:
|
||||
- waitForAnimationToEnd:
|
||||
timeout: 3000
|
||||
- assertVisible: ".*" # Any content loaded
|
||||
|
||||
# Handle permission dialogs
|
||||
- handlePermissions:
|
||||
commands:
|
||||
- tapOn:
|
||||
text: "Allow"
|
||||
optional: true
|
||||
- tapOn:
|
||||
text: "OK"
|
||||
optional: true
|
||||
|
||||
# Navigate to tab
|
||||
- navigateToTab:
|
||||
params:
|
||||
tabName: ${tab}
|
||||
commands:
|
||||
- tapOn: ${tab}
|
||||
|
||||
# Start workout from detail
|
||||
- startWorkout:
|
||||
commands:
|
||||
- tapOn: "Start Workout"
|
||||
- waitForAnimationToEnd:
|
||||
timeout: 5000
|
||||
- assertVisible: "Get Ready|WORK"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Running Tests
|
||||
|
||||
### Local Development
|
||||
|
||||
```bash
|
||||
# Install Maestro
|
||||
curl -Ls "https://get.maestro.mobile.dev" | bash
|
||||
|
||||
# Run single test
|
||||
maestro test .maestro/flows/critical/onboarding.yaml
|
||||
|
||||
# Run all critical tests
|
||||
maestro test .maestro/flows/critical/
|
||||
|
||||
# Run with specific environment
|
||||
maestro test --env SKIP_PAYWALL=true .maestro/flows/
|
||||
|
||||
# Record video of test
|
||||
maestro record .maestro/flows/critical/workoutComplete.yaml
|
||||
|
||||
# Run with tags
|
||||
maestro test --include-tags=critical .maestro/flows/
|
||||
```
|
||||
|
||||
### CI/CD Integration (GitHub Actions)
|
||||
|
||||
```yaml
|
||||
# .github/workflows/maestro.yml
|
||||
name: Maestro E2E Tests
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
pull_request:
|
||||
branches: [main]
|
||||
|
||||
jobs:
|
||||
e2e-tests:
|
||||
runs-on: macos-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@v3
|
||||
|
||||
- name: Install Maestro
|
||||
run: curl -Ls "https://get.maestro.mobile.dev" | bash
|
||||
|
||||
- name: Start iOS Simulator
|
||||
run: |
|
||||
xcrun simctl boot "iPhone 15"
|
||||
sleep 10
|
||||
|
||||
- name: Install App
|
||||
run: |
|
||||
npm install
|
||||
npx expo prebuild
|
||||
npx pod install
|
||||
npx react-native run-ios --simulator="iPhone 15"
|
||||
|
||||
- name: Run Critical Tests
|
||||
run: |
|
||||
export MAESTRO_DRIVER_STARTUP_TIMEOUT=120000
|
||||
maestro test .maestro/flows/critical/
|
||||
|
||||
- name: Upload Test Results
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: maestro-results
|
||||
path: |
|
||||
~/.maestro/tests/
|
||||
*.png
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Test Coverage Matrix
|
||||
|
||||
| Feature | Test File | Priority | Frequency | Status |
|
||||
|---------|-----------|----------|-----------|--------|
|
||||
| Onboarding | `onboarding.yaml` | P0 | Every PR | ⏳ Pending |
|
||||
| Workout Play | `workoutComplete.yaml` | P0 | Every PR | ⏳ Pending |
|
||||
| Purchase | `subscription.yaml` | P0 | Every PR | ⏳ Pending |
|
||||
| Category Filter | `categoryFilter.yaml` | P1 | Pre-release | ⏳ Pending |
|
||||
| Collections | `collections.yaml` | P1 | Pre-release | ⏳ Pending |
|
||||
| Trainers | `trainers.yaml` | P1 | Pre-release | ⏳ Pending |
|
||||
| Activity | `activityHistory.yaml` | P2 | Nightly | ⏳ Pending |
|
||||
| Offline | `offlineMode.yaml` | P2 | Weekly | ⏳ Pending |
|
||||
|
||||
---
|
||||
|
||||
## React Native Prerequisites
|
||||
|
||||
Before running tests, add `testID` props to components for reliable selectors:
|
||||
|
||||
```tsx
|
||||
// WorkoutCard.tsx
|
||||
<Pressable testID={`workout-card-${index}`}>
|
||||
{/* ... */}
|
||||
</Pressable>
|
||||
|
||||
// WorkoutPlayer.tsx
|
||||
<Button testID="done-button" title="Done" />
|
||||
|
||||
// Paywall.tsx
|
||||
<Pressable testID="yearly-plan">
|
||||
{/* ... */}
|
||||
</Pressable>
|
||||
```
|
||||
|
||||
### Required testIDs Checklist
|
||||
|
||||
- [ ] `workout-card-{index}` - Workout list items
|
||||
- [ ] `collection-card-{index}` - Collection items
|
||||
- [ ] `trainer-card-{index}` - Trainer items
|
||||
- [ ] `done-button` - Complete workout button
|
||||
- [ ] `yearly-plan` / `monthly-plan` - Subscription plans
|
||||
- [ ] `start-workout-button` - Start workout CTA
|
||||
- [ ] `category-{name}` - Category filter buttons
|
||||
- [ ] `tab-{name}` - Bottom navigation tabs
|
||||
|
||||
---
|
||||
|
||||
## Environment Variables
|
||||
|
||||
Create `.env.maestro` file:
|
||||
|
||||
```bash
|
||||
# Test Configuration
|
||||
SKIP_PAYWALL=true
|
||||
USE_MOCK_PURCHASE=true
|
||||
TEST_USER_NAME=Test User
|
||||
TEST_USER_EMAIL=test@example.com
|
||||
|
||||
# API Configuration (if needed)
|
||||
API_BASE_URL=https://api-staging.tabatafit.com
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Common Issues
|
||||
|
||||
1. **Tests fail on first run**
|
||||
- Clear app state: `maestro test --clear-state`
|
||||
- Increase timeout in config.yaml
|
||||
|
||||
2. **Element not found**
|
||||
- Verify testID is set correctly
|
||||
- Add wait times before assertions
|
||||
- Check for animations completing
|
||||
|
||||
3. **Purchase tests fail**
|
||||
- Ensure `USE_MOCK_PURCHASE=true` in test env
|
||||
- Use sandbox/test products
|
||||
|
||||
4. **Slow tests**
|
||||
- Use `waitForAnimationToEnd` with shorter timeouts
|
||||
- Disable animations in test builds
|
||||
|
||||
### Debug Commands
|
||||
|
||||
```bash
|
||||
# Interactive mode
|
||||
maestro studio
|
||||
|
||||
# View hierarchy
|
||||
maestro hierarchy
|
||||
|
||||
# Record test execution
|
||||
maestro record <test-file>
|
||||
|
||||
# Verbose logging
|
||||
maestro test --verbose <test-file>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Next Steps (After Features Are Complete)
|
||||
|
||||
1. ✅ Create `.maestro/` directory structure
|
||||
2. ✅ Write `config.yaml`
|
||||
3. ✅ Implement P0 critical test flows
|
||||
4. ✅ Add testIDs to React Native components
|
||||
5. ✅ Run tests locally
|
||||
6. ✅ Setup CI/CD pipeline
|
||||
7. ⏳ Implement P1 core test flows
|
||||
8. ⏳ Add visual regression tests
|
||||
9. ⏳ Setup nightly regression suite
|
||||
|
||||
---
|
||||
|
||||
## Resources
|
||||
|
||||
- [Maestro Documentation](https://maestro.mobile.dev/)
|
||||
- [Maestro YAML Reference](https://maestro.mobile.dev/api-reference/commands)
|
||||
- [React Native Testing with Maestro](https://maestro.mobile.dev/platform-support/react-native)
|
||||
- [Maestro Best Practices](https://maestro.mobile.dev/advanced/best-practices)
|
||||
|
||||
---
|
||||
|
||||
**Created:** March 17, 2026
|
||||
**Status:** Implementation Pending (Waiting for feature completion)
|
||||
@@ -1,486 +0,0 @@
|
||||
# TabataFit — UI Feature Brief
|
||||
|
||||
> Generated for Google Stitch design handoff.
|
||||
> Covers all end-user screens, interactions, states, and navigation flows.
|
||||
|
||||
---
|
||||
|
||||
## App Overview
|
||||
|
||||
**TabataFit** is a mobile fitness app ("Apple Fitness+ for Tabata") built with React Native / Expo. It delivers guided Tabata HIIT workouts with video, voice coaching, music, and Apple Watch heart-rate sync.
|
||||
|
||||
### Design System
|
||||
|
||||
| Token | Value | Usage |
|
||||
|-------|-------|-------|
|
||||
| Background | `#000000` | Pure black base |
|
||||
| Surface | `#1C1C1E` | Cards, sheets |
|
||||
| Brand | `#FF6B35` | Flame orange — primary accent |
|
||||
| Rest | `#5AC8FA` | Ice blue — rest phases |
|
||||
| Success | `#30D158` | Energy green — completion |
|
||||
| Prep phase | `#FF9500` | Orange-yellow |
|
||||
| Work phase | `#FF6B35` | Flame orange |
|
||||
| Rest phase | `#5AC8FA` | Ice blue |
|
||||
| Complete phase | `#30D158` | Green |
|
||||
|
||||
- Supports **dark and light mode**
|
||||
- Multi-language (i18n)
|
||||
- Haptic feedback throughout
|
||||
|
||||
---
|
||||
|
||||
## Navigation Structure
|
||||
|
||||
```
|
||||
Root Stack
|
||||
├── Onboarding (6-step flow)
|
||||
├── (tabs)
|
||||
│ ├── Home — index
|
||||
│ ├── Explore — browse workouts
|
||||
│ ├── Activity — stats & history
|
||||
│ └── Profile — settings & account
|
||||
├── workout/[id] — Workout detail (push)
|
||||
├── program/[id] — Program detail (push)
|
||||
├── collection/[id] — Collection detail (push)
|
||||
├── player/[id] — Workout player (push, full-screen)
|
||||
├── complete/[id] — Post-workout celebration (push)
|
||||
├── paywall — Premium upsell (modal)
|
||||
├── explore-filters — Filter sheet (form sheet modal)
|
||||
└── privacy — Privacy policy (push)
|
||||
```
|
||||
|
||||
**Tab bar**: 4 tabs — Home, Explore, Activity, Profile. SF Symbol icons. Badge support.
|
||||
|
||||
---
|
||||
|
||||
## 1. Onboarding Flow
|
||||
|
||||
A 6-screen linear funnel shown on first launch. Progress dots at top. Skip available on some steps.
|
||||
|
||||
### 1.1 Problem Screen
|
||||
- **Purpose**: Motivational hook about time constraints
|
||||
- **Elements**: Headline text, subtitle, illustration
|
||||
- **CTA**: Continue
|
||||
|
||||
### 1.2 Empathy Screen
|
||||
- **Purpose**: User selects fitness barriers to build rapport
|
||||
- **Elements**: Grid of 4 selectable cards — "No time", "Low motivation", "No knowledge", "No gym"
|
||||
- **Interaction**: Tap to select, max 2 selections, visual highlight on selected
|
||||
- **CTA**: Continue (enabled after 1+ selection)
|
||||
|
||||
### 1.3 Solution Screen
|
||||
- **Purpose**: Show Tabata's effectiveness
|
||||
- **Elements**: Animated comparison bar chart (Tabata vs traditional cardio calorie burn)
|
||||
- **CTA**: Continue
|
||||
|
||||
### 1.4 Wow Screen
|
||||
- **Purpose**: Reveal key app features
|
||||
- **Elements**: 4 feature cards with staggered entrance animations — Timer, Exercises, Voice Coaching, Progress Tracking
|
||||
- **CTA**: Continue
|
||||
|
||||
### 1.5 Personalization Screen
|
||||
- **Purpose**: Collect user preferences to personalize experience
|
||||
- **Inputs**:
|
||||
- Name (text input)
|
||||
- Fitness level: Beginner / Intermediate / Advanced (single select chips)
|
||||
- Goal: Weight Loss / Cardio / Strength / Wellness (single select chips)
|
||||
- Weekly frequency: 2x / 3x / 5x per week (single select chips)
|
||||
- **CTA**: Continue (enabled when all fields filled)
|
||||
|
||||
### 1.6 Paywall Screen (Onboarding variant)
|
||||
- **Purpose**: Premium conversion at end of onboarding
|
||||
- **Elements**: Premium features list, yearly/monthly plan toggle with real prices from RevenueCat
|
||||
- **CTAs**: Subscribe, Restore Purchases, Skip (close button)
|
||||
- **States**: Loading prices, purchase in progress, error
|
||||
|
||||
---
|
||||
|
||||
## 2. Home Tab
|
||||
|
||||
Personalized dashboard and primary entry point.
|
||||
|
||||
### Elements
|
||||
- **Greeting header**: Time-based ("Good morning/afternoon/evening") + user's name + animated mascot
|
||||
- **Streak badge**: Current streak count with flame icon
|
||||
- **Quick stats row**: 3 stat pills — Current streak, This week (workouts), Total minutes
|
||||
- **Assessment card**: Feature-flagged (currently OFF) — fitness assessment prompt
|
||||
- **Program cards**: 3 horizontal cards (Upper Body, Lower Body, Full Body)
|
||||
- Each shows: icon, title, progress bar (% complete), status badge (Not Started / In Progress / Completed)
|
||||
- CTA per card: Start / Continue / Restart (depends on state)
|
||||
- **Switch program button**: Opens program selection
|
||||
|
||||
### Navigation
|
||||
- Tap program card → `program/[id]`
|
||||
- Tap "Start" on program → `player/[id]` (first workout)
|
||||
- Tap "Continue" → `player/[id]` (next incomplete workout)
|
||||
|
||||
### States
|
||||
- **New user**: 0 stats, no streak, programs at 0%
|
||||
- **Returning user**: Populated stats, active streak, program progress
|
||||
|
||||
---
|
||||
|
||||
## 3. Explore Tab
|
||||
|
||||
Browse, search, and filter the full workout catalog.
|
||||
|
||||
### Elements
|
||||
- **Search bar**: Search by workout title, trainer name, exercise name, category. Real-time filtering.
|
||||
- **Featured collection**: Hero card at top with image, title, workout count. Tap → `collection/[id]`
|
||||
- **Trainer avatars**: Horizontal scroll of circular trainer photos. Tap to filter workouts by trainer.
|
||||
- **Collections carousel**: Horizontal scroll of collection cards. Tap → `collection/[id]`
|
||||
- **Recommended For You**: Horizontal workout card list, personalized based on workout history
|
||||
- **Featured workouts**: Grid of highlighted workouts
|
||||
- **All Workouts section**:
|
||||
- Category filter pills: All, Full Body, Upper Body, Lower Body, Core, Cardio
|
||||
- Filter button → opens `explore-filters` sheet
|
||||
- Active filter indicator + clear filters button
|
||||
- 2-column workout card grid
|
||||
|
||||
### Workout Card
|
||||
- Thumbnail image
|
||||
- Duration badge overlay
|
||||
- Title, trainer name, level indicator
|
||||
- Lock icon if premium-only and user is free tier
|
||||
|
||||
### Navigation
|
||||
- Tap workout card → `workout/[id]`
|
||||
- Tap collection → `collection/[id]`
|
||||
- Tap trainer avatar → filters workout list by that trainer
|
||||
- Tap filter button → `explore-filters` (form sheet modal)
|
||||
|
||||
### States
|
||||
- **Loading**: Skeleton placeholders for cards
|
||||
- **Error**: Error message with Retry button
|
||||
- **Empty search**: "No workouts found" message
|
||||
- **Filtered**: Active filter chips shown, clear all button
|
||||
|
||||
---
|
||||
|
||||
## 4. Activity Tab
|
||||
|
||||
Workout history, statistics, and achievements.
|
||||
|
||||
### Elements
|
||||
- **Streak banner**: Current streak + longest streak (flame icons)
|
||||
- **Stats grid** (2x2): Each stat in a card with circular progress ring
|
||||
- Total workouts (ring fills toward goal)
|
||||
- Total minutes
|
||||
- Total calories
|
||||
- Best streak
|
||||
- **Weekly bar chart**: Sun–Sat, each bar filled if a workout was completed that day, current day highlighted
|
||||
- **Recent workouts list**: Last 5 workouts
|
||||
- Each row: workout title, relative time ("2h ago"), duration, calories
|
||||
- Tap → `workout/[id]`
|
||||
- **Achievements grid**: 4 achievement badges displayed
|
||||
- Types: workouts milestone, streak milestone, minutes milestone, calories milestone
|
||||
- States: locked (greyed out) / unlocked (colored with checkmark)
|
||||
|
||||
### States
|
||||
- **Empty**: No workouts yet — motivational message + "Start Your First Workout" CTA → `explore`
|
||||
- **Populated**: All sections visible with data
|
||||
|
||||
---
|
||||
|
||||
## 5. Profile Tab
|
||||
|
||||
User settings, account management, and app info.
|
||||
|
||||
### Elements
|
||||
- **User header**: Avatar circle with initial, display name, plan label ("Free" or "TabataFit+")
|
||||
- **Stats row**: 3 inline stats — workouts count, streak, calories
|
||||
- **Upgrade CTA** (free users only): Gradient button → `paywall`
|
||||
|
||||
#### Workout Settings Section
|
||||
- Haptic feedback toggle
|
||||
- Sound effects toggle
|
||||
- Voice coaching toggle
|
||||
|
||||
#### Notifications Section
|
||||
- Daily reminders toggle
|
||||
- Reminder time display (when enabled)
|
||||
|
||||
#### Personalization Section (premium only)
|
||||
- Sync status indicator
|
||||
|
||||
#### About Section
|
||||
- Version number
|
||||
- Rate App → opens App Store rating prompt
|
||||
- Contact Us → opens email compose
|
||||
- FAQ → opens external web link
|
||||
- Privacy Policy → `privacy` screen
|
||||
|
||||
#### Account Section (premium only)
|
||||
- Restore Purchases → triggers RevenueCat restore
|
||||
|
||||
#### Danger Zone
|
||||
- Sign Out button
|
||||
- Data deletion: triggers confirmation modal
|
||||
|
||||
### Data Deletion Modal
|
||||
- Warning text explaining data loss
|
||||
- Cancel / Delete buttons
|
||||
- Delete is destructive (red)
|
||||
|
||||
---
|
||||
|
||||
## 6. Workout Detail Screen
|
||||
|
||||
Pre-workout information screen. Reached by tapping any workout card.
|
||||
|
||||
**Route**: `workout/[id]`
|
||||
|
||||
### Elements
|
||||
- **Header**: Thumbnail or video preview, back button, heart/save button (toggle)
|
||||
- **Title**: Workout name
|
||||
- **Trainer**: Trainer name (colored text)
|
||||
- **Metadata row**: Duration (minutes), Calories estimate, Level badge (Beginner/Intermediate/Advanced)
|
||||
- **Equipment list**: Icons + labels for required equipment (or "No equipment")
|
||||
- **Timing card**: Prep time, Work time, Rest time, Rounds — displayed in a structured card
|
||||
- **Exercise list**: Ordered list of exercises with individual durations
|
||||
- **Repeat rounds indicator**: Shows if rounds repeat the exercise sequence
|
||||
- **Music vibe label**: Genre/mood of the workout soundtrack
|
||||
|
||||
### CTAs
|
||||
- **Start Workout** → `player/[id]` (if unlocked or user is premium)
|
||||
- **Unlock with TabataFit+** → `paywall` (if locked and user is free tier)
|
||||
|
||||
### Header Actions
|
||||
- **Back**: Navigate back
|
||||
- **Save/Unsave**: Heart icon toggle — saves workout to favorites
|
||||
|
||||
### States
|
||||
- **Loading**: Skeleton layout
|
||||
- **Unlocked**: Full detail visible, "Start Workout" CTA
|
||||
- **Locked**: Full detail visible but "Unlock with TabataFit+" CTA replaces start button
|
||||
|
||||
---
|
||||
|
||||
## 7. Program Detail Screen
|
||||
|
||||
Multi-week training program overview with per-week workout breakdown.
|
||||
|
||||
**Route**: `program/[id]`
|
||||
|
||||
### Elements
|
||||
- **Header**: Program icon, title, subtitle (e.g., "4 weeks · 12 workouts")
|
||||
- **Description**: Program summary text
|
||||
- **Stats card**: 3 stats — Weeks, Workouts, Total Minutes
|
||||
- **Tags**: Equipment required (e.g., Dumbbells, Mat) + Equipment optional + Focus areas (e.g., Arms, Core)
|
||||
- **Progress bar** (if started): Percentage complete with label
|
||||
- **Training plan**: Expandable week sections
|
||||
- Each week shows its workouts in order
|
||||
- Workout rows show: title, duration, completion checkmark (if done)
|
||||
- Current week has a "Current" badge
|
||||
- Future weeks may show lock icons (progressive unlock)
|
||||
|
||||
### CTAs
|
||||
- **Start Program** (not started) → `player/[id]` (first workout)
|
||||
- **Continue Training** (in progress) → `player/[id]` (next incomplete workout)
|
||||
- **Restart** (completed) → resets progress, starts from week 1
|
||||
|
||||
### States
|
||||
- **Not Started**: 0% progress, all weeks shown, "Start Program" CTA
|
||||
- **In Progress**: Progress bar filled, completed workouts checked, "Continue Training" CTA
|
||||
- **Completed**: 100% progress, all checked, "Restart" CTA
|
||||
|
||||
---
|
||||
|
||||
## 8. Collection Detail Screen
|
||||
|
||||
A curated group of workouts.
|
||||
|
||||
**Route**: `collection/[id]`
|
||||
|
||||
### Elements
|
||||
- **Header**: Collection title, description, workout count
|
||||
- **Workout list**: Vertical list of workout cards in the collection
|
||||
- Each card: thumbnail, title, trainer, duration, level
|
||||
- Lock icon for premium-gated workouts
|
||||
|
||||
### Navigation
|
||||
- Tap workout → `workout/[id]`
|
||||
- Back button → previous screen
|
||||
|
||||
---
|
||||
|
||||
## 9. Player Screen
|
||||
|
||||
Full-screen workout execution with timer, video, audio, and Watch sync.
|
||||
|
||||
**Route**: `player/[id]`
|
||||
|
||||
### Layout
|
||||
- **Full-screen dark mode** — no tab bar, no status bar chrome
|
||||
- **Background**: Workout video (HLS streaming) or gradient fallback
|
||||
- **Phase-colored tint**: Background overlay changes color per phase (prep=orange, work=flame, rest=blue, complete=green)
|
||||
|
||||
### Timer Section
|
||||
- **Timer ring**: Large circular progress indicator, fills as phase progresses
|
||||
- **Phase label**: PREP / WORK / REST / COMPLETE (color-coded)
|
||||
- **Countdown**: Large MM:SS timer (uses tabular-nums for alignment)
|
||||
- **Round indicator**: "Round 3 of 8" text
|
||||
|
||||
### Exercise Info
|
||||
- **Current exercise name**: Large text
|
||||
- **Next exercise preview**: Smaller text ("Up next: Burpees")
|
||||
- **Coach encouragement**: Motivational text overlays (e.g., "Keep going!", "Almost there!")
|
||||
|
||||
### Controls
|
||||
- **Start**: Begins the workout (shown before first start)
|
||||
- **Pause / Resume**: Toggle button during workout
|
||||
- **Stop**: Ends workout early (confirmation prompt)
|
||||
- **Skip**: Skip to next phase
|
||||
|
||||
### Stats Overlay
|
||||
- **Calories**: Running calorie count
|
||||
- **Heart rate**: BPM from Apple Watch (if connected)
|
||||
- **Rounds**: Current / total
|
||||
|
||||
### Burn Bar
|
||||
- Horizontal bar comparing user's current calorie burn vs. average for this workout
|
||||
- Updates in real-time
|
||||
|
||||
### Now Playing Pill
|
||||
- Shows current music track name
|
||||
- Skip track button
|
||||
|
||||
### Audio & Haptics
|
||||
- **Sound effects**: Phase start chime, 3-2-1 countdown beeps, workout complete fanfare
|
||||
- **Haptic feedback**: Phase transitions, countdown ticks, button presses
|
||||
- **Voice coaching**: Audio cues for exercises and encouragement
|
||||
- **Screen stays awake** (useKeepAwake)
|
||||
|
||||
### Apple Watch Integration
|
||||
- Sends: workout state (phase, timer, exercise)
|
||||
- Receives: play/pause, skip, stop commands, heart rate data
|
||||
|
||||
### Completion State
|
||||
- Timer ring shows 100%
|
||||
- Phase label: COMPLETE
|
||||
- Summary: Rounds completed, calories burned, total minutes
|
||||
- **Done** CTA → `complete/[id]`
|
||||
|
||||
### States
|
||||
- **Ready**: Before starting — shows workout info, Start CTA
|
||||
- **Active**: Timer running, video playing, stats updating
|
||||
- **Paused**: Timer frozen, controls show Resume
|
||||
- **Complete**: Summary shown, Done CTA
|
||||
|
||||
---
|
||||
|
||||
## 10. Workout Complete Screen
|
||||
|
||||
Post-workout celebration and next steps.
|
||||
|
||||
**Route**: `complete/[id]`
|
||||
|
||||
### Elements
|
||||
- **Celebration animation**: Concentric emoji rings spinning (fire, muscle, lightning emojis)
|
||||
- **Stats grid**: 3 stats — Calories, Minutes, 100% completion
|
||||
- **Burn bar result**: Percentile comparison ("You burned more than 73% of users")
|
||||
- **Streak display**: Current streak count + subtitle ("Keep it going!")
|
||||
- **Share button**: Opens native share sheet with workout summary
|
||||
- **Recommended next workouts**: 3 horizontal workout cards
|
||||
- Tap → `workout/[id]`
|
||||
- **Back to Home** CTA → navigates to Home tab
|
||||
|
||||
### Sync Consent Modal
|
||||
- Appears after first workout for premium users
|
||||
- Prompts to enable cross-device data sync
|
||||
- Accept / Decline buttons
|
||||
|
||||
---
|
||||
|
||||
## 11. Paywall Screen
|
||||
|
||||
Premium subscription purchase flow.
|
||||
|
||||
**Route**: `paywall` (presented as modal)
|
||||
|
||||
### Elements
|
||||
- **Header**: "TabataFit+" branding
|
||||
- **Features grid**: 6 premium feature cards with icons
|
||||
- Music during workouts
|
||||
- Unlimited workouts
|
||||
- Detailed stats
|
||||
- Calorie tracking
|
||||
- Smart reminders
|
||||
- No ads
|
||||
- **Plan selection**: Two radio-style options
|
||||
- Yearly: Price/year + "Save 50%" badge (highlighted as best value)
|
||||
- Monthly: Price/month
|
||||
- Prices fetched live from RevenueCat
|
||||
- **Subscribe CTA**: Gradient button, shows selected plan price
|
||||
- **Restore purchases**: Text link below CTA
|
||||
- **Terms**: Privacy policy + terms of service links
|
||||
- **Close button**: X in top corner to dismiss
|
||||
|
||||
### States
|
||||
- **Loading**: Skeleton while fetching prices from RevenueCat
|
||||
- **Ready**: Plans displayed with real prices
|
||||
- **Purchasing**: Loading spinner on CTA, inputs disabled
|
||||
- **Error**: Error message with retry
|
||||
- **Success**: Dismisses modal, unlocks premium features
|
||||
|
||||
---
|
||||
|
||||
## 12. Explore Filters Sheet
|
||||
|
||||
Filter modal for the Explore tab workout grid.
|
||||
|
||||
**Route**: `explore-filters` (form sheet modal with grabber)
|
||||
|
||||
### Elements
|
||||
- **Level filter chips**: All / Beginner / Intermediate / Advanced (single select)
|
||||
- **Equipment filter chips**: All / None / Dumbbells / Band / Mat (dynamic from data, single select)
|
||||
- **Apply**: Dismiss sheet, filters persist in shared store
|
||||
- **Clear**: Reset all filters to "All"
|
||||
|
||||
---
|
||||
|
||||
## 13. Privacy Policy Screen
|
||||
|
||||
Static content screen.
|
||||
|
||||
**Route**: `privacy`
|
||||
|
||||
### Elements
|
||||
- Privacy policy text content
|
||||
- Back navigation
|
||||
|
||||
---
|
||||
|
||||
## Cross-Cutting Features
|
||||
|
||||
### Premium Gating
|
||||
- Free users see all workouts but some are locked (lock icon overlay)
|
||||
- Tapping a locked workout's "Start" CTA redirects to `paywall`
|
||||
- Premium users have full access to all workouts, stats sync, and personalization
|
||||
|
||||
### Internationalization (i18n)
|
||||
- All user-facing strings are translated via i18n system
|
||||
- Multi-language support throughout
|
||||
|
||||
### Haptic Feedback
|
||||
- Configurable via Profile settings toggle
|
||||
- Triggered on: button presses, phase changes, countdown ticks, achievements
|
||||
|
||||
### Analytics (PostHog)
|
||||
- Events tracked across all screens: screen views, button taps, workout starts/completions, purchases, onboarding steps
|
||||
|
||||
### Dark / Light Mode
|
||||
- Full theme support — colors adapt to system appearance
|
||||
- Player screen is always dark mode regardless of system setting
|
||||
|
||||
### Loading & Error States
|
||||
- Skeleton placeholders during data fetches
|
||||
- Error states with descriptive message + Retry button
|
||||
- Empty states with motivational messaging + CTAs
|
||||
|
||||
### Animations
|
||||
- Onboarding: staggered card reveals, animated charts
|
||||
- Home: mascot animation
|
||||
- Player: timer ring fill, phase color transitions
|
||||
- Complete: spinning emoji celebration rings
|
||||
- Navigation: standard iOS push/pop + modal presentations
|
||||
Reference in New Issue
Block a user