@croacroa/react-native-template 2.0.1 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (172) hide show
  1. package/.env.example +5 -0
  2. package/.eslintrc.js +8 -0
  3. package/.github/workflows/ci.yml +187 -187
  4. package/.github/workflows/eas-build.yml +55 -55
  5. package/.github/workflows/eas-update.yml +50 -50
  6. package/.github/workflows/npm-publish.yml +57 -0
  7. package/CHANGELOG.md +195 -106
  8. package/CONTRIBUTING.md +377 -377
  9. package/LICENSE +21 -0
  10. package/README.md +446 -399
  11. package/__tests__/accessibility/components.test.tsx +285 -0
  12. package/__tests__/components/Button.test.tsx +2 -4
  13. package/__tests__/components/__snapshots__/snapshots.test.tsx.snap +512 -0
  14. package/__tests__/components/snapshots.test.tsx +131 -131
  15. package/__tests__/helpers/a11y.ts +54 -0
  16. package/__tests__/hooks/useAnalytics.test.ts +100 -0
  17. package/__tests__/hooks/useAnimations.test.ts +70 -0
  18. package/__tests__/hooks/useAuth.test.tsx +71 -28
  19. package/__tests__/hooks/useMedia.test.ts +318 -0
  20. package/__tests__/hooks/usePayments.test.tsx +307 -0
  21. package/__tests__/hooks/usePermission.test.ts +230 -0
  22. package/__tests__/hooks/useWebSocket.test.ts +329 -0
  23. package/__tests__/integration/auth-api.test.tsx +224 -227
  24. package/__tests__/performance/VirtualizedList.perf.test.tsx +385 -362
  25. package/__tests__/services/api.test.ts +24 -6
  26. package/app/(auth)/home.tsx +11 -9
  27. package/app/(auth)/profile.tsx +8 -6
  28. package/app/(auth)/settings.tsx +11 -9
  29. package/app/(public)/forgot-password.tsx +25 -15
  30. package/app/(public)/login.tsx +48 -12
  31. package/app/(public)/onboarding.tsx +5 -5
  32. package/app/(public)/register.tsx +24 -15
  33. package/app/_layout.tsx +6 -3
  34. package/app.config.ts +27 -2
  35. package/assets/images/.gitkeep +7 -7
  36. package/assets/images/adaptive-icon.png +0 -0
  37. package/assets/images/favicon.png +0 -0
  38. package/assets/images/icon.png +0 -0
  39. package/assets/images/notification-icon.png +0 -0
  40. package/assets/images/splash.png +0 -0
  41. package/components/ErrorBoundary.tsx +73 -28
  42. package/components/auth/SocialLoginButtons.tsx +168 -0
  43. package/components/forms/FormInput.tsx +5 -3
  44. package/components/onboarding/OnboardingScreen.tsx +370 -370
  45. package/components/onboarding/index.ts +2 -2
  46. package/components/providers/AnalyticsProvider.tsx +67 -0
  47. package/components/providers/SuspenseBoundary.tsx +359 -357
  48. package/components/providers/index.ts +24 -21
  49. package/components/ui/AnimatedButton.tsx +1 -9
  50. package/components/ui/AnimatedList.tsx +98 -0
  51. package/components/ui/AnimatedScreen.tsx +89 -0
  52. package/components/ui/Avatar.tsx +319 -316
  53. package/components/ui/Badge.tsx +416 -416
  54. package/components/ui/BottomSheet.tsx +307 -307
  55. package/components/ui/Button.tsx +11 -3
  56. package/components/ui/Checkbox.tsx +261 -261
  57. package/components/ui/FeatureGate.tsx +57 -0
  58. package/components/ui/ForceUpdateScreen.tsx +108 -0
  59. package/components/ui/ImagePickerButton.tsx +180 -0
  60. package/components/ui/Input.stories.tsx +2 -10
  61. package/components/ui/Input.tsx +2 -10
  62. package/components/ui/OptimizedImage.tsx +369 -369
  63. package/components/ui/Paywall.tsx +253 -0
  64. package/components/ui/PermissionGate.tsx +155 -0
  65. package/components/ui/PurchaseButton.tsx +84 -0
  66. package/components/ui/Select.tsx +240 -240
  67. package/components/ui/Skeleton.tsx +3 -1
  68. package/components/ui/Toast.tsx +427 -0
  69. package/components/ui/UploadProgress.tsx +189 -0
  70. package/components/ui/VirtualizedList.tsx +288 -285
  71. package/components/ui/index.ts +28 -23
  72. package/constants/config.ts +135 -97
  73. package/docs/adr/001-state-management.md +79 -79
  74. package/docs/adr/002-styling-approach.md +130 -130
  75. package/docs/adr/003-data-fetching.md +155 -155
  76. package/docs/adr/004-auth-adapter-pattern.md +144 -144
  77. package/docs/adr/README.md +78 -78
  78. package/docs/guides/analytics-posthog.md +121 -0
  79. package/docs/guides/auth-supabase.md +162 -0
  80. package/docs/guides/feature-flags-launchdarkly.md +150 -0
  81. package/docs/guides/payments-revenuecat.md +169 -0
  82. package/docs/plans/2026-02-22-phase6-implementation.md +3222 -0
  83. package/docs/plans/2026-02-22-phase6-template-completion-design.md +196 -0
  84. package/docs/plans/2026-02-23-npm-publish-design.md +31 -0
  85. package/docs/plans/2026-02-23-phase7-polish-documentation-design.md +79 -0
  86. package/docs/plans/2026-02-23-phase8-additional-features-design.md +136 -0
  87. package/eas.json +2 -1
  88. package/hooks/index.ts +70 -27
  89. package/hooks/useAnimatedEntry.ts +204 -0
  90. package/hooks/useApi.ts +64 -4
  91. package/hooks/useAuth.tsx +7 -3
  92. package/hooks/useBiometrics.ts +295 -295
  93. package/hooks/useChannel.ts +111 -0
  94. package/hooks/useDeepLinking.ts +256 -256
  95. package/hooks/useExperiment.ts +36 -0
  96. package/hooks/useFeatureFlag.ts +59 -0
  97. package/hooks/useForceUpdate.ts +91 -0
  98. package/hooks/useImagePicker.ts +281 -0
  99. package/hooks/useInAppReview.ts +64 -0
  100. package/hooks/useMFA.ts +509 -499
  101. package/hooks/useParallax.ts +142 -0
  102. package/hooks/usePerformance.ts +434 -434
  103. package/hooks/usePermission.ts +190 -0
  104. package/hooks/usePresence.ts +129 -0
  105. package/hooks/useProducts.ts +36 -0
  106. package/hooks/usePurchase.ts +103 -0
  107. package/hooks/useRateLimit.ts +70 -0
  108. package/hooks/useSubscription.ts +49 -0
  109. package/hooks/useTrackEvent.ts +52 -0
  110. package/hooks/useTrackScreen.ts +40 -0
  111. package/hooks/useUpdates.ts +358 -358
  112. package/hooks/useUpload.ts +165 -0
  113. package/hooks/useWebSocket.ts +111 -0
  114. package/i18n/index.ts +197 -194
  115. package/i18n/locales/ar.json +170 -101
  116. package/i18n/locales/de.json +170 -101
  117. package/i18n/locales/en.json +170 -101
  118. package/i18n/locales/es.json +170 -101
  119. package/i18n/locales/fr.json +170 -101
  120. package/jest.config.js +1 -1
  121. package/maestro/README.md +113 -113
  122. package/maestro/config.yaml +35 -35
  123. package/maestro/flows/login.yaml +62 -62
  124. package/maestro/flows/mfa-login.yaml +92 -92
  125. package/maestro/flows/mfa-setup.yaml +86 -86
  126. package/maestro/flows/navigation.yaml +68 -68
  127. package/maestro/flows/offline-conflict.yaml +101 -101
  128. package/maestro/flows/offline-sync.yaml +128 -128
  129. package/maestro/flows/offline.yaml +60 -60
  130. package/maestro/flows/register.yaml +94 -94
  131. package/package.json +188 -175
  132. package/scripts/generate-placeholders.js +38 -0
  133. package/services/analytics/adapters/console.ts +50 -0
  134. package/services/analytics/analytics-adapter.ts +94 -0
  135. package/services/analytics/types.ts +73 -0
  136. package/services/analytics.ts +428 -428
  137. package/services/api.ts +419 -340
  138. package/services/auth/social/apple.ts +110 -0
  139. package/services/auth/social/google.ts +159 -0
  140. package/services/auth/social/social-auth.ts +100 -0
  141. package/services/auth/social/types.ts +80 -0
  142. package/services/authAdapter.ts +333 -333
  143. package/services/backgroundSync.ts +652 -626
  144. package/services/feature-flags/adapters/mock.ts +108 -0
  145. package/services/feature-flags/feature-flag-adapter.ts +174 -0
  146. package/services/feature-flags/types.ts +79 -0
  147. package/services/force-update.ts +140 -0
  148. package/services/index.ts +116 -54
  149. package/services/media/compression.ts +91 -0
  150. package/services/media/media-picker.ts +151 -0
  151. package/services/media/media-upload.ts +160 -0
  152. package/services/payments/adapters/mock.ts +159 -0
  153. package/services/payments/payment-adapter.ts +118 -0
  154. package/services/payments/types.ts +131 -0
  155. package/services/permissions/permission-manager.ts +284 -0
  156. package/services/permissions/types.ts +104 -0
  157. package/services/realtime/types.ts +100 -0
  158. package/services/realtime/websocket-manager.ts +441 -0
  159. package/services/security.ts +289 -286
  160. package/services/sentry.ts +4 -4
  161. package/stores/appStore.ts +9 -0
  162. package/stores/notificationStore.ts +3 -1
  163. package/tailwind.config.js +47 -47
  164. package/tsconfig.json +37 -13
  165. package/types/user.ts +1 -1
  166. package/utils/accessibility.ts +446 -446
  167. package/utils/animations/presets.ts +182 -0
  168. package/utils/animations/transitions.ts +62 -0
  169. package/utils/index.ts +63 -52
  170. package/utils/toast.ts +9 -2
  171. package/utils/validation.ts +4 -1
  172. package/utils/withAccessibility.tsx +272 -272
@@ -1,101 +1,170 @@
1
- {
2
- "common": {
3
- "loading": "Chargement...",
4
- "error": "Erreur",
5
- "success": "Succès",
6
- "cancel": "Annuler",
7
- "confirm": "Confirmer",
8
- "save": "Enregistrer",
9
- "delete": "Supprimer",
10
- "edit": "Modifier",
11
- "close": "Fermer",
12
- "back": "Retour",
13
- "next": "Suivant",
14
- "done": "Terminé",
15
- "retry": "Réessayer",
16
- "search": "Rechercher",
17
- "noResults": "Aucun résultat trouvé",
18
- "offline": "Vous êtes hors ligne",
19
- "online": "De retour en ligne"
20
- },
21
- "auth": {
22
- "signIn": "Se connecter",
23
- "signUp": "S'inscrire",
24
- "signOut": "Se déconnecter",
25
- "email": "Email",
26
- "password": "Mot de passe",
27
- "confirmPassword": "Confirmer le mot de passe",
28
- "name": "Nom",
29
- "forgotPassword": "Mot de passe oublié ?",
30
- "resetPassword": "Réinitialiser le mot de passe",
31
- "noAccount": "Vous n'avez pas de compte ?",
32
- "haveAccount": "Vous avez déjà un compte ?",
33
- "welcomeBack": "Bon retour !",
34
- "signInToContinue": "Connectez-vous pour continuer",
35
- "createAccount": "Créer un compte",
36
- "joinUs": "Rejoignez-nous",
37
- "enterEmail": "Entrez votre email",
38
- "enterPassword": "Entrez votre mot de passe",
39
- "enterName": "Entrez votre nom",
40
- "passwordHint": "Au moins 8 caractères",
41
- "invalidCredentials": "Email ou mot de passe invalide",
42
- "accountCreated": "Compte créé avec succès !",
43
- "sessionExpired": "Session expirée. Veuillez vous reconnecter.",
44
- "biometric": {
45
- "title": "Authentification biométrique",
46
- "prompt": "Authentifiez-vous pour continuer",
47
- "fallback": "Utiliser le code",
48
- "enabled": "Connexion biométrique activée",
49
- "disabled": "Connexion biométrique désactivée",
50
- "notAvailable": "Authentification biométrique non disponible"
51
- }
52
- },
53
- "navigation": {
54
- "home": "Accueil",
55
- "profile": "Profil",
56
- "settings": "Paramètres",
57
- "notifications": "Notifications"
58
- },
59
- "profile": {
60
- "title": "Profil",
61
- "editProfile": "Modifier le profil",
62
- "changePhoto": "Changer la photo",
63
- "personalInfo": "Informations personnelles",
64
- "memberSince": "Membre depuis {{date}}"
65
- },
66
- "settings": {
67
- "title": "Paramètres",
68
- "appearance": "Apparence",
69
- "theme": "Thème",
70
- "themeLight": "Clair",
71
- "themeDark": "Sombre",
72
- "themeSystem": "Système",
73
- "language": "Langue",
74
- "notifications": "Notifications",
75
- "pushNotifications": "Notifications push",
76
- "emailNotifications": "Notifications par email",
77
- "security": "Sécurité",
78
- "biometricAuth": "Authentification biométrique",
79
- "changePassword": "Changer le mot de passe",
80
- "privacy": "Politique de confidentialité",
81
- "terms": "Conditions d'utilisation",
82
- "about": "À propos",
83
- "version": "Version",
84
- "deleteAccount": "Supprimer le compte"
85
- },
86
- "errors": {
87
- "generic": "Une erreur s'est produite",
88
- "network": "Erreur réseau. Vérifiez votre connexion.",
89
- "timeout": "Délai dépassé. Veuillez réessayer.",
90
- "unauthorized": "Vous n'êtes pas autorisé à effectuer cette action.",
91
- "notFound": "Ressource introuvable.",
92
- "validation": "Veuillez vérifier vos informations et réessayer."
93
- },
94
- "validation": {
95
- "required": "Ce champ est requis",
96
- "email": "Veuillez entrer un email valide",
97
- "passwordMin": "Le mot de passe doit contenir au moins 8 caractères",
98
- "passwordMatch": "Les mots de passe ne correspondent pas",
99
- "nameMin": "Le nom doit contenir au moins 2 caractères"
100
- }
101
- }
1
+ {
2
+ "common": {
3
+ "loading": "Chargement...",
4
+ "error": "Erreur",
5
+ "success": "Succès",
6
+ "cancel": "Annuler",
7
+ "confirm": "Confirmer",
8
+ "save": "Enregistrer",
9
+ "delete": "Supprimer",
10
+ "edit": "Modifier",
11
+ "close": "Fermer",
12
+ "back": "Retour",
13
+ "next": "Suivant",
14
+ "done": "Terminé",
15
+ "retry": "Réessayer",
16
+ "search": "Rechercher",
17
+ "noResults": "Aucun résultat trouvé",
18
+ "offline": "Vous êtes hors ligne",
19
+ "online": "De retour en ligne"
20
+ },
21
+ "auth": {
22
+ "signIn": "Se connecter",
23
+ "signUp": "S'inscrire",
24
+ "signOut": "Se déconnecter",
25
+ "email": "Email",
26
+ "password": "Mot de passe",
27
+ "confirmPassword": "Confirmer le mot de passe",
28
+ "name": "Nom",
29
+ "forgotPassword": "Mot de passe oublié ?",
30
+ "resetPassword": "Réinitialiser le mot de passe",
31
+ "noAccount": "Vous n'avez pas de compte ?",
32
+ "haveAccount": "Vous avez déjà un compte ?",
33
+ "welcomeBack": "Bon retour !",
34
+ "signInToContinue": "Connectez-vous pour continuer",
35
+ "createAccount": "Créer un compte",
36
+ "joinUs": "Rejoignez-nous",
37
+ "enterEmail": "Entrez votre email",
38
+ "enterPassword": "Entrez votre mot de passe",
39
+ "enterName": "Entrez votre nom",
40
+ "passwordHint": "Au moins 8 caractères",
41
+ "invalidCredentials": "Email ou mot de passe invalide",
42
+ "accountCreated": "Compte créé avec succès !",
43
+ "sessionExpired": "Session expirée. Veuillez vous reconnecter.",
44
+ "createPasswordPlaceholder": "Créer un mot de passe",
45
+ "confirmPasswordPlaceholder": "Confirmez votre mot de passe",
46
+ "passwordHintFull": "Min 8 car., 1 majuscule, 1 minuscule, 1 chiffre",
47
+ "biometric": {
48
+ "title": "Authentification biométrique",
49
+ "prompt": "Authentifiez-vous pour continuer",
50
+ "fallback": "Utiliser le code",
51
+ "enabled": "Connexion biométrique activée",
52
+ "disabled": "Connexion biométrique désactivée",
53
+ "notAvailable": "Authentification biométrique non disponible"
54
+ }
55
+ },
56
+ "forgotPassword": {
57
+ "title": "Mot de passe oublié",
58
+ "subtitle": "Entrez votre email et nous vous enverrons un lien de réinitialisation",
59
+ "sendResetLink": "Envoyer le lien de réinitialisation",
60
+ "checkEmail": "Vérifiez votre email",
61
+ "resetSent": "Nous avons envoyé un lien de réinitialisation à {{email}}",
62
+ "backToSignIn": "Retour à la connexion",
63
+ "rememberPassword": "Vous vous souvenez de votre mot de passe ?",
64
+ "emailRequired": "Veuillez entrer votre adresse email",
65
+ "sendFailed": "Échec de l'envoi du lien. Veuillez réessayer."
66
+ },
67
+ "home": {
68
+ "welcomeBack": "Bon retour, {{name}} !",
69
+ "quickActions": "Actions rapides",
70
+ "newItem": "Nouvel élément",
71
+ "stats": "Statistiques",
72
+ "recentActivity": "Activité récente",
73
+ "noRecentActivity": "Aucune activité récente",
74
+ "activityWillAppear": "Votre activité apparaîtra ici"
75
+ },
76
+ "navigation": {
77
+ "home": "Accueil",
78
+ "profile": "Profil",
79
+ "settings": "Paramètres",
80
+ "notifications": "Notifications"
81
+ },
82
+ "profile": {
83
+ "title": "Profil",
84
+ "editProfile": "Modifier le profil",
85
+ "changePhoto": "Changer la photo",
86
+ "personalInfo": "Informations personnelles",
87
+ "memberSince": "Membre depuis {{date}}",
88
+ "privacySecurity": "Confidentialité et sécurité",
89
+ "helpSupport": "Aide et assistance"
90
+ },
91
+ "settings": {
92
+ "title": "Paramètres",
93
+ "appearance": "Apparence",
94
+ "theme": "Thème",
95
+ "themeLight": "Clair",
96
+ "themeDark": "Sombre",
97
+ "themeSystem": "Système",
98
+ "language": "Langue",
99
+ "notifications": "Notifications",
100
+ "pushNotifications": "Notifications push",
101
+ "emailNotifications": "Notifications par email",
102
+ "security": "Sécurité",
103
+ "biometricAuth": "Authentification biométrique",
104
+ "changePassword": "Changer le mot de passe",
105
+ "privacy": "Politique de confidentialité",
106
+ "terms": "Conditions d'utilisation",
107
+ "about": "À propos",
108
+ "version": "Version",
109
+ "deleteAccount": "Supprimer le compte",
110
+ "darkMode": "Mode sombre",
111
+ "appVersion": "Version de l'application"
112
+ },
113
+ "errors": {
114
+ "generic": "Une erreur s'est produite",
115
+ "network": "Erreur réseau. Vérifiez votre connexion.",
116
+ "timeout": "Délai dépassé. Veuillez réessayer.",
117
+ "unauthorized": "Vous n'êtes pas autorisé à effectuer cette action.",
118
+ "notFound": "Ressource introuvable.",
119
+ "validation": "Veuillez vérifier vos informations et réessayer.",
120
+ "rateLimited": "Trop de requêtes. Veuillez patienter un moment.",
121
+ "crashTitle": "Une erreur s'est produite",
122
+ "crashMessage": "L'application a rencontré une erreur inattendue.",
123
+ "tryAgain": "Réessayer",
124
+ "restartApp": "Redémarrer l'application"
125
+ },
126
+ "forceUpdate": {
127
+ "title": "Mise à jour requise",
128
+ "message": "Une nouvelle version de l'application est disponible. Veuillez mettre à jour pour continuer.",
129
+ "button": "Mettre à jour",
130
+ "currentVersion": "Version actuelle",
131
+ "minimumVersion": "Version minimale"
132
+ },
133
+ "validation": {
134
+ "required": "Ce champ est requis",
135
+ "email": "Veuillez entrer un email valide",
136
+ "passwordMin": "Le mot de passe doit contenir au moins 8 caractères",
137
+ "passwordMatch": "Les mots de passe ne correspondent pas",
138
+ "nameMin": "Le nom doit contenir au moins 2 caractères"
139
+ },
140
+ "permissions": {
141
+ "camera": "L'accès à la caméra est nécessaire pour prendre des photos.",
142
+ "location": "L'accès à la localisation est nécessaire pour afficher les résultats à proximité.",
143
+ "contacts": "L'accès aux contacts est nécessaire pour trouver des amis.",
144
+ "mediaLibrary": "L'accès à la photothèque est nécessaire pour sélectionner des images.",
145
+ "microphone": "L'accès au microphone est nécessaire pour enregistrer de l'audio.",
146
+ "notifications": "L'autorisation de notifications est nécessaire pour vous envoyer des alertes.",
147
+ "openSettings": "Ouvrir les réglages",
148
+ "allowAccess": "Autoriser l'accès",
149
+ "blocked": "L'autorisation a été refusée. Veuillez l'activer dans les réglages."
150
+ },
151
+ "socialAuth": {
152
+ "continueWithGoogle": "Continuer avec Google",
153
+ "continueWithApple": "Continuer avec Apple",
154
+ "orContinueWith": "Ou continuer avec"
155
+ },
156
+ "payments": {
157
+ "upgradeToPremium": "Passer à Premium",
158
+ "subscribe": "S'abonner",
159
+ "restore": "Restaurer les achats",
160
+ "perMonth": "/mois",
161
+ "perYear": "/an"
162
+ },
163
+ "upload": {
164
+ "uploading": "Téléchargement en cours...",
165
+ "complete": "Terminé",
166
+ "failed": "Échec du téléchargement",
167
+ "retry": "Réessayer",
168
+ "addPhoto": "Ajouter une photo"
169
+ }
170
+ }
package/jest.config.js CHANGED
@@ -27,6 +27,6 @@ module.exports = {
27
27
  statements: 70,
28
28
  },
29
29
  },
30
- testPathIgnorePatterns: ["/node_modules/", "/.expo/"],
30
+ testPathIgnorePatterns: ["/node_modules/", "/.expo/", "__tests__/helpers/"],
31
31
  moduleFileExtensions: ["ts", "tsx", "js", "jsx", "json"],
32
32
  };
package/maestro/README.md CHANGED
@@ -1,113 +1,113 @@
1
- # Maestro E2E Tests
2
-
3
- This directory contains end-to-end tests using [Maestro](https://maestro.mobile.dev/).
4
-
5
- ## Setup
6
-
7
- ### Install Maestro
8
-
9
- ```bash
10
- # macOS
11
- brew install maestro
12
-
13
- # Or using curl
14
- curl -Ls "https://get.maestro.mobile.dev" | bash
15
- ```
16
-
17
- ### Prerequisites
18
-
19
- - iOS Simulator or Android Emulator running
20
- - App built and installed on the device/emulator
21
-
22
- ## Running Tests
23
-
24
- ### Run all tests
25
-
26
- ```bash
27
- maestro test maestro/flows/
28
- ```
29
-
30
- ### Run a specific test
31
-
32
- ```bash
33
- maestro test maestro/flows/login.yaml
34
- ```
35
-
36
- ### Run with a specific app ID
37
-
38
- ```bash
39
- APP_ID=com.yourcompany.app maestro test maestro/flows/
40
- ```
41
-
42
- ### Run in CI mode
43
-
44
- ```bash
45
- maestro test --format junit --output results.xml maestro/flows/
46
- ```
47
-
48
- ## Test Structure
49
-
50
- ```
51
- maestro/
52
- ├── config.yaml # Global configuration
53
- ├── README.md # This file
54
- └── flows/
55
- ├── login.yaml # Login flow tests
56
- ├── register.yaml # Registration flow tests
57
- ├── navigation.yaml # Navigation tests
58
- └── offline.yaml # Offline mode tests
59
- ```
60
-
61
- ## Writing Tests
62
-
63
- ### Basic test structure
64
-
65
- ```yaml
66
- appId: ${APP_ID}
67
- name: My Test
68
- tags:
69
- - smoke
70
- ---
71
- - launchApp
72
- - tapOn: "Button Text"
73
- - assertVisible: "Expected Text"
74
- ```
75
-
76
- ### Common commands
77
-
78
- - `launchApp` - Launch the app
79
- - `tapOn` - Tap on an element
80
- - `inputText` - Enter text
81
- - `assertVisible` - Assert element is visible
82
- - `scrollUntilVisible` - Scroll until element is found
83
- - `waitForAnimationToEnd` - Wait for animations
84
- - `back` - Press back button
85
-
86
- ### Tips
87
-
88
- 1. Use `waitForAnimationToEnd` after navigation
89
- 2. Use `clearState: true` in `launchApp` for clean tests
90
- 3. Use `optional: true` for elements that may not always appear
91
- 4. Use tags to organize and filter tests
92
-
93
- ## CI Integration
94
-
95
- ### GitHub Actions example
96
-
97
- ```yaml
98
- - name: Run E2E Tests
99
- run: |
100
- maestro test --format junit --output results.xml maestro/flows/
101
-
102
- - name: Upload Test Results
103
- uses: actions/upload-artifact@v3
104
- with:
105
- name: e2e-results
106
- path: results.xml
107
- ```
108
-
109
- ## Resources
110
-
111
- - [Maestro Documentation](https://maestro.mobile.dev/)
112
- - [CLI Reference](https://maestro.mobile.dev/reference/cli)
113
- - [Command Reference](https://maestro.mobile.dev/reference/commands)
1
+ # Maestro E2E Tests
2
+
3
+ This directory contains end-to-end tests using [Maestro](https://maestro.mobile.dev/).
4
+
5
+ ## Setup
6
+
7
+ ### Install Maestro
8
+
9
+ ```bash
10
+ # macOS
11
+ brew install maestro
12
+
13
+ # Or using curl
14
+ curl -Ls "https://get.maestro.mobile.dev" | bash
15
+ ```
16
+
17
+ ### Prerequisites
18
+
19
+ - iOS Simulator or Android Emulator running
20
+ - App built and installed on the device/emulator
21
+
22
+ ## Running Tests
23
+
24
+ ### Run all tests
25
+
26
+ ```bash
27
+ maestro test maestro/flows/
28
+ ```
29
+
30
+ ### Run a specific test
31
+
32
+ ```bash
33
+ maestro test maestro/flows/login.yaml
34
+ ```
35
+
36
+ ### Run with a specific app ID
37
+
38
+ ```bash
39
+ APP_ID=com.yourcompany.app maestro test maestro/flows/
40
+ ```
41
+
42
+ ### Run in CI mode
43
+
44
+ ```bash
45
+ maestro test --format junit --output results.xml maestro/flows/
46
+ ```
47
+
48
+ ## Test Structure
49
+
50
+ ```
51
+ maestro/
52
+ ├── config.yaml # Global configuration
53
+ ├── README.md # This file
54
+ └── flows/
55
+ ├── login.yaml # Login flow tests
56
+ ├── register.yaml # Registration flow tests
57
+ ├── navigation.yaml # Navigation tests
58
+ └── offline.yaml # Offline mode tests
59
+ ```
60
+
61
+ ## Writing Tests
62
+
63
+ ### Basic test structure
64
+
65
+ ```yaml
66
+ appId: ${APP_ID}
67
+ name: My Test
68
+ tags:
69
+ - smoke
70
+ ---
71
+ - launchApp
72
+ - tapOn: "Button Text"
73
+ - assertVisible: "Expected Text"
74
+ ```
75
+
76
+ ### Common commands
77
+
78
+ - `launchApp` - Launch the app
79
+ - `tapOn` - Tap on an element
80
+ - `inputText` - Enter text
81
+ - `assertVisible` - Assert element is visible
82
+ - `scrollUntilVisible` - Scroll until element is found
83
+ - `waitForAnimationToEnd` - Wait for animations
84
+ - `back` - Press back button
85
+
86
+ ### Tips
87
+
88
+ 1. Use `waitForAnimationToEnd` after navigation
89
+ 2. Use `clearState: true` in `launchApp` for clean tests
90
+ 3. Use `optional: true` for elements that may not always appear
91
+ 4. Use tags to organize and filter tests
92
+
93
+ ## CI Integration
94
+
95
+ ### GitHub Actions example
96
+
97
+ ```yaml
98
+ - name: Run E2E Tests
99
+ run: |
100
+ maestro test --format junit --output results.xml maestro/flows/
101
+
102
+ - name: Upload Test Results
103
+ uses: actions/upload-artifact@v3
104
+ with:
105
+ name: e2e-results
106
+ path: results.xml
107
+ ```
108
+
109
+ ## Resources
110
+
111
+ - [Maestro Documentation](https://maestro.mobile.dev/)
112
+ - [CLI Reference](https://maestro.mobile.dev/reference/cli)
113
+ - [Command Reference](https://maestro.mobile.dev/reference/commands)
@@ -1,35 +1,35 @@
1
- # Maestro Configuration
2
- # https://maestro.mobile.dev/reference/configuration
3
-
4
- # Default app ID (can be overridden with env vars)
5
- appId: com.croacroa.app
6
-
7
- # Environment variables
8
- env:
9
- APP_ID: ${APP_ID:-com.croacroa.app}
10
- API_URL: ${API_URL:-http://localhost:3000}
11
-
12
- # Test execution settings
13
- executionOrder:
14
- continueOnFailure: false
15
- retryFailedTests: 1
16
-
17
- # Screenshots
18
- screenshots:
19
- enabled: true
20
- directory: ./maestro/screenshots
21
-
22
- # Video recording
23
- video:
24
- enabled: true
25
- directory: ./maestro/videos
26
-
27
- # Timeouts
28
- timeouts:
29
- launchApp: 30000
30
- waitForAnimationToEnd: 5000
31
-
32
- # Device settings
33
- device:
34
- locale: en_US
35
- orientation: portrait
1
+ # Maestro Configuration
2
+ # https://maestro.mobile.dev/reference/configuration
3
+
4
+ # Default app ID (can be overridden with env vars)
5
+ appId: com.croacroa.app
6
+
7
+ # Environment variables
8
+ env:
9
+ APP_ID: ${APP_ID:-com.croacroa.app}
10
+ API_URL: ${API_URL:-http://localhost:3000}
11
+
12
+ # Test execution settings
13
+ executionOrder:
14
+ continueOnFailure: false
15
+ retryFailedTests: 1
16
+
17
+ # Screenshots
18
+ screenshots:
19
+ enabled: true
20
+ directory: ./maestro/screenshots
21
+
22
+ # Video recording
23
+ video:
24
+ enabled: true
25
+ directory: ./maestro/videos
26
+
27
+ # Timeouts
28
+ timeouts:
29
+ launchApp: 30000
30
+ waitForAnimationToEnd: 5000
31
+
32
+ # Device settings
33
+ device:
34
+ locale: en_US
35
+ orientation: portrait