@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.
- package/.env.example +5 -0
- package/.eslintrc.js +8 -0
- package/.github/workflows/ci.yml +187 -187
- package/.github/workflows/eas-build.yml +55 -55
- package/.github/workflows/eas-update.yml +50 -50
- package/.github/workflows/npm-publish.yml +57 -0
- package/CHANGELOG.md +195 -106
- package/CONTRIBUTING.md +377 -377
- package/LICENSE +21 -0
- package/README.md +446 -399
- package/__tests__/accessibility/components.test.tsx +285 -0
- package/__tests__/components/Button.test.tsx +2 -4
- package/__tests__/components/__snapshots__/snapshots.test.tsx.snap +512 -0
- package/__tests__/components/snapshots.test.tsx +131 -131
- package/__tests__/helpers/a11y.ts +54 -0
- package/__tests__/hooks/useAnalytics.test.ts +100 -0
- package/__tests__/hooks/useAnimations.test.ts +70 -0
- package/__tests__/hooks/useAuth.test.tsx +71 -28
- package/__tests__/hooks/useMedia.test.ts +318 -0
- package/__tests__/hooks/usePayments.test.tsx +307 -0
- package/__tests__/hooks/usePermission.test.ts +230 -0
- package/__tests__/hooks/useWebSocket.test.ts +329 -0
- package/__tests__/integration/auth-api.test.tsx +224 -227
- package/__tests__/performance/VirtualizedList.perf.test.tsx +385 -362
- package/__tests__/services/api.test.ts +24 -6
- package/app/(auth)/home.tsx +11 -9
- package/app/(auth)/profile.tsx +8 -6
- package/app/(auth)/settings.tsx +11 -9
- package/app/(public)/forgot-password.tsx +25 -15
- package/app/(public)/login.tsx +48 -12
- package/app/(public)/onboarding.tsx +5 -5
- package/app/(public)/register.tsx +24 -15
- package/app/_layout.tsx +6 -3
- package/app.config.ts +27 -2
- package/assets/images/.gitkeep +7 -7
- package/assets/images/adaptive-icon.png +0 -0
- package/assets/images/favicon.png +0 -0
- package/assets/images/icon.png +0 -0
- package/assets/images/notification-icon.png +0 -0
- package/assets/images/splash.png +0 -0
- package/components/ErrorBoundary.tsx +73 -28
- package/components/auth/SocialLoginButtons.tsx +168 -0
- package/components/forms/FormInput.tsx +5 -3
- package/components/onboarding/OnboardingScreen.tsx +370 -370
- package/components/onboarding/index.ts +2 -2
- package/components/providers/AnalyticsProvider.tsx +67 -0
- package/components/providers/SuspenseBoundary.tsx +359 -357
- package/components/providers/index.ts +24 -21
- package/components/ui/AnimatedButton.tsx +1 -9
- package/components/ui/AnimatedList.tsx +98 -0
- package/components/ui/AnimatedScreen.tsx +89 -0
- package/components/ui/Avatar.tsx +319 -316
- package/components/ui/Badge.tsx +416 -416
- package/components/ui/BottomSheet.tsx +307 -307
- package/components/ui/Button.tsx +11 -3
- package/components/ui/Checkbox.tsx +261 -261
- package/components/ui/FeatureGate.tsx +57 -0
- package/components/ui/ForceUpdateScreen.tsx +108 -0
- package/components/ui/ImagePickerButton.tsx +180 -0
- package/components/ui/Input.stories.tsx +2 -10
- package/components/ui/Input.tsx +2 -10
- package/components/ui/OptimizedImage.tsx +369 -369
- package/components/ui/Paywall.tsx +253 -0
- package/components/ui/PermissionGate.tsx +155 -0
- package/components/ui/PurchaseButton.tsx +84 -0
- package/components/ui/Select.tsx +240 -240
- package/components/ui/Skeleton.tsx +3 -1
- package/components/ui/Toast.tsx +427 -0
- package/components/ui/UploadProgress.tsx +189 -0
- package/components/ui/VirtualizedList.tsx +288 -285
- package/components/ui/index.ts +28 -23
- package/constants/config.ts +135 -97
- package/docs/adr/001-state-management.md +79 -79
- package/docs/adr/002-styling-approach.md +130 -130
- package/docs/adr/003-data-fetching.md +155 -155
- package/docs/adr/004-auth-adapter-pattern.md +144 -144
- package/docs/adr/README.md +78 -78
- package/docs/guides/analytics-posthog.md +121 -0
- package/docs/guides/auth-supabase.md +162 -0
- package/docs/guides/feature-flags-launchdarkly.md +150 -0
- package/docs/guides/payments-revenuecat.md +169 -0
- package/docs/plans/2026-02-22-phase6-implementation.md +3222 -0
- package/docs/plans/2026-02-22-phase6-template-completion-design.md +196 -0
- package/docs/plans/2026-02-23-npm-publish-design.md +31 -0
- package/docs/plans/2026-02-23-phase7-polish-documentation-design.md +79 -0
- package/docs/plans/2026-02-23-phase8-additional-features-design.md +136 -0
- package/eas.json +2 -1
- package/hooks/index.ts +70 -27
- package/hooks/useAnimatedEntry.ts +204 -0
- package/hooks/useApi.ts +64 -4
- package/hooks/useAuth.tsx +7 -3
- package/hooks/useBiometrics.ts +295 -295
- package/hooks/useChannel.ts +111 -0
- package/hooks/useDeepLinking.ts +256 -256
- package/hooks/useExperiment.ts +36 -0
- package/hooks/useFeatureFlag.ts +59 -0
- package/hooks/useForceUpdate.ts +91 -0
- package/hooks/useImagePicker.ts +281 -0
- package/hooks/useInAppReview.ts +64 -0
- package/hooks/useMFA.ts +509 -499
- package/hooks/useParallax.ts +142 -0
- package/hooks/usePerformance.ts +434 -434
- package/hooks/usePermission.ts +190 -0
- package/hooks/usePresence.ts +129 -0
- package/hooks/useProducts.ts +36 -0
- package/hooks/usePurchase.ts +103 -0
- package/hooks/useRateLimit.ts +70 -0
- package/hooks/useSubscription.ts +49 -0
- package/hooks/useTrackEvent.ts +52 -0
- package/hooks/useTrackScreen.ts +40 -0
- package/hooks/useUpdates.ts +358 -358
- package/hooks/useUpload.ts +165 -0
- package/hooks/useWebSocket.ts +111 -0
- package/i18n/index.ts +197 -194
- package/i18n/locales/ar.json +170 -101
- package/i18n/locales/de.json +170 -101
- package/i18n/locales/en.json +170 -101
- package/i18n/locales/es.json +170 -101
- package/i18n/locales/fr.json +170 -101
- package/jest.config.js +1 -1
- package/maestro/README.md +113 -113
- package/maestro/config.yaml +35 -35
- package/maestro/flows/login.yaml +62 -62
- package/maestro/flows/mfa-login.yaml +92 -92
- package/maestro/flows/mfa-setup.yaml +86 -86
- package/maestro/flows/navigation.yaml +68 -68
- package/maestro/flows/offline-conflict.yaml +101 -101
- package/maestro/flows/offline-sync.yaml +128 -128
- package/maestro/flows/offline.yaml +60 -60
- package/maestro/flows/register.yaml +94 -94
- package/package.json +188 -175
- package/scripts/generate-placeholders.js +38 -0
- package/services/analytics/adapters/console.ts +50 -0
- package/services/analytics/analytics-adapter.ts +94 -0
- package/services/analytics/types.ts +73 -0
- package/services/analytics.ts +428 -428
- package/services/api.ts +419 -340
- package/services/auth/social/apple.ts +110 -0
- package/services/auth/social/google.ts +159 -0
- package/services/auth/social/social-auth.ts +100 -0
- package/services/auth/social/types.ts +80 -0
- package/services/authAdapter.ts +333 -333
- package/services/backgroundSync.ts +652 -626
- package/services/feature-flags/adapters/mock.ts +108 -0
- package/services/feature-flags/feature-flag-adapter.ts +174 -0
- package/services/feature-flags/types.ts +79 -0
- package/services/force-update.ts +140 -0
- package/services/index.ts +116 -54
- package/services/media/compression.ts +91 -0
- package/services/media/media-picker.ts +151 -0
- package/services/media/media-upload.ts +160 -0
- package/services/payments/adapters/mock.ts +159 -0
- package/services/payments/payment-adapter.ts +118 -0
- package/services/payments/types.ts +131 -0
- package/services/permissions/permission-manager.ts +284 -0
- package/services/permissions/types.ts +104 -0
- package/services/realtime/types.ts +100 -0
- package/services/realtime/websocket-manager.ts +441 -0
- package/services/security.ts +289 -286
- package/services/sentry.ts +4 -4
- package/stores/appStore.ts +9 -0
- package/stores/notificationStore.ts +3 -1
- package/tailwind.config.js +47 -47
- package/tsconfig.json +37 -13
- package/types/user.ts +1 -1
- package/utils/accessibility.ts +446 -446
- package/utils/animations/presets.ts +182 -0
- package/utils/animations/transitions.ts +62 -0
- package/utils/index.ts +63 -52
- package/utils/toast.ts +9 -2
- package/utils/validation.ts +4 -1
- package/utils/withAccessibility.tsx +272 -272
package/i18n/locales/fr.json
CHANGED
|
@@ -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
|
-
"
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
"
|
|
49
|
-
"
|
|
50
|
-
"
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
"
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
"
|
|
61
|
-
"
|
|
62
|
-
"
|
|
63
|
-
"
|
|
64
|
-
"
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
"
|
|
69
|
-
"
|
|
70
|
-
"
|
|
71
|
-
"
|
|
72
|
-
"
|
|
73
|
-
"
|
|
74
|
-
"
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
"
|
|
78
|
-
"
|
|
79
|
-
"
|
|
80
|
-
"
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
"
|
|
84
|
-
"
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
"
|
|
88
|
-
"
|
|
89
|
-
"
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
"
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
"
|
|
96
|
-
"
|
|
97
|
-
"
|
|
98
|
-
"
|
|
99
|
-
"
|
|
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
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)
|
package/maestro/config.yaml
CHANGED
|
@@ -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
|