Complete feature file audit and fix scenarios

- Fix US-6: Rename to "M'inscrire/me désinscrire à un atelier" and remove
  non-atelier scenarios
- Fix US-9: Add missing scenario for "Ajouter une photo personnelle"
- Fix US-13: Add scenarios for "Modifier" and "Supprimer" événement,
  plus "Retirer une organisation"
- Fix US-14: Mark all scenarios as non-implemented (no atelier screen)
- Fix US-15: Distinguish événement vs atelier scenarios, remove unclear ones
- Fix US-16: Implement 4 scenarios for MeetingPointsScreen
- Fix US-22: Implement 5 scenarios for ShareProfileScreen (parrainage)
- Fix US-23: Implement 3 scenarios for profile sharing

Add missing scenarios from user story descriptions:
- US-1: Programme détaillé, zone partage collective
- US-2: Programme détaillé des ateliers
- US-4: Icône ajouter commentaire
- US-5: Interactions Date/Heure/Lieu
- US-7: Recherche Mobilizon
- US-8: 4 scenarios for macro-événement
- US-12: Vue carte des événements
- US-20: Profils publiques

Add new step definitions:
- l'écran contient un bouton {string}
- l'écran contient un champ {string}
- l'écran contient un texte {string}
- l'écran contient un avatar

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Sylvain Duchesne
2026-01-19 12:49:41 +01:00
parent 7827479e9c
commit a3e89e65c9
30 changed files with 3417 additions and 1689 deletions
+390 -95
View File
@@ -23,7 +23,16 @@ export const parsedFeatures: ParsedFeature[] = [
{
"name": "Accéder au profil pour voir la photo",
"tags": [],
"steps": []
"steps": [
{
"keyword": "Étant donné que ",
"text": "je suis sur la page \"mon profil\""
},
{
"keyword": "Alors",
"text": "l'écran contient un avatar"
}
]
},
{
"name": "Naviguer vers le profil depuis la liste des participants",
@@ -64,13 +73,32 @@ export const parsedFeatures: ParsedFeature[] = [
{
"name": "Vérifier les champs de données du profil",
"tags": [],
"steps": [
{
"keyword": "Étant donné que ",
"text": "je suis sur la page \"mon profil\""
},
{
"keyword": "Alors",
"text": "l'écran contient un texte \"Marie Dupont\""
},
{
"keyword": "Et",
"text": "l'écran contient un texte \"@mariedupont\""
}
]
},
{
"name": "Ajouter une photo personnelle sur une fiche existante",
"tags": [],
"steps": []
}
],
"filePath": "features/user/us-9-visualiser-photo.feature",
"rawContent": "# language: fr\n@USER @priority-0\nFonctionnalité: US-9 Visualiser la photo d'un individu\n En tant qu'utilisateur\n Je peux visualiser la photo d'un individu ou ajouter une photo personnelle sur une fiche existante\n Et consulter la liste des inscrits à un atelier\n Afin d'identifier les personnes que j'ai rencontrées dont je n'ai pas noté leur nom\n\n Contexte:\n Étant donné que je suis connecté en tant qu'utilisateur\n\n Scénario: Accéder au profil pour voir la photo\n * Scénario non implémenté\n\n Scénario: Naviguer vers le profil depuis la liste des participants\n Étant donné que je suis sur la page \"détail événement\"\n Quand je clique sur un participant\n Alors je suis redirigé vers \"profil utilisateur\"\n Et l'écran affiche les informations du profil\n\n Scénario: Consulter la liste des inscrits à un atelier\n Étant donné que je suis sur la page \"détail événement\"\n Alors je peux voir la liste des participants\n\n Scénario: Vérifier les champs de données du profil\n * Scénario non implémenté\n",
"rawContent": "# language: fr\n@USER @priority-0\nFonctionnalité: US-9 Visualiser la photo d'un individu\n En tant qu'utilisateur\n Je peux visualiser la photo d'un individu ou ajouter une photo personnelle sur une fiche existante\n Et consulter la liste des inscrits à un atelier\n Afin d'identifier les personnes que j'ai rencontrées dont je n'ai pas noté leur nom\n\n Contexte:\n Étant donné que je suis connecté en tant qu'utilisateur\n\n Scénario: Accéder au profil pour voir la photo\n Étant donné que je suis sur la page \"mon profil\"\n Alors l'écran contient un avatar\n\n Scénario: Naviguer vers le profil depuis la liste des participants\n Étant donné que je suis sur la page \"détail événement\"\n Quand je clique sur un participant\n Alors je suis redirigé vers \"profil utilisateur\"\n Et l'écran affiche les informations du profil\n\n Scénario: Consulter la liste des inscrits à un atelier\n Étant donné que je suis sur la page \"détail événement\"\n Alors je peux voir la liste des participants\n\n Scénario: Vérifier les champs de données du profil\n Étant donné que je suis sur la page \"mon profil\"\n Alors l'écran contient un texte \"Marie Dupont\"\n Et l'écran contient un texte \"@mariedupont\"\n\n Scénario: Ajouter une photo personnelle sur une fiche existante\n * Scénario non implémenté\n",
"screenIds": [
"event-detail",
"profile",
"user-profile"
]
},
@@ -123,11 +151,6 @@ export const parsedFeatures: ParsedFeature[] = [
}
]
},
{
"name": "Remplir le formulaire de création d'événement",
"tags": [],
"steps": []
},
{
"name": "Vérifier la présence du bouton de création",
"tags": [],
@@ -155,10 +178,25 @@ export const parsedFeatures: ParsedFeature[] = [
"text": "je peux annuler et revenir à l'écran précédent"
}
]
},
{
"name": "Modifier un événement",
"tags": [],
"steps": []
},
{
"name": "Supprimer un événement",
"tags": [],
"steps": []
},
{
"name": "Retirer une organisation (personne ou structure)",
"tags": [],
"steps": []
}
],
"filePath": "features/event/us-13-creer-evenement.feature",
"rawContent": "# language: fr\n@EVENT @priority-1\nFonctionnalité: US-13 Créer/Modifier/Supprimer un événement\n En tant qu'utilisateur\n Je peux créer/modifier/supprimer un événement\n En choisissant les dates, horaires, lieu et thématique\n Afin de créer/présenter le contenu de cet événement et le catégoriser\n\n Contexte:\n Étant donné que je suis connecté en tant qu'utilisateur\n\n Scénario: Accéder à la création d'événement\n Étant donné que je suis sur la page \"accueil\"\n Quand je navigue vers \"créer un événement\"\n Alors je vois l'écran \"create-event\"\n\n Scénario: Vérifier les champs obligatoires du formulaire\n Étant donné que l'écran \"create-event\" est affiché\n Alors le formulaire contient les champs obligatoires suivants:\n | Nom de l'événement |\n | Date |\n | Heure de début |\n | Lieu |\n | Thématique |\n\n Scénario: Remplir le formulaire de création d'événement\n * Scénario non implémenté\n\n Scénario: Vérifier la présence du bouton de création\n Étant donné que je suis sur la page \"créer un événement\"\n Alors l'écran contient une section \"Créer l'événement\"\n\n Scénario: Pouvoir annuler la création d'événement\n Étant donné que je suis sur la page \"créer un événement\"\n Alors je peux annuler et revenir à l'écran précédent\n",
"rawContent": "# language: fr\n@EVENT @priority-1\nFonctionnalité: US-13 Créer/Modifier/Supprimer un événement\n En tant qu'utilisateur\n Je peux créer/modifier/supprimer un événement\n En choisissant les dates, horaires, lieu et thématique\n Afin de créer/présenter le contenu de cet événement et le catégoriser\n\n Contexte:\n Étant donné que je suis connecté en tant qu'utilisateur\n\n Scénario: Accéder à la création d'événement\n Étant donné que je suis sur la page \"accueil\"\n Quand je navigue vers \"créer un événement\"\n Alors je vois l'écran \"create-event\"\n\n Scénario: Vérifier les champs obligatoires du formulaire\n Étant donné que l'écran \"create-event\" est affiché\n Alors le formulaire contient les champs obligatoires suivants:\n | Nom de l'événement |\n | Date |\n | Heure de début |\n | Lieu |\n | Thématique |\n\n Scénario: Vérifier la présence du bouton de création\n Étant donné que je suis sur la page \"créer un événement\"\n Alors l'écran contient une section \"Créer l'événement\"\n\n Scénario: Pouvoir annuler la création d'événement\n Étant donné que je suis sur la page \"créer un événement\"\n Alors je peux annuler et revenir à l'écran précédent\n\n Scénario: Modifier un événement\n * Scénario non implémenté\n\n Scénario: Supprimer un événement\n * Scénario non implémenté\n\n Scénario: Retirer une organisation (personne ou structure)\n * Scénario non implémenté\n",
"screenIds": [
"create-event",
"home"
@@ -226,15 +264,10 @@ export const parsedFeatures: ParsedFeature[] = [
"text": "je peux voir la liste des participants"
}
]
},
{
"name": "Vérifier les données affichées",
"tags": [],
"steps": []
}
],
"filePath": "features/event/us-3-visualiser-evenement-termine.feature",
"rawContent": "# language: fr\n@EVENT @priority-1\nFonctionnalité: US-3 Visualiser un événement terminé\n En tant qu'utilisateur\n Je peux visualiser un événement terminé et consulter la description de l'événement\n Afin de voir les personnes qui ont participé à cet événement\n\n Contexte:\n Étant donné que je suis connecté en tant qu'utilisateur\n\n Scénario: Accéder aux détails d'un événement terminé\n Étant donné que je suis sur la page \"accueil\"\n Quand je clique sur un événement\n Alors je vois l'écran \"event-detail\"\n\n Scénario: Voir la description de l'événement\n Étant donné que je suis sur la page \"détail événement\"\n Alors l'écran affiche les informations de l'événement\n\n Scénario: Voir la liste des participants\n Étant donné que je suis sur la page \"détail événement\"\n Alors je peux voir la liste des participants\n\n Scénario: Vérifier les données affichées\n * Scénario non implémenté\n",
"rawContent": "# language: fr\n@EVENT @priority-1\nFonctionnalité: US-3 Visualiser un événement terminé\n En tant qu'utilisateur\n Je peux visualiser un événement terminé et consulter la description de l'événement\n Afin de voir les personnes qui ont participé à cet événement\n\n Contexte:\n Étant donné que je suis connecté en tant qu'utilisateur\n\n Scénario: Accéder aux détails d'un événement terminé\n Étant donné que je suis sur la page \"accueil\"\n Quand je clique sur un événement\n Alors je vois l'écran \"event-detail\"\n\n Scénario: Voir la description de l'événement\n Étant donné que je suis sur la page \"détail événement\"\n Alors l'écran affiche les informations de l'événement\n\n Scénario: Voir la liste des participants\n Étant donné que je suis sur la page \"détail événement\"\n Alors je peux voir la liste des participants\n",
"screenIds": [
"event-detail",
"home"
@@ -299,10 +332,15 @@ export const parsedFeatures: ParsedFeature[] = [
"name": "Vérifier les données de l'écran",
"tags": [],
"steps": []
},
{
"name": "Rechercher dans une base existante (Mobilizon)",
"tags": [],
"steps": []
}
],
"filePath": "features/event/us-7-inscription-evenement.feature",
"rawContent": "# language: fr\n@EVENT @priority-1\nFonctionnalité: US-7 M'inscrire/me désinscrire à un événement\n En tant qu'utilisateur\n Je peux m'inscrire/me désinscrire à un événement\n Après avoir consulté la description de l'événement, les dates et le lieu\n S'il existe déjà dans le système ou en le retrouvant dans une base existante\n\n Contexte:\n Étant donné que je suis connecté en tant qu'utilisateur\n\n Scénario: Consulter un événement avant inscription\n Étant donné que je suis sur la page \"détail événement\"\n Alors l'écran affiche les informations de l'événement\n\n Scénario: S'inscrire à un événement\n * Scénario non implémenté\n\n Scénario: Se désinscrire d'un événement\n * Scénario non implémenté\n\n Scénario: Rechercher un événement existant\n Étant donné que je suis sur la page \"découvrir\"\n Alors je peux voir la liste des événements\n\n Scénario: Vérifier les données de l'écran\n * Scénario non implémenté\n",
"rawContent": "# language: fr\n@EVENT @priority-1\nFonctionnalité: US-7 M'inscrire/me désinscrire à un événement\n En tant qu'utilisateur\n Je peux m'inscrire/me désinscrire à un événement\n Après avoir consulté la description de l'événement, les dates et le lieu\n S'il existe déjà dans le système ou en le retrouvant dans une base existante\n\n Contexte:\n Étant donné que je suis connecté en tant qu'utilisateur\n\n Scénario: Consulter un événement avant inscription\n Étant donné que je suis sur la page \"détail événement\"\n Alors l'écran affiche les informations de l'événement\n\n Scénario: S'inscrire à un événement\n * Scénario non implémenté\n\n Scénario: Se désinscrire d'un événement\n * Scénario non implémenté\n\n Scénario: Rechercher un événement existant\n Étant donné que je suis sur la page \"découvrir\"\n Alors je peux voir la liste des événements\n\n Scénario: Vérifier les données de l'écran\n * Scénario non implémenté\n\n Scénario: Rechercher dans une base existante (Mobilizon)\n * Scénario non implémenté\n",
"screenIds": [
"event-detail",
"events"
@@ -346,26 +384,86 @@ export const parsedFeatures: ParsedFeature[] = [
{
"name": "Créer un point de rencontre",
"tags": [],
"steps": []
"steps": [
{
"keyword": "Étant donné que ",
"text": "je suis sur la page \"points de rencontre\""
},
{
"keyword": "Alors",
"text": "l'écran contient un bouton \"Créer le point de rencontre\""
}
]
},
{
"name": "Définir le lieu de rencontre",
"tags": [],
"steps": []
"steps": [
{
"keyword": "Étant donné que ",
"text": "je suis sur la page \"points de rencontre\""
},
{
"keyword": "Alors",
"text": "l'écran contient une section \"Proposer un point de rencontre\""
},
{
"keyword": "Et",
"text": "l'écran contient un champ \"Lieu\""
}
]
},
{
"name": "Définir l'heure de rencontre",
"tags": [],
"steps": []
"steps": [
{
"keyword": "Étant donné que ",
"text": "je suis sur la page \"points de rencontre\""
},
{
"keyword": "Alors",
"text": "l'écran contient un bouton \"30 min avant\""
},
{
"keyword": "Et",
"text": "l'écran contient un bouton \"1h avant\""
},
{
"keyword": "Et",
"text": "l'écran contient un bouton \"Personnalisé\""
}
]
},
{
"name": "Échanger des liens de contact",
"tags": [],
"steps": []
"steps": [
{
"keyword": "Étant donné que ",
"text": "je suis sur la page \"points de rencontre\""
},
{
"keyword": "Alors",
"text": "l'écran contient une section \"Échanger vos contacts\""
},
{
"keyword": "Et",
"text": "l'écran contient un texte \"Mon QR Code\""
},
{
"keyword": "Et",
"text": "l'écran contient un bouton \"Scanner un QR\""
},
{
"keyword": "Et",
"text": "l'écran contient un bouton \"Partager mon lien\""
}
]
}
],
"filePath": "features/meeting/us-16-point-rencontre.feature",
"rawContent": "# language: fr\n@MEETING @priority-1\nFonctionnalité: US-16 Indiquer un ou plusieurs points de rencontre\n En tant qu'utilisateur\n Je peux indiquer un ou plusieurs points de rencontre\n En précisant le lieu et l'heure de cette rencontre\n Afin de croiser et faire connaissance d'autres participants\n\n Contexte:\n Étant donné que je suis connecté en tant qu'utilisateur\n\n Scénario: Accéder aux points de rencontre\n Étant donné que je suis sur la page \"détail événement\"\n Quand je navigue vers \"points de rencontre\"\n Alors je vois l'écran \"meeting-points\"\n\n Scénario: Créer un point de rencontre\n * Scénario non implémenté\n\n Scénario: Définir le lieu de rencontre\n * Scénario non implémenté\n\n Scénario: Définir l'heure de rencontre\n * Scénario non implémenté\n\n Scénario: Échanger des liens de contact\n * Scénario non implémenté\n",
"rawContent": "# language: fr\n@MEETING @priority-1\nFonctionnalité: US-16 Indiquer un ou plusieurs points de rencontre\n En tant qu'utilisateur\n Je peux indiquer un ou plusieurs points de rencontre\n En précisant le lieu et l'heure de cette rencontre\n Afin de croiser et faire connaissance d'autres participants\n\n Contexte:\n Étant donné que je suis connecté en tant qu'utilisateur\n\n Scénario: Accéder aux points de rencontre\n Étant donné que je suis sur la page \"détail événement\"\n Quand je navigue vers \"points de rencontre\"\n Alors je vois l'écran \"meeting-points\"\n\n Scénario: Créer un point de rencontre\n Étant donné que je suis sur la page \"points de rencontre\"\n Alors l'écran contient un bouton \"Créer le point de rencontre\"\n\n Scénario: Définir le lieu de rencontre\n Étant donné que je suis sur la page \"points de rencontre\"\n Alors l'écran contient une section \"Proposer un point de rencontre\"\n Et l'écran contient un champ \"Lieu\"\n\n Scénario: Définir l'heure de rencontre\n Étant donné que je suis sur la page \"points de rencontre\"\n Alors l'écran contient un bouton \"30 min avant\"\n Et l'écran contient un bouton \"1h avant\"\n Et l'écran contient un bouton \"Personnalisé\"\n\n Scénario: Échanger des liens de contact\n Étant donné que je suis sur la page \"points de rencontre\"\n Alors l'écran contient une section \"Échanger vos contacts\"\n Et l'écran contient un texte \"Mon QR Code\"\n Et l'écran contient un bouton \"Scanner un QR\"\n Et l'écran contient un bouton \"Partager mon lien\"\n",
"screenIds": [
"event-detail",
"meeting-points"
@@ -479,7 +577,7 @@ export const parsedFeatures: ParsedFeature[] = [
],
"scenarios": [
{
"name": "Accéder à la liste des inscrits",
"name": "Accéder à la liste des inscrits d'un événement",
"tags": [],
"steps": [
{
@@ -493,7 +591,12 @@ export const parsedFeatures: ParsedFeature[] = [
]
},
{
"name": "Voir la liste triée",
"name": "Accéder à la liste des inscrits d'un atelier",
"tags": [],
"steps": []
},
{
"name": "Voir la liste des participants d'un événement",
"tags": [],
"steps": [
{
@@ -506,6 +609,11 @@ export const parsedFeatures: ParsedFeature[] = [
}
]
},
{
"name": "Voir la liste des participants d'un atelier",
"tags": [],
"steps": []
},
{
"name": "Cliquer sur un inscrit pour voir son profil",
"tags": [],
@@ -523,15 +631,10 @@ export const parsedFeatures: ParsedFeature[] = [
"text": "je vois l'écran \"user-profile\""
}
]
},
{
"name": "Vérifier les données de l'écran",
"tags": [],
"steps": []
}
],
"filePath": "features/user/us-15-visualiser-inscrits.feature",
"rawContent": "# language: fr\n@USER @priority-1\nFonctionnalité: US-15 Visualiser les inscrits à un atelier/événement\n En tant qu'utilisateur\n Je peux visualiser les inscrits à un atelier/événement\n En sélectionnant l'atelier/l'événement désiré dans la liste\n Afin de consulter la liste des inscrits triée par ordre alphabétique\n\n Contexte:\n Étant donné que je suis connecté en tant qu'utilisateur\n\n Scénario: Accéder à la liste des inscrits\n Étant donné que je suis sur la page \"détail événement\"\n Alors je peux voir la liste des participants\n\n Scénario: Voir la liste triée\n Étant donné que je suis sur la page \"détail événement\"\n Alors l'écran contient une section \"Participants\"\n\n Scénario: Cliquer sur un inscrit pour voir son profil\n Étant donné que je suis sur la page \"détail événement\"\n Quand je clique sur un participant\n Alors je vois l'écran \"user-profile\"\n\n Scénario: Vérifier les données de l'écran\n * Scénario non implémenté\n",
"rawContent": "# language: fr\n@USER @priority-1\nFonctionnalité: US-15 Visualiser les inscrits à un atelier/événement\n En tant qu'utilisateur\n Je peux visualiser les inscrits à un atelier/événement\n En sélectionnant l'atelier/l'événement désiré dans la liste\n Afin de consulter la liste des inscrits triée par ordre alphabétique\n\n Contexte:\n Étant donné que je suis connecté en tant qu'utilisateur\n\n Scénario: Accéder à la liste des inscrits d'un événement\n Étant donné que je suis sur la page \"détail événement\"\n Alors je peux voir la liste des participants\n\n Scénario: Accéder à la liste des inscrits d'un atelier\n * Scénario non implémenté\n\n Scénario: Voir la liste des participants d'un événement\n Étant donné que je suis sur la page \"détail événement\"\n Alors l'écran contient une section \"Participants\"\n\n Scénario: Voir la liste des participants d'un atelier\n * Scénario non implémenté\n\n Scénario: Cliquer sur un inscrit pour voir son profil\n Étant donné que je suis sur la page \"détail événement\"\n Quand je clique sur un participant\n Alors je vois l'écran \"user-profile\"\n",
"screenIds": [
"event-detail",
"user-profile"
@@ -571,12 +674,30 @@ export const parsedFeatures: ParsedFeature[] = [
{
"name": "Voir le QR code",
"tags": [],
"steps": []
"steps": [
{
"keyword": "Étant donné que ",
"text": "je suis sur la page \"partage profil\""
},
{
"keyword": "Alors",
"text": "l'écran contient un texte \"Scannez pour me retrouver sur Festipod\""
}
]
},
{
"name": "Voir le lien de partage",
"tags": [],
"steps": []
"steps": [
{
"keyword": "Étant donné que ",
"text": "je suis sur la page \"partage profil\""
},
{
"keyword": "Alors",
"text": "l'écran contient une section \"Mon lien de profil\""
}
]
},
{
"name": "Accéder à l'écran de partage dédié",
@@ -599,11 +720,20 @@ export const parsedFeatures: ParsedFeature[] = [
{
"name": "Vérifier les données du profil",
"tags": [],
"steps": []
"steps": [
{
"keyword": "Étant donné que ",
"text": "je suis sur la page \"partage profil\""
},
{
"keyword": "Alors",
"text": "l'écran contient un texte \"Marie Dupont\""
}
]
}
],
"filePath": "features/user/us-23-connexion-utilisateurs.feature",
"rawContent": "# language: fr\n@USER @priority-1\nFonctionnalité: US-23 Me connecter avec d'autres utilisateurs\n En tant qu'utilisateur\n Je peux me connecter avec d'autres utilisateurs\n En partageant mon QR code ou mon lien de contact\n Afin d'étendre mon réseau\n\n Contexte:\n Étant donné que je suis connecté en tant qu'utilisateur\n\n Scénario: Accéder au partage depuis le profil\n Étant donné que je suis sur la page \"mon profil\"\n Alors l'écran contient une section \"Partager\"\n\n Scénario: Voir le QR code\n * Scénario non implémenté\n\n Scénario: Voir le lien de partage\n * Scénario non implémenté\n\n Scénario: Accéder à l'écran de partage dédié\n Étant donné que je suis sur la page \"mon profil\"\n Quand je navigue vers \"partage de profil\"\n Alors je vois l'écran \"share-profile\"\n\n Scénario: Vérifier les données du profil\n * Scénario non implémenté\n",
"rawContent": "# language: fr\n@USER @priority-1\nFonctionnalité: US-23 Me connecter avec d'autres utilisateurs\n En tant qu'utilisateur\n Je peux me connecter avec d'autres utilisateurs\n En partageant mon QR code ou mon lien de contact\n Afin d'étendre mon réseau\n\n Contexte:\n Étant donné que je suis connecté en tant qu'utilisateur\n\n Scénario: Accéder au partage depuis le profil\n Étant donné que je suis sur la page \"mon profil\"\n Alors l'écran contient une section \"Partager\"\n\n Scénario: Voir le QR code\n Étant donné que je suis sur la page \"partage profil\"\n Alors l'écran contient un texte \"Scannez pour me retrouver sur Festipod\"\n\n Scénario: Voir le lien de partage\n Étant donné que je suis sur la page \"partage profil\"\n Alors l'écran contient une section \"Mon lien de profil\"\n\n Scénario: Accéder à l'écran de partage dédié\n Étant donné que je suis sur la page \"mon profil\"\n Quand je navigue vers \"partage de profil\"\n Alors je vois l'écran \"share-profile\"\n\n Scénario: Vérifier les données du profil\n Étant donné que je suis sur la page \"partage profil\"\n Alors l'écran contient un texte \"Marie Dupont\"\n",
"screenIds": [
"profile",
"share-profile"
@@ -647,7 +777,20 @@ export const parsedFeatures: ParsedFeature[] = [
{
"name": "Voir mon réseau",
"tags": [],
"steps": []
"steps": [
{
"keyword": "Étant donné que ",
"text": "je suis sur la page \"mon profil\""
},
{
"keyword": "Alors",
"text": "l'écran contient un texte \"Amis\""
},
{
"keyword": "Et",
"text": "l'écran contient un texte \"Mes amis\""
}
]
},
{
"name": "Voir un profil de mon réseau",
@@ -688,11 +831,29 @@ export const parsedFeatures: ParsedFeature[] = [
{
"name": "Vérifier les données du profil",
"tags": [],
"steps": [
{
"keyword": "Étant donné que ",
"text": "je suis sur la page \"mon profil\""
},
{
"keyword": "Alors",
"text": "l'écran contient un texte \"Événements\""
},
{
"keyword": "Et",
"text": "l'écran contient un texte \"Participations\""
}
]
},
{
"name": "Voir les profils publiques",
"tags": [],
"steps": []
}
],
"filePath": "features/user/us-20-profil-reseau.feature",
"rawContent": "# language: fr\n@USER @priority-1\nFonctionnalité: US-20 Voir le profil des personnes faisant partie de mon réseau\n En tant qu'utilisateur\n Je peux voir le profil des personnes faisant partie de mon réseau\n Ainsi que le profil des personnes publiques\n Et consulter la description de l'événement afin de savoir si je veux participer\n\n Contexte:\n Étant donné que je suis connecté en tant qu'utilisateur\n\n Scénario: Accéder à mon profil\n Étant donné que je suis sur la page \"accueil\"\n Quand je navigue vers \"mon profil\"\n Alors je vois l'écran \"profile\"\n\n Scénario: Voir mon réseau\n * Scénario non implémenté\n\n Scénario: Voir un profil de mon réseau\n Étant donné que je suis sur la page \"mon profil\"\n Quand je clique sur un participant\n Alors je vois l'écran \"user-profile\"\n\n Scénario: Consulter un événement depuis un profil\n Étant donné que je suis sur la page \"profil utilisateur\"\n Quand je clique sur un événement\n Alors je vois l'écran \"event-detail\"\n\n Scénario: Vérifier les données du profil\n * Scénario non implémenté\n",
"rawContent": "# language: fr\n@USER @priority-1\nFonctionnalité: US-20 Voir le profil des personnes faisant partie de mon réseau\n En tant qu'utilisateur\n Je peux voir le profil des personnes faisant partie de mon réseau\n Ainsi que le profil des personnes publiques\n Et consulter la description de l'événement afin de savoir si je veux participer\n\n Contexte:\n Étant donné que je suis connecté en tant qu'utilisateur\n\n Scénario: Accéder à mon profil\n Étant donné que je suis sur la page \"accueil\"\n Quand je navigue vers \"mon profil\"\n Alors je vois l'écran \"profile\"\n\n Scénario: Voir mon réseau\n Étant donné que je suis sur la page \"mon profil\"\n Alors l'écran contient un texte \"Amis\"\n Et l'écran contient un texte \"Mes amis\"\n\n Scénario: Voir un profil de mon réseau\n Étant donné que je suis sur la page \"mon profil\"\n Quand je clique sur un participant\n Alors je vois l'écran \"user-profile\"\n\n Scénario: Consulter un événement depuis un profil\n Étant donné que je suis sur la page \"profil utilisateur\"\n Quand je clique sur un événement\n Alors je vois l'écran \"event-detail\"\n\n Scénario: Vérifier les données du profil\n Étant donné que je suis sur la page \"mon profil\"\n Alors l'écran contient un texte \"Événements\"\n Et l'écran contient un texte \"Participations\"\n\n Scénario: Voir les profils publiques\n * Scénario non implémenté\n",
"screenIds": [
"event-detail",
"home",
@@ -744,18 +905,41 @@ export const parsedFeatures: ParsedFeature[] = [
{
"name": "Voir mes inscriptions",
"tags": [],
"steps": []
"steps": [
{
"keyword": "Étant donné que ",
"text": "je suis sur la page \"mon profil\""
},
{
"keyword": "Alors",
"text": "l'écran contient une section \"Mes événements à venir\""
}
]
},
{
"name": "Vérifier les données de l'accueil",
"tags": [],
"steps": []
"steps": [
{
"keyword": "Étant donné que ",
"text": "je suis sur la page \"accueil\""
},
{
"keyword": "Alors",
"text": "l'écran contient un texte \"Barbecue d'été\""
},
{
"keyword": "Et",
"text": "l'écran contient un texte \"Soirée jeux de société\""
}
]
}
],
"filePath": "features/notif/us-19-recapitulatif.feature",
"rawContent": "# language: fr\n# Note: US-19 concerne les récapitulatifs par email - non testable via écrans\n# Les scénarios ci-dessous testent l'affichage sur l'écran d'accueil (aspect UI)\n@NOTIF @priority-2\nFonctionnalité: US-19 Recevoir un récapitulatif des prochaines rencontres\n En tant qu'utilisateur\n Je peux recevoir un récapitulatif des prochaines rencontres\n En réceptionnant une liste des événements auxquels je suis inscrit ou qui sont proches de chez moi\n Afin d'établir un programme des événements auxquels je participe par période\n\n Contexte:\n Étant donné que je suis connecté en tant qu'utilisateur\n\n Scénario: Voir les événements à venir sur l'accueil\n Étant donné que je suis sur la page \"accueil\"\n Alors l'écran contient une section \"Événements à venir\"\n\n Scénario: Voir le récapitulatif par période\n * Scénario non implémenté\n\n Scénario: Voir les événements proches géographiquement\n * Scénario non implémenté\n\n Scénario: Voir mes inscriptions\n * Scénario non implémenté\n\n Scénario: Vérifier les données de l'accueil\n * Scénario non implémenté\n",
"rawContent": "# language: fr\n# Note: US-19 concerne les récapitulatifs par email - non testable via écrans\n# Les scénarios ci-dessous testent l'affichage sur l'écran d'accueil (aspect UI)\n@NOTIF @priority-2\nFonctionnalité: US-19 Recevoir un récapitulatif des prochaines rencontres\n En tant qu'utilisateur\n Je peux recevoir un récapitulatif des prochaines rencontres\n En réceptionnant une liste des événements auxquels je suis inscrit ou qui sont proches de chez moi\n Afin d'établir un programme des événements auxquels je participe par période\n\n Contexte:\n Étant donné que je suis connecté en tant qu'utilisateur\n\n Scénario: Voir les événements à venir sur l'accueil\n Étant donné que je suis sur la page \"accueil\"\n Alors l'écran contient une section \"Événements à venir\"\n\n Scénario: Voir le récapitulatif par période\n * Scénario non implémenté\n\n Scénario: Voir les événements proches géographiquement\n * Scénario non implémenté\n\n Scénario: Voir mes inscriptions\n Étant donné que je suis sur la page \"mon profil\"\n Alors l'écran contient une section \"Mes événements à venir\"\n\n Scénario: Vérifier les données de l'accueil\n Étant donné que je suis sur la page \"accueil\"\n Alors l'écran contient un texte \"Barbecue d'été\"\n Et l'écran contient un texte \"Soirée jeux de société\"\n",
"screenIds": [
"home"
"home",
"profile"
]
},
{
@@ -922,10 +1106,15 @@ export const parsedFeatures: ParsedFeature[] = [
"name": "Vérifier les données de l'écran profil",
"tags": [],
"steps": []
},
{
"name": "Voir la vue carte des événements",
"tags": [],
"steps": []
}
],
"filePath": "features/user/us-12-carte-evenements.feature",
"rawContent": "# language: fr\n@USER @priority-2\nFonctionnalité: US-12 Consulter la carte/tableau des événements\n En tant qu'utilisateur\n Je peux consulter la carte/tableau des événements auxquels j'ai participé\n En filtrant les événements par dates ou par personne\n Afin d'avoir une vue consolidée des événements et lieux de rencontre\n\n Contexte:\n Étant donné que je suis connecté en tant qu'utilisateur\n\n Scénario: Accéder à la liste des événements depuis le profil\n * Scénario non implémenté\n\n Scénario: Accéder à la liste des événements depuis découvrir\n Étant donné que je suis sur la page \"découvrir\"\n Alors je peux voir la liste des événements\n\n Scénario: Filtrer par date\n * Scénario non implémenté\n\n Scénario: Filtrer par personne\n Étant donné que je suis sur la page \"profil utilisateur\"\n Alors je peux voir les événements auxquels l'utilisateur a participé\n\n Scénario: Vérifier les données de l'écran événements\n * Scénario non implémenté\n\n Scénario: Vérifier les données de l'écran profil\n * Scénario non implémenté\n",
"rawContent": "# language: fr\n@USER @priority-2\nFonctionnalité: US-12 Consulter la carte/tableau des événements\n En tant qu'utilisateur\n Je peux consulter la carte/tableau des événements auxquels j'ai participé\n En filtrant les événements par dates ou par personne\n Afin d'avoir une vue consolidée des événements et lieux de rencontre\n\n Contexte:\n Étant donné que je suis connecté en tant qu'utilisateur\n\n Scénario: Accéder à la liste des événements depuis le profil\n * Scénario non implémenté\n\n Scénario: Accéder à la liste des événements depuis découvrir\n Étant donné que je suis sur la page \"découvrir\"\n Alors je peux voir la liste des événements\n\n Scénario: Filtrer par date\n * Scénario non implémenté\n\n Scénario: Filtrer par personne\n Étant donné que je suis sur la page \"profil utilisateur\"\n Alors je peux voir les événements auxquels l'utilisateur a participé\n\n Scénario: Vérifier les données de l'écran événements\n * Scénario non implémenté\n\n Scénario: Vérifier les données de l'écran profil\n * Scénario non implémenté\n\n Scénario: Voir la vue carte des événements\n * Scénario non implémenté\n",
"screenIds": [
"events",
"user-profile"
@@ -999,7 +1188,20 @@ export const parsedFeatures: ParsedFeature[] = [
{
"name": "Accéder à la création d'événement",
"tags": [],
"steps": []
"steps": [
{
"keyword": "Étant donné que ",
"text": "je suis sur la page \"accueil\""
},
{
"keyword": "Quand",
"text": "je navigue vers \"créer un événement\""
},
{
"keyword": "Alors",
"text": "je vois l'écran \"create-event\""
}
]
},
{
"name": "Définir le rayon d'intérêt",
@@ -1036,9 +1238,10 @@ export const parsedFeatures: ParsedFeature[] = [
}
],
"filePath": "features/user/us-26-portee-evenement.feature",
"rawContent": "# language: fr\n@USER @priority-2\nFonctionnalité: US-26 Définir la portée d'un événement\n En tant qu'utilisateur\n Je peux créer/présenter le contenu d'un événement et le catégoriser par type/thématique\n En indiquant son rayon d'intérêt en kilomètres\n Afin de m'assurer que les utilisateurs qui habitent trop loin ne reçoivent pas de notification\n\n Contexte:\n Étant donné que je suis connecté en tant qu'utilisateur\n\n Scénario: Accéder à la création d'événement\n * Scénario non implémenté\n\n Scénario: Définir le rayon d'intérêt\n * Scénario non implémenté\n\n Scénario: Choisir une thématique\n Étant donné que je suis sur la page \"créer un événement\"\n Alors l'écran contient une section \"Thématique\"\n\n Scénario: Vérifier les champs obligatoires\n Étant donné que l'écran \"create-event\" est affiché\n Alors le formulaire contient les champs obligatoires suivants:\n | Nom de l'événement |\n | Date |\n | Heure de début |\n | Lieu |\n | Thématique |\n",
"rawContent": "# language: fr\n@USER @priority-2\nFonctionnalité: US-26 Définir la portée d'un événement\n En tant qu'utilisateur\n Je peux créer/présenter le contenu d'un événement et le catégoriser par type/thématique\n En indiquant son rayon d'intérêt en kilomètres\n Afin de m'assurer que les utilisateurs qui habitent trop loin ne reçoivent pas de notification\n\n Contexte:\n Étant donné que je suis connecté en tant qu'utilisateur\n\n Scénario: Accéder à la création d'événement\n Étant donné que je suis sur la page \"accueil\"\n Quand je navigue vers \"créer un événement\"\n Alors je vois l'écran \"create-event\"\n\n Scénario: Définir le rayon d'intérêt\n * Scénario non implémenté\n\n Scénario: Choisir une thématique\n Étant donné que je suis sur la page \"créer un événement\"\n Alors l'écran contient une section \"Thématique\"\n\n Scénario: Vérifier les champs obligatoires\n Étant donné que l'écran \"create-event\" est affiché\n Alors le formulaire contient les champs obligatoires suivants:\n | Nom de l'événement |\n | Date |\n | Heure de début |\n | Lieu |\n | Thématique |\n",
"screenIds": [
"create-event"
"create-event",
"home"
]
},
{
@@ -1118,27 +1321,96 @@ export const parsedFeatures: ParsedFeature[] = [
{
"name": "Accéder au partage de profil",
"tags": [],
"steps": []
"steps": [
{
"keyword": "Étant donné que ",
"text": "je suis sur la page \"profil\""
},
{
"keyword": "Alors",
"text": "l'écran contient un bouton \"Partager\""
}
]
},
{
"name": "Naviguer vers le partage de profil",
"tags": [],
"steps": [
{
"keyword": "Étant donné que ",
"text": "je suis sur la page \"profil\""
},
{
"keyword": "Quand",
"text": "je navigue vers \"partage de profil\""
},
{
"keyword": "Alors",
"text": "je vois l'écran \"share-profile\""
}
]
},
{
"name": "Voir le QR code de parrainage",
"tags": [],
"steps": []
"steps": [
{
"keyword": "Étant donné que ",
"text": "je suis sur la page \"partage profil\""
},
{
"keyword": "Alors",
"text": "l'écran contient un texte \"Scannez pour me retrouver sur Festipod\""
}
]
},
{
"name": "Voir le lien de parrainage",
"tags": [],
"steps": []
"steps": [
{
"keyword": "Étant donné que ",
"text": "je suis sur la page \"partage profil\""
},
{
"keyword": "Alors",
"text": "l'écran contient une section \"Mon lien de profil\""
},
{
"keyword": "Et",
"text": "l'écran contient un bouton \"Copier\""
}
]
},
{
"name": "Voir les statistiques de parrainage",
"tags": [],
"steps": []
"steps": [
{
"keyword": "Étant donné que ",
"text": "je suis sur la page \"partage profil\""
},
{
"keyword": "Alors",
"text": "l'écran contient une section \"Statistiques de parrainage\""
},
{
"keyword": "Et",
"text": "l'écran contient un texte \"Personnes parrainées\""
},
{
"keyword": "Et",
"text": "l'écran contient un texte \"Scans du QR code\""
}
]
}
],
"filePath": "features/user/us-22-parrainer.feature",
"rawContent": "# language: fr\n@USER @priority-2\nFonctionnalité: US-22 Parrainer un nouvel utilisateur\n En tant qu'utilisateur\n Je peux parrainer un nouvel utilisateur\n En lui partageant mon QR code ou lien de contact\n Afin de savoir combien de personnes ont rejoint le réseau grâce à moi\n\n Contexte:\n Étant donné que je suis connecté en tant qu'utilisateur\n\n Scénario: Accéder au partage de profil\n * Scénario non implémenté\n\n Scénario: Voir le QR code de parrainage\n * Scénario non implémenté\n\n Scénario: Voir le lien de parrainage\n * Scénario non implémenté\n\n Scénario: Voir les statistiques de parrainage\n * Scénario non implémenté\n",
"screenIds": []
"rawContent": "# language: fr\n@USER @priority-2\nFonctionnalité: US-22 Parrainer un nouvel utilisateur\n En tant qu'utilisateur\n Je peux parrainer un nouvel utilisateur\n En lui partageant mon QR code ou lien de contact\n Afin de savoir combien de personnes ont rejoint le réseau grâce à moi\n\n Contexte:\n Étant donné que je suis connecté en tant qu'utilisateur\n\n Scénario: Accéder au partage de profil\n Étant donné que je suis sur la page \"profil\"\n Alors l'écran contient un bouton \"Partager\"\n\n Scénario: Naviguer vers le partage de profil\n Étant donné que je suis sur la page \"profil\"\n Quand je navigue vers \"partage de profil\"\n Alors je vois l'écran \"share-profile\"\n\n Scénario: Voir le QR code de parrainage\n Étant donné que je suis sur la page \"partage profil\"\n Alors l'écran contient un texte \"Scannez pour me retrouver sur Festipod\"\n\n Scénario: Voir le lien de parrainage\n Étant donné que je suis sur la page \"partage profil\"\n Alors l'écran contient une section \"Mon lien de profil\"\n Et l'écran contient un bouton \"Copier\"\n\n Scénario: Voir les statistiques de parrainage\n Étant donné que je suis sur la page \"partage profil\"\n Alors l'écran contient une section \"Statistiques de parrainage\"\n Et l'écran contient un texte \"Personnes parrainées\"\n Et l'écran contient un texte \"Scans du QR code\"\n",
"screenIds": [
"profile",
"share-profile"
]
},
{
"id": "us-21",
@@ -1248,10 +1520,15 @@ export const parsedFeatures: ParsedFeature[] = [
"name": "Supprimer un commentaire",
"tags": [],
"steps": []
},
{
"name": "Enregistrer les interactions avec des individus (Date/Heure/Lieu)",
"tags": [],
"steps": []
}
],
"filePath": "features/event/us-5-commentaires-evenement.feature",
"rawContent": "# language: fr\n@EVENT @priority-3\nFonctionnalité: US-5 Ajouter/modifier/supprimer un commentaire à un événement\n En tant qu'utilisateur\n Je peux consulter et ajouter/modifier/supprimer un commentaire à un événement\n En sélectionnant l'icône \"ajouter un commentaire\" en dessous du titre\n Afin de voir les commentaires précédents et ajouter mes notes personnelles\n\n Contexte:\n Étant donné que je suis connecté en tant qu'utilisateur\n\n Scénario: Voir les commentaires existants\n * Scénario non implémenté\n\n Scénario: Ajouter un commentaire\n * Scénario non implémenté\n\n Scénario: Modifier un commentaire\n * Scénario non implémenté\n\n Scénario: Supprimer un commentaire\n * Scénario non implémenté\n",
"rawContent": "# language: fr\n@EVENT @priority-3\nFonctionnalité: US-5 Ajouter/modifier/supprimer un commentaire à un événement\n En tant qu'utilisateur\n Je peux consulter et ajouter/modifier/supprimer un commentaire à un événement\n En sélectionnant l'icône \"ajouter un commentaire\" en dessous du titre\n Afin de voir les commentaires précédents et ajouter mes notes personnelles\n\n Contexte:\n Étant donné que je suis connecté en tant qu'utilisateur\n\n Scénario: Voir les commentaires existants\n * Scénario non implémenté\n\n Scénario: Ajouter un commentaire\n * Scénario non implémenté\n\n Scénario: Modifier un commentaire\n * Scénario non implémenté\n\n Scénario: Supprimer un commentaire\n * Scénario non implémenté\n\n Scénario: Enregistrer les interactions avec des individus (Date/Heure/Lieu)\n * Scénario non implémenté\n",
"screenIds": []
},
{
@@ -1290,10 +1567,30 @@ export const parsedFeatures: ParsedFeature[] = [
"name": "Voir la consolidation des participants",
"tags": [],
"steps": []
},
{
"name": "Créer un macro-événement",
"tags": [],
"steps": []
},
{
"name": "Voir la consolidation des commentaires/liens/ressources",
"tags": [],
"steps": []
},
{
"name": "Rattacher à une thématique particulière",
"tags": [],
"steps": []
},
{
"name": "Gérer un événement répété sur plusieurs périodes",
"tags": [],
"steps": []
}
],
"filePath": "features/event/us-8-macro-evenement.feature",
"rawContent": "# language: fr\n@EVENT @priority-3\nFonctionnalité: US-8 Consulter et m'inscrire à un macro-événement\n En tant qu'utilisateur\n Je peux consulter et m'inscrire à un événement de type \"Macro-événement\"\n En créant ou en rattachant des événements existants à ce macro-événement\n Afin de voir une consolidation des commentaires/liens/ressources/participants\n\n Contexte:\n Étant donné que je suis connecté en tant qu'utilisateur\n\n Scénario: Consulter un macro-événement\n * Scénario non implémenté\n\n Scénario: Voir les événements rattachés\n * Scénario non implémenté\n\n Scénario: Rattacher un événement existant\n * Scénario non implémenté\n\n Scénario: Voir la consolidation des participants\n * Scénario non implémenté\n",
"rawContent": "# language: fr\n@EVENT @priority-3\nFonctionnalité: US-8 Consulter et m'inscrire à un macro-événement\n En tant qu'utilisateur\n Je peux consulter et m'inscrire à un événement de type \"Macro-événement\"\n En créant ou en rattachant des événements existants à ce macro-événement\n Afin de voir une consolidation des commentaires/liens/ressources/participants\n\n Contexte:\n Étant donné que je suis connecté en tant qu'utilisateur\n\n Scénario: Consulter un macro-événement\n * Scénario non implémenté\n\n Scénario: Voir les événements rattachés\n * Scénario non implémenté\n\n Scénario: Rattacher un événement existant\n * Scénario non implémenté\n\n Scénario: Voir la consolidation des participants\n * Scénario non implémenté\n\n Scénario: Créer un macro-événement\n * Scénario non implémenté\n\n Scénario: Voir la consolidation des commentaires/liens/ressources\n * Scénario non implémenté\n\n Scénario: Rattacher à une thématique particulière\n * Scénario non implémenté\n\n Scénario: Gérer un événement répété sur plusieurs périodes\n * Scénario non implémenté\n",
"screenIds": []
},
{
@@ -1327,10 +1624,20 @@ export const parsedFeatures: ParsedFeature[] = [
"name": "Consulter les ressources d'un atelier",
"tags": [],
"steps": []
},
{
"name": "Consulter le programme détaillé par journée/heure",
"tags": [],
"steps": []
},
{
"name": "Accéder à la zone de partage collective",
"tags": [],
"steps": []
}
],
"filePath": "features/workshop/us-1-visualiser-atelier-termine.feature",
"rawContent": "# language: fr\n@WORKSHOP @priority-3\nFonctionnalité: US-1 Visualiser un événement terminé (ateliers)\n En tant qu'utilisateur\n Je peux visualiser un événement terminé et consulter le programme détaillé des ateliers par journée/heure\n Afin de voir les personnes qui ont participé à chaque atelier et consulter les notes/liens/commentaires\n\n Contexte:\n Étant donné que je suis connecté en tant qu'utilisateur\n\n Scénario: Accéder aux détails d'un événement terminé\n * Scénario non implémenté\n\n Scénario: Consulter la liste des participants d'un atelier\n * Scénario non implémenté\n\n Scénario: Consulter les ressources d'un atelier\n * Scénario non implémenté\n",
"rawContent": "# language: fr\n@WORKSHOP @priority-3\nFonctionnalité: US-1 Visualiser un événement terminé (ateliers)\n En tant qu'utilisateur\n Je peux visualiser un événement terminé et consulter le programme détaillé des ateliers par journée/heure\n Afin de voir les personnes qui ont participé à chaque atelier et consulter les notes/liens/commentaires\n\n Contexte:\n Étant donné que je suis connecté en tant qu'utilisateur\n\n Scénario: Accéder aux détails d'un événement terminé\n * Scénario non implémenté\n\n Scénario: Consulter la liste des participants d'un atelier\n * Scénario non implémenté\n\n Scénario: Consulter les ressources d'un atelier\n * Scénario non implémenté\n\n Scénario: Consulter le programme détaillé par journée/heure\n * Scénario non implémenté\n\n Scénario: Accéder à la zone de partage collective\n * Scénario non implémenté\n",
"screenIds": []
},
{
@@ -1369,10 +1676,15 @@ export const parsedFeatures: ParsedFeature[] = [
"name": "Ajouter un lien/ressource",
"tags": [],
"steps": []
},
{
"name": "Consulter le programme détaillé des ateliers par journée/heure",
"tags": [],
"steps": []
}
],
"filePath": "features/workshop/us-2-visualiser-notes-atelier.feature",
"rawContent": "# language: fr\n@WORKSHOP @priority-3\nFonctionnalité: US-2 Visualiser un événement terminé (notes)\n En tant qu'utilisateur\n Je peux visualiser un événement terminé et consulter le programme détaillé des ateliers\n Afin d'ajouter d'éventuelles prises de notes/liens ou des commentaires associés à l'atelier\n\n Contexte:\n Étant donné que je suis connecté en tant qu'utilisateur\n\n Scénario: Accéder à la zone de notes personnelles\n * Scénario non implémenté\n\n Scénario: Accéder à la zone de partage publique\n * Scénario non implémenté\n\n Scénario: Ajouter une note personnelle\n * Scénario non implémenté\n\n Scénario: Ajouter un lien/ressource\n * Scénario non implémenté\n",
"rawContent": "# language: fr\n@WORKSHOP @priority-3\nFonctionnalité: US-2 Visualiser un événement terminé (notes)\n En tant qu'utilisateur\n Je peux visualiser un événement terminé et consulter le programme détaillé des ateliers\n Afin d'ajouter d'éventuelles prises de notes/liens ou des commentaires associés à l'atelier\n\n Contexte:\n Étant donné que je suis connecté en tant qu'utilisateur\n\n Scénario: Accéder à la zone de notes personnelles\n * Scénario non implémenté\n\n Scénario: Accéder à la zone de partage publique\n * Scénario non implémenté\n\n Scénario: Ajouter une note personnelle\n * Scénario non implémenté\n\n Scénario: Ajouter un lien/ressource\n * Scénario non implémenté\n\n Scénario: Consulter le programme détaillé des ateliers par journée/heure\n * Scénario non implémenté\n",
"screenIds": []
},
{
@@ -1400,16 +1712,7 @@ export const parsedFeatures: ParsedFeature[] = [
{
"name": "Vérifier les champs obligatoires pour créer un atelier",
"tags": [],
"steps": [
{
"keyword": "Étant donné que ",
"text": "l'écran \"create-event\" est affiché"
},
{
"keyword": "Alors",
"text": "le formulaire contient les champs obligatoires suivants:"
}
]
"steps": []
},
{
"name": "Créer un atelier",
@@ -1425,13 +1728,21 @@ export const parsedFeatures: ParsedFeature[] = [
"name": "Supprimer un atelier",
"tags": [],
"steps": []
},
{
"name": "Sélectionner mon événement parent",
"tags": [],
"steps": []
},
{
"name": "Définir les horaires de fin de l'atelier",
"tags": [],
"steps": []
}
],
"filePath": "features/workshop/us-14-creer-atelier.feature",
"rawContent": "# language: fr\n@WORKSHOP @priority-3\nFonctionnalité: US-14 Créer/Modifier/Supprimer un atelier\n En tant qu'utilisateur\n Je peux créer/modifier/supprimer un atelier\n En sélectionnant mon événement et en saisissant les dates et horaires de l'atelier\n Afin de définir le programme de mon événement et ajouter une description\n\n Contexte:\n Étant donné que je suis connecté en tant qu'utilisateur\n\n Scénario: Accéder à la création d'atelier\n * Scénario non implémenté\n\n Scénario: Vérifier les champs obligatoires pour créer un atelier\n Étant donné que l'écran \"create-event\" est affiché\n Alors le formulaire contient les champs obligatoires suivants:\n | Nom de l'événement |\n | Date |\n | Heure de début |\n | Lieu |\n | Thématique |\n\n Scénario: Créer un atelier\n * Scénario non implémenté\n\n Scénario: Modifier un atelier existant\n * Scénario non implémenté\n\n Scénario: Supprimer un atelier\n * Scénario non implémenté\n",
"screenIds": [
"create-event"
]
"rawContent": "# language: fr\n@WORKSHOP @priority-3\nFonctionnalité: US-14 Créer/Modifier/Supprimer un atelier\n En tant qu'utilisateur\n Je peux créer/modifier/supprimer un atelier\n En sélectionnant mon événement et en saisissant les dates et horaires de l'atelier\n Afin de définir le programme de mon événement et ajouter une description\n\n Contexte:\n Étant donné que je suis connecté en tant qu'utilisateur\n\n Scénario: Accéder à la création d'atelier\n * Scénario non implémenté\n\n Scénario: Vérifier les champs obligatoires pour créer un atelier\n * Scénario non implémenté\n\n Scénario: Créer un atelier\n * Scénario non implémenté\n\n Scénario: Modifier un atelier existant\n * Scénario non implémenté\n\n Scénario: Supprimer un atelier\n * Scénario non implémenté\n\n Scénario: Sélectionner mon événement parent\n * Scénario non implémenté\n\n Scénario: Définir les horaires de fin de l'atelier\n * Scénario non implémenté\n",
"screenIds": []
},
{
"id": "us-11",
@@ -1506,16 +1817,21 @@ export const parsedFeatures: ParsedFeature[] = [
"name": "Supprimer un commentaire",
"tags": [],
"steps": []
},
{
"name": "Accéder à l'icône ajouter un commentaire",
"tags": [],
"steps": []
}
],
"filePath": "features/workshop/us-4-commentaires-atelier.feature",
"rawContent": "# language: fr\n@WORKSHOP @priority-3\nFonctionnalité: US-4 Ajouter/modifier/supprimer un commentaire à un atelier\n En tant qu'utilisateur\n Je peux consulter et ajouter/modifier/supprimer un commentaire à un atelier\n En sélectionnant l'icône \"ajouter un commentaire\" en dessous du titre de l'atelier\n Afin de voir les commentaires précédents et ajouter mes commentaires\n\n Contexte:\n Étant donné que je suis connecté en tant qu'utilisateur\n\n Scénario: Voir les commentaires existants d'un atelier\n * Scénario non implémenté\n\n Scénario: Ajouter un commentaire à un atelier\n * Scénario non implémenté\n\n Scénario: Modifier un commentaire existant\n * Scénario non implémenté\n\n Scénario: Supprimer un commentaire\n * Scénario non implémenté\n",
"rawContent": "# language: fr\n@WORKSHOP @priority-3\nFonctionnalité: US-4 Ajouter/modifier/supprimer un commentaire à un atelier\n En tant qu'utilisateur\n Je peux consulter et ajouter/modifier/supprimer un commentaire à un atelier\n En sélectionnant l'icône \"ajouter un commentaire\" en dessous du titre de l'atelier\n Afin de voir les commentaires précédents et ajouter mes commentaires\n\n Contexte:\n Étant donné que je suis connecté en tant qu'utilisateur\n\n Scénario: Voir les commentaires existants d'un atelier\n * Scénario non implémenté\n\n Scénario: Ajouter un commentaire à un atelier\n * Scénario non implémenté\n\n Scénario: Modifier un commentaire existant\n * Scénario non implémenté\n\n Scénario: Supprimer un commentaire\n * Scénario non implémenté\n\n Scénario: Accéder à l'icône ajouter un commentaire\n * Scénario non implémenté\n",
"screenIds": []
},
{
"id": "us-6",
"name": "US-6 M'inscrire/me désinscrire à un événement (atelier)",
"description": "En tant qu'utilisateur Je peux m'inscrire/me désinscrire à un événement En regardant si l'événement public existe déjà et en m'enregistrant sur les différents ateliers Afin de m'inscrire à l'atelier tout en visualisant les personnes qui sont déjà pré-inscrites",
"name": "US-6 M'inscrire/me désinscrire à un atelier",
"description": "En tant qu'utilisateur Je peux m'inscrire/me désinscrire à un atelier En regardant si l'événement public existe déjà et en m'enregistrant sur les différents ateliers Afin de m'inscrire à l'atelier tout en visualisant les personnes qui sont déjà pré-inscrites",
"tags": [
"@WORKSHOP",
"@priority-3"
@@ -1530,32 +1846,14 @@ export const parsedFeatures: ParsedFeature[] = [
],
"scenarios": [
{
"name": "Rechercher un événement public existant",
"name": "Voir les ateliers d'un événement",
"tags": [],
"steps": [
{
"keyword": "Étant donné que ",
"text": "je suis sur la page \"découvrir\""
},
{
"keyword": "Alors",
"text": "je peux voir la liste des événements"
}
]
"steps": []
},
{
"name": "Voir les personnes pré-inscrites à un atelier",
"tags": [],
"steps": [
{
"keyword": "Étant donné que ",
"text": "je suis sur la page \"détail événement\""
},
{
"keyword": "Alors",
"text": "je peux voir la liste des participants"
}
]
"steps": []
},
{
"name": "S'inscrire à un atelier",
@@ -1569,11 +1867,8 @@ export const parsedFeatures: ParsedFeature[] = [
}
],
"filePath": "features/workshop/us-6-inscription-atelier.feature",
"rawContent": "# language: fr\n@WORKSHOP @priority-3\nFonctionnalité: US-6 M'inscrire/me désinscrire à un événement (atelier)\n En tant qu'utilisateur\n Je peux m'inscrire/me désinscrire à un événement\n En regardant si l'événement public existe déjà et en m'enregistrant sur les différents ateliers\n Afin de m'inscrire à l'atelier tout en visualisant les personnes qui sont déjà pré-inscrites\n\n Contexte:\n Étant donné que je suis connecté en tant qu'utilisateur\n\n Scénario: Rechercher un événement public existant\n Étant donné que je suis sur la page \"découvrir\"\n Alors je peux voir la liste des événements\n\n Scénario: Voir les personnes pré-inscrites à un atelier\n Étant donné que je suis sur la page \"détail événement\"\n Alors je peux voir la liste des participants\n\n Scénario: S'inscrire à un atelier\n * Scénario non implémenté\n\n Scénario: Se désinscrire d'un atelier\n * Scénario non implémenté\n",
"screenIds": [
"event-detail",
"events"
]
"rawContent": "# language: fr\n@WORKSHOP @priority-3\nFonctionnalité: US-6 M'inscrire/me désinscrire à un atelier\n En tant qu'utilisateur\n Je peux m'inscrire/me désinscrire à un atelier\n En regardant si l'événement public existe déjà et en m'enregistrant sur les différents ateliers\n Afin de m'inscrire à l'atelier tout en visualisant les personnes qui sont déjà pré-inscrites\n\n Contexte:\n Étant donné que je suis connecté en tant qu'utilisateur\n\n Scénario: Voir les ateliers d'un événement\n * Scénario non implémenté\n\n Scénario: Voir les personnes pré-inscrites à un atelier\n * Scénario non implémenté\n\n Scénario: S'inscrire à un atelier\n * Scénario non implémenté\n\n Scénario: Se désinscrire d'un atelier\n * Scénario non implémenté\n",
"screenIds": []
}
];
+75 -159
View File
@@ -22,119 +22,147 @@ export const stepDefinitions: StepDefinitionInfo[] = [
"keyword": "Given",
"file": "navigation.steps.ts",
"sourceCode": "Given('je suis sur la page {string}', async function (this: FestipodWorld, pageName: string) {\n const screenId = resolveScreenId(pageName);\n this.navigateTo(`#/demo/${screenId}`);\n});",
"lineNumber": 37
"lineNumber": 38
},
{
"pattern": "je suis connecté en tant qu'utilisateur",
"keyword": "Given",
"file": "navigation.steps.ts",
"sourceCode": "Given('je suis connecté en tant qu\\'utilisateur', async function (this: FestipodWorld) {\n this.isAuthenticated = true;\n});",
"lineNumber": 42
"lineNumber": 43
},
{
"pattern": "je suis connecté",
"keyword": "Given",
"file": "navigation.steps.ts",
"sourceCode": "Given('je suis connecté', async function (this: FestipodWorld) {\n this.isAuthenticated = true;\n});",
"lineNumber": 46
"lineNumber": 47
},
{
"pattern": "je ne suis pas connecté",
"keyword": "Given",
"file": "navigation.steps.ts",
"sourceCode": "Given('je ne suis pas connecté', async function (this: FestipodWorld) {\n this.isAuthenticated = false;\n});",
"lineNumber": 50
"lineNumber": 51
},
{
"pattern": "je navigue vers {string}",
"keyword": "When",
"file": "navigation.steps.ts",
"sourceCode": "When('je navigue vers {string}', async function (this: FestipodWorld, pageName: string) {\n const screenId = resolveScreenId(pageName);\n this.navigateTo(`#/demo/${screenId}`);\n});",
"lineNumber": 54
"lineNumber": 55
},
{
"pattern": "je clique sur {string}",
"keyword": "When",
"file": "navigation.steps.ts",
"sourceCode": "When('je clique sur {string}', async function (this: FestipodWorld, elementName: string) {\n const source = this.getRenderedText();\n // Check that a clickable element with this text exists (onClick handler + text content)\n const escapedName = elementName.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n const pattern = new RegExp(`onClick[^>]*>[^<]*${escapedName}`, 'i');\n const found = pattern.test(source);\n if (!found) {\n this.attach(`MISSING: Clickable element \"${elementName}\" not found in screen \"${this.currentScreenId}\"`, 'text/plain');\n return 'pending';\n }\n});",
"lineNumber": 59
"sourceCode": "When('je clique sur {string}', async function (this: FestipodWorld, elementName: string) {\n const source = this.getRenderedText();\n // Check that a clickable element with this text exists (onClick handler + text content)\n const escapedName = elementName.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n const pattern = new RegExp(`onClick[^>]*>[^<]*${escapedName}`, 'i');\n expect(pattern.test(source), `Clickable element \"${elementName}\" should exist in screen \"${this.currentScreenId}\"`).to.be.true;\n});",
"lineNumber": 60
},
{
"pattern": "je sélectionne {string}",
"keyword": "When",
"file": "navigation.steps.ts",
"sourceCode": "When('je sélectionne {string}', async function (this: FestipodWorld, elementName: string) {\n const source = this.getRenderedText();\n // Check that a selectable element with this text exists\n const escapedName = elementName.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n const pattern = new RegExp(`onClick[^>]*>[^<]*${escapedName}`, 'i');\n const found = pattern.test(source);\n if (!found) {\n this.attach(`MISSING: Selectable element \"${elementName}\" not found in screen \"${this.currentScreenId}\"`, 'text/plain');\n return 'pending';\n }\n});",
"lineNumber": 71
"sourceCode": "When('je sélectionne {string}', async function (this: FestipodWorld, elementName: string) {\n const source = this.getRenderedText();\n // Check that a selectable element with this text exists\n const escapedName = elementName.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n const pattern = new RegExp(`onClick[^>]*>[^<]*${escapedName}`, 'i');\n expect(pattern.test(source), `Selectable element \"${elementName}\" should exist in screen \"${this.currentScreenId}\"`).to.be.true;\n});",
"lineNumber": 68
},
{
"pattern": "je clique sur le bouton {string}",
"keyword": "When",
"file": "navigation.steps.ts",
"sourceCode": "When('je clique sur le bouton {string}', async function (this: FestipodWorld, buttonName: string) {\n const source = this.getRenderedText();\n // Check that a Button component with this label exists\n const escapedName = buttonName.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n const pattern = new RegExp(`<Button[^>]*>[^<]*${escapedName}[^<]*</Button>`, 'i');\n const found = pattern.test(source);\n if (!found) {\n this.attach(`MISSING: Button \"${buttonName}\" not found in screen \"${this.currentScreenId}\"`, 'text/plain');\n return 'pending';\n }\n});",
"lineNumber": 83
"sourceCode": "When('je clique sur le bouton {string}', async function (this: FestipodWorld, buttonName: string) {\n const source = this.getRenderedText();\n // Check that a Button component with this label exists\n const escapedName = buttonName.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n const pattern = new RegExp(`<Button[^>]*>[^<]*${escapedName}[^<]*</Button>`, 'i');\n expect(pattern.test(source), `Button \"${buttonName}\" should exist in screen \"${this.currentScreenId}\"`).to.be.true;\n});",
"lineNumber": 76
},
{
"pattern": "je clique sur un participant",
"keyword": "When",
"file": "navigation.steps.ts",
"sourceCode": "When('je clique sur un participant', async function (this: FestipodWorld) {\n this.navigateTo('#/demo/user-profile');\n});",
"lineNumber": 95
"lineNumber": 84
},
{
"pattern": "je clique sur un événement",
"keyword": "When",
"file": "navigation.steps.ts",
"sourceCode": "When('je clique sur un événement', async function (this: FestipodWorld) {\n this.navigateTo('#/demo/event-detail');\n});",
"lineNumber": 99
"lineNumber": 88
},
{
"pattern": "je suis redirigé vers {string}",
"keyword": "Then",
"file": "navigation.steps.ts",
"sourceCode": "Then('je suis redirigé vers {string}', async function (this: FestipodWorld, pageName: string) {\n const screenId = resolveScreenId(pageName);\n expect(this.currentScreenId).to.equal(screenId);\n});",
"lineNumber": 103
"lineNumber": 92
},
{
"pattern": "je vois l'écran {string}",
"keyword": "Then",
"file": "navigation.steps.ts",
"sourceCode": "Then('je vois l\\'écran {string}', async function (this: FestipodWorld, pageName: string) {\n const screenId = resolveScreenId(pageName);\n expect(this.currentScreenId).to.equal(screenId);\n});",
"lineNumber": 108
"lineNumber": 97
},
{
"pattern": "je reste sur la page {string}",
"keyword": "Then",
"file": "navigation.steps.ts",
"sourceCode": "Then('je reste sur la page {string}', async function (this: FestipodWorld, pageName: string) {\n const screenId = resolveScreenId(pageName);\n expect(this.currentScreenId).to.equal(screenId);\n});",
"lineNumber": 113
"lineNumber": 102
},
{
"pattern": "l'écran contient une section {string}",
"keyword": "Then",
"file": "navigation.steps.ts",
"sourceCode": "Then('l\\'écran contient une section {string}', async function (this: FestipodWorld, sectionName: string) {\n const found = this.hasText(sectionName);\n if (!found) {\n this.attach(`MISSING SECTION: \"${sectionName}\" not found in screen \"${this.currentScreenId}\"`, 'text/plain');\n return 'pending';\n }\n});",
"lineNumber": 118
"sourceCode": "Then('l\\'écran contient une section {string}', async function (this: FestipodWorld, sectionName: string) {\n expect(this.hasText(sectionName), `Section \"${sectionName}\" should be present in screen \"${this.currentScreenId}\"`).to.be.true;\n});",
"lineNumber": 107
},
{
"pattern": "je peux annuler et revenir à l'écran précédent",
"keyword": "Then",
"file": "navigation.steps.ts",
"sourceCode": "Then('je peux annuler et revenir à l\\'écran précédent', async function (this: FestipodWorld) {\n expect(this.currentScreenId).to.equal('create-event');\n const source = this.getRenderedText();\n // Detect ✕ close button with onClick handler that calls navigate()\n const found = /onClick\\s*=\\s*\\{\\s*\\(\\)\\s*=>\\s*navigate\\s*\\(['\"]home['\"]\\)\\s*\\}[^>]*>✕</.test(source);\n expect(found, 'Create event screen should have ✕ button with navigate(\"home\")').to.be.true;\n});",
"lineNumber": 126
"lineNumber": 111
},
{
"pattern": "je peux naviguer vers {string}",
"keyword": "Then",
"file": "navigation.steps.ts",
"sourceCode": "Then('je peux naviguer vers {string}', async function (this: FestipodWorld, pageName: string) {\n const screenId = resolveScreenId(pageName);\n const source = this.getRenderedText();\n // Check that a navigation link to this screen exists: navigate('screenId') or onClick={() => navigate('screenId')}\n const pattern = new RegExp(`navigate\\\\s*\\\\(\\\\s*['\"]${screenId}['\"]\\\\s*\\\\)`);\n const found = pattern.test(source);\n if (!found) {\n this.attach(`MISSING: Navigation to \"${screenId}\" not found in screen \"${this.currentScreenId}\"`, 'text/plain');\n return 'pending';\n }\n});",
"lineNumber": 134
"sourceCode": "Then('je peux naviguer vers {string}', async function (this: FestipodWorld, pageName: string) {\n const screenId = resolveScreenId(pageName);\n const source = this.getRenderedText();\n // Check that a navigation link to this screen exists: navigate('screenId') or onClick={() => navigate('screenId')}\n const pattern = new RegExp(`navigate\\\\s*\\\\(\\\\s*['\"]${screenId}['\"]\\\\s*\\\\)`);\n expect(pattern.test(source), `Navigation to \"${screenId}\" should exist in screen \"${this.currentScreenId}\"`).to.be.true;\n});",
"lineNumber": 119
},
{
"pattern": "la navigation affiche {string} comme actif",
"keyword": "Then",
"file": "navigation.steps.ts",
"sourceCode": "Then('la navigation affiche {string} comme actif', async function (this: FestipodWorld, menuItem: string) {\n const source = this.getRenderedText();\n // Check that NavBar has an item with this label and active: true\n // Pattern: { icon: '...', label: 'menuItem', active: true }\n const escapedItem = menuItem.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n const pattern = new RegExp(`label:\\\\s*['\"]${escapedItem}['\"][^}]*active:\\\\s*true`, 'i');\n const found = pattern.test(source);\n if (!found) {\n this.attach(`MISSING: Menu item \"${menuItem}\" is not active in NavBar of screen \"${this.currentScreenId}\"`, 'text/plain');\n return 'pending';\n }\n});",
"lineNumber": 146
"sourceCode": "Then('la navigation affiche {string} comme actif', async function (this: FestipodWorld, menuItem: string) {\n const source = this.getRenderedText();\n // Check that NavBar has an item with this label and active: true\n // Pattern: { icon: '...', label: 'menuItem', active: true }\n const escapedItem = menuItem.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n const pattern = new RegExp(`label:\\\\s*['\"]${escapedItem}['\"][^}]*active:\\\\s*true`, 'i');\n expect(pattern.test(source), `Menu item \"${menuItem}\" should be active in NavBar of screen \"${this.currentScreenId}\"`).to.be.true;\n});",
"lineNumber": 127
},
{
"pattern": "l'écran contient un bouton {string}",
"keyword": "Then",
"file": "navigation.steps.ts",
"sourceCode": "Then('l\\'écran contient un bouton {string}', async function (this: FestipodWorld, buttonText: string) {\n expect(this.hasText(buttonText), `Button \"${buttonText}\" should be present in screen \"${this.currentScreenId}\"`).to.be.true;\n});",
"lineNumber": 136
},
{
"pattern": "l'écran contient un champ {string}",
"keyword": "Then",
"file": "navigation.steps.ts",
"sourceCode": "Then('l\\'écran contient un champ {string}', async function (this: FestipodWorld, fieldLabel: string) {\n expect(this.hasText(fieldLabel), `Field \"${fieldLabel}\" should be present in screen \"${this.currentScreenId}\"`).to.be.true;\n});",
"lineNumber": 140
},
{
"pattern": "l'écran contient un texte {string}",
"keyword": "Then",
"file": "navigation.steps.ts",
"sourceCode": "Then('l\\'écran contient un texte {string}', async function (this: FestipodWorld, text: string) {\n expect(this.hasText(text), `Text \"${text}\" should be present in screen \"${this.currentScreenId}\"`).to.be.true;\n});",
"lineNumber": 144
},
{
"pattern": "l'écran contient un avatar",
"keyword": "Then",
"file": "navigation.steps.ts",
"sourceCode": "Then('l\\'écran contient un avatar', async function (this: FestipodWorld) {\n const source = this.getRenderedText();\n const hasAvatar = /<Avatar/.test(source);\n expect(hasAvatar, `Avatar should be present in screen \"${this.currentScreenId}\"`).to.be.true;\n});",
"lineNumber": 148
},
{
"pattern": "l'écran {string} est affiché",
@@ -150,75 +178,33 @@ export const stepDefinitions: StepDefinitionInfo[] = [
"sourceCode": "Given('le formulaire de création est vide', async function (this: FestipodWorld) {\n this.formFields.forEach((field, key) => {\n this.formFields.set(key, { ...field, value: '' });",
"lineNumber": 10
},
{
"pattern": "je remplis le champ {string} avec {string}",
"keyword": "When",
"file": "form.steps.ts",
"sourceCode": "When('je remplis le champ {string} avec {string}', async function (this: FestipodWorld, fieldName: string, value: string) {\n // Cannot fill form fields without browser automation\n this.attach(`CANNOT TEST: Filling field \"${fieldName}\" with \"${value}\" requires browser automation`, 'text/plain');\n return 'pending';\n});",
"lineNumber": 16
},
{
"pattern": "je laisse le champ {string} vide",
"keyword": "When",
"file": "form.steps.ts",
"sourceCode": "When('je laisse le champ {string} vide', async function (this: FestipodWorld, fieldName: string) {\n // Cannot manipulate form fields without browser automation\n this.attach(`CANNOT TEST: Leaving field \"${fieldName}\" empty requires browser automation`, 'text/plain');\n return 'pending';\n});",
"lineNumber": 22
},
{
"pattern": "je soumets le formulaire",
"keyword": "When",
"file": "form.steps.ts",
"sourceCode": "When('je soumets le formulaire', async function (this: FestipodWorld) {\n // Cannot submit forms without browser automation\n this.attach('CANNOT TEST: Form submission requires browser automation', 'text/plain');\n return 'pending';\n});",
"lineNumber": 28
},
{
"pattern": "le formulaire contient le champ obligatoire {string}",
"keyword": "Then",
"file": "form.steps.ts",
"sourceCode": "Then('le formulaire contient le champ obligatoire {string}', async function (this: FestipodWorld, fieldName: string) {\n // This step is for form screens only (create-event)\n // For display screens, use different steps\n if (this.currentScreenId !== 'create-event') {\n this.attach(`WRONG STEP: \"le formulaire contient le champ obligatoire\" is for forms. Screen \"${this.currentScreenId}\" is not a form.`, 'text/plain');\n return 'pending';\n }\n const source = this.getRenderedText();\n // CreateEventScreen.tsx: Required fields have \" *\" after label: >Label *<\n const escapedName = fieldName.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n const pattern = new RegExp(`>${escapedName}\\\\s*\\\\*<`);\n expect(pattern.test(source), `Field \"${fieldName}\" should be marked as required (with *) in create-event screen`).to.be.true;\n});",
"lineNumber": 34
"sourceCode": "Then('le formulaire contient le champ obligatoire {string}', async function (this: FestipodWorld, fieldName: string) {\n // This step is for form screens only (create-event)\n expect(this.currentScreenId, 'This step is for form screens only').to.equal('create-event');\n const source = this.getRenderedText();\n // CreateEventScreen.tsx: Required fields have \" *\" after label: >Label *<\n const escapedName = fieldName.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n const pattern = new RegExp(`>${escapedName}\\\\s*\\\\*<`);\n expect(pattern.test(source), `Field \"${fieldName}\" should be marked as required (with *) in create-event screen`).to.be.true;\n});",
"lineNumber": 19
},
{
"pattern": "le formulaire contient les champs obligatoires suivants:",
"keyword": "Then",
"file": "form.steps.ts",
"sourceCode": "Then('le formulaire contient les champs obligatoires suivants:', async function (this: FestipodWorld, dataTable) {\n // This step is for form screens only (create-event)\n // For display screens, use different steps\n if (this.currentScreenId !== 'create-event') {\n this.attach(`WRONG STEP: \"le formulaire contient les champs obligatoires\" is for forms. Screen \"${this.currentScreenId}\" is not a form.`, 'text/plain');\n return 'pending';\n }\n const source = this.getRenderedText();\n const expectedFields = dataTable.raw().flat();\n expectedFields.forEach((fieldName: string) => {\n // CreateEventScreen.tsx: Required fields have \" *\" after label: >Label *<\n const escapedName = fieldName.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n const pattern = new RegExp(`>${escapedName}\\\\s*\\\\*<`);\n expect(pattern.test(source), `Field \"${fieldName}\" should be marked as required (with *) in create-event screen`).to.be.true;\n });",
"lineNumber": 48
"sourceCode": "Then('le formulaire contient les champs obligatoires suivants:', async function (this: FestipodWorld, dataTable) {\n // This step is for form screens only (create-event)\n expect(this.currentScreenId, 'This step is for form screens only').to.equal('create-event');\n const source = this.getRenderedText();\n const expectedFields = dataTable.raw().flat();\n expectedFields.forEach((fieldName: string) => {\n // CreateEventScreen.tsx: Required fields have \" *\" after label: >Label *<\n const escapedName = fieldName.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n const pattern = new RegExp(`>${escapedName}\\\\s*\\\\*<`);\n expect(pattern.test(source), `Field \"${fieldName}\" should be marked as required (with *) in create-event screen`).to.be.true;\n });",
"lineNumber": 29
},
{
"pattern": "le champ {string} est facultatif",
"keyword": "Then",
"file": "form.steps.ts",
"sourceCode": "Then('le champ {string} est facultatif', async function (this: FestipodWorld, fieldName: string) {\n const source = this.getRenderedText();\n // Optional fields have label without \" *\": >Label< followed by Input\n const escapedName = fieldName.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n // Check field exists but NOT marked as required\n const existsPattern = new RegExp(`>${escapedName}<`);\n const requiredPattern = new RegExp(`>${escapedName}\\\\s*\\\\*<`);\n expect(existsPattern.test(source), `Field \"${fieldName}\" should exist in screen`).to.be.true;\n expect(requiredPattern.test(source), `Field \"${fieldName}\" should NOT be marked as required`).to.be.false;\n});",
"lineNumber": 65
},
{
"pattern": "le champ {string} affiche {string}",
"keyword": "Then",
"file": "form.steps.ts",
"sourceCode": "Then('le champ {string} affiche {string}', async function (this: FestipodWorld, fieldName: string, expectedValue: string) {\n // Cannot verify displayed field values without browser automation\n this.attach(`CANNOT TEST: Verifying field \"${fieldName}\" displays \"${expectedValue}\" requires browser automation`, 'text/plain');\n return 'pending';\n});",
"lineNumber": 76
"lineNumber": 42
},
{
"pattern": "le champ {string} est présent",
"keyword": "Then",
"file": "form.steps.ts",
"sourceCode": "Then('le champ {string} est présent', async function (this: FestipodWorld, fieldName: string) {\n const source = this.getRenderedText();\n // Check that field label exists in screen source\n const escapedName = fieldName.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n const pattern = new RegExp(`>${escapedName}[^<]*<`);\n const found = pattern.test(source);\n if (!found) {\n this.attach(`NOT FOUND: Field \"${fieldName}\" not present in screen \"${this.currentScreenId}\"`, 'text/plain');\n return 'pending';\n }\n});",
"lineNumber": 82
},
{
"pattern": "une erreur de validation est affichée pour {string}",
"keyword": "Then",
"file": "form.steps.ts",
"sourceCode": "Then('une erreur de validation est affichée pour {string}', async function (this: FestipodWorld, fieldName: string) {\n // Cannot verify validation errors without browser automation\n this.attach(`CANNOT TEST: Validation error for \"${fieldName}\" requires browser automation`, 'text/plain');\n return 'pending';\n});",
"lineNumber": 94
},
{
"pattern": "le formulaire affiche {int} champs",
"keyword": "Then",
"file": "form.steps.ts",
"sourceCode": "Then('le formulaire affiche {int} champs', async function (this: FestipodWorld, count: number) {\n // Cannot count form fields without specific analysis\n this.attach(`CANNOT TEST: Counting ${count} form fields requires more specific screen analysis`, 'text/plain');\n return 'pending';\n});",
"lineNumber": 100
"sourceCode": "Then('le champ {string} est présent', async function (this: FestipodWorld, fieldName: string) {\n const source = this.getRenderedText();\n // Check that field label exists in screen source\n const escapedName = fieldName.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n const pattern = new RegExp(`>${escapedName}[^<]*<`);\n expect(pattern.test(source), `Field \"${fieldName}\" should be present in screen`).to.be.true;\n});",
"lineNumber": 53
},
{
"pattern": "je peux voir la liste des participants",
@@ -241,173 +227,103 @@ export const stepDefinitions: StepDefinitionInfo[] = [
"sourceCode": "Then('je peux voir la section {string}', async function (this: FestipodWorld, sectionName: string) {\n const source = this.getRenderedText();\n // Detect section by text search\n const found = source.includes(sectionName);\n if (!found) {\n this.attach(`Looking for section: \"${sectionName}\"`, 'text/plain');\n this.attach(`Rendered text: ${source.substring(0, 500)}...`, 'text/plain');\n }\n expect(found, `Section \"${sectionName}\" should be visible on screen`).to.be.true;\n});",
"lineNumber": 26
},
{
"pattern": "la page affiche {int} éléments",
"keyword": "Then",
"file": "screen.steps.ts",
"sourceCode": "Then('la page affiche {int} éléments', async function (this: FestipodWorld, count: number) {\n // Cannot count rendered elements without browser automation\n this.attach(`CANNOT TEST: Counting ${count} elements requires browser automation`, 'text/plain');\n return 'pending';\n});",
"lineNumber": 37
},
{
"pattern": "je peux voir mon profil",
"keyword": "Then",
"file": "screen.steps.ts",
"sourceCode": "Then('je peux voir mon profil', async function (this: FestipodWorld) {\n expect(this.currentScreenId).to.equal('profile');\n const source = this.getRenderedText();\n // ProfileScreen.tsx has: <Avatar initials=\"MD\" size=\"lg\" />, <Title>Marie Dupont</Title>, @mariedupont\n expect(/<Avatar[^>]*initials=\"MD\"[^>]*size=\"lg\"/.test(source), 'Profile should have Avatar with initials=\"MD\" and size=\"lg\"').to.be.true;\n expect(/<Title[^>]*>Marie Dupont<\\/Title>/.test(source), 'Profile should have Title \"Marie Dupont\"').to.be.true;\n expect(/@mariedupont/.test(source), 'Profile should have username @mariedupont').to.be.true;\n});",
"lineNumber": 43
"lineNumber": 40
},
{
"pattern": "je peux voir le profil de l'utilisateur",
"keyword": "Then",
"file": "screen.steps.ts",
"sourceCode": "Then('je peux voir le profil de l\\'utilisateur', async function (this: FestipodWorld) {\n expect(this.currentScreenId).to.equal('user-profile');\n const source = this.getRenderedText();\n // UserProfileScreen.tsx has: <Avatar initials=\"JD\" size=\"lg\" />, <Title>Jean Durand</Title>, @jeandurand\n expect(/<Avatar[^>]*initials=\"JD\"[^>]*size=\"lg\"/.test(source), 'User profile should have Avatar with initials=\"JD\" and size=\"lg\"').to.be.true;\n expect(/<Title[^>]*>Jean Durand<\\/Title>/.test(source), 'User profile should have Title \"Jean Durand\"').to.be.true;\n expect(/@jeandurand/.test(source), 'User profile should have username @jeandurand').to.be.true;\n});",
"lineNumber": 52
"lineNumber": 49
},
{
"pattern": "je peux voir la liste des événements",
"keyword": "Then",
"file": "screen.steps.ts",
"sourceCode": "Then('je peux voir la liste des événements', async function (this: FestipodWorld) {\n const source = this.getRenderedText();\n if (this.currentScreenId === 'home') {\n // HomeScreen.tsx has: \"Événements à venir\" text and EventCard components\n expect(/Événements à venir/.test(source), 'Home screen should have \"Événements à venir\" text').to.be.true;\n } else if (this.currentScreenId === 'events') {\n // EventsScreen.tsx has: EventCard components with event data\n expect(/<Card[^>]*onClick/.test(source), 'Events screen should have clickable Card components').to.be.true;\n } else {\n this.attach(`UNEXPECTED SCREEN: \"${this.currentScreenId}\" is not expected to show events list`, 'text/plain');\n return 'pending';\n }\n});",
"lineNumber": 61
"sourceCode": "Then('je peux voir la liste des événements', async function (this: FestipodWorld) {\n const source = this.getRenderedText();\n if (this.currentScreenId === 'home') {\n // HomeScreen.tsx has: \"Événements à venir\" text and EventCard components\n expect(/Événements à venir/.test(source), 'Home screen should have \"Événements à venir\" text').to.be.true;\n } else if (this.currentScreenId === 'events') {\n // EventsScreen.tsx has: EventCard components with event data\n expect(/<Card[^>]*onClick/.test(source), 'Events screen should have clickable Card components').to.be.true;\n } else {\n expect.fail(`Unexpected screen \"${this.currentScreenId}\" - events list should be on home or events screen`);\n }\n});",
"lineNumber": 58
},
{
"pattern": "je peux voir le QR code",
"keyword": "Then",
"file": "screen.steps.ts",
"sourceCode": "Then('je peux voir le QR code', async function (this: FestipodWorld) {\n const source = this.getRenderedText();\n if (this.currentScreenId === 'share-profile') {\n // ShareProfileScreen.tsx has: \"QR Code\" comment and \"Scannez pour me retrouver\" text\n expect(/QR Code/.test(source), 'Share profile should have \"QR Code\" text').to.be.true;\n expect(/Scannez pour me retrouver/.test(source), 'Share profile should have \"Scannez pour me retrouver\" text').to.be.true;\n } else if (this.currentScreenId === 'meeting-points') {\n // MeetingPointsScreen.tsx has: \"Mon QR Code\" text and \"Scannez pour m'ajouter\"\n expect(/Mon QR Code/.test(source), 'Meeting points should have \"Mon QR Code\" text').to.be.true;\n expect(/Scannez pour m'ajouter/.test(source), 'Meeting points should have \"Scannez pour m\\'ajouter\" text').to.be.true;\n } else {\n // QR code is NOT on this screen\n this.attach(`NOT ON THIS SCREEN: QR code is on share-profile or meeting-points, not \"${this.currentScreenId}\"`, 'text/plain');\n return 'pending';\n }\n});",
"lineNumber": 75
"sourceCode": "Then('je peux voir le QR code', async function (this: FestipodWorld) {\n const source = this.getRenderedText();\n if (this.currentScreenId === 'share-profile') {\n // ShareProfileScreen.tsx has: \"QR Code\" comment and \"Scannez pour me retrouver\" text\n expect(/QR Code/.test(source), 'Share profile should have \"QR Code\" text').to.be.true;\n expect(/Scannez pour me retrouver/.test(source), 'Share profile should have \"Scannez pour me retrouver\" text').to.be.true;\n } else if (this.currentScreenId === 'meeting-points') {\n // MeetingPointsScreen.tsx has: \"Mon QR Code\" text and \"Scannez pour m'ajouter\"\n expect(/Mon QR Code/.test(source), 'Meeting points should have \"Mon QR Code\" text').to.be.true;\n expect(/Scannez pour m'ajouter/.test(source), 'Meeting points should have \"Scannez pour m\\'ajouter\" text').to.be.true;\n } else {\n expect.fail(`QR code should be on share-profile or meeting-points, not \"${this.currentScreenId}\"`);\n }\n});",
"lineNumber": 71
},
{
"pattern": "je peux voir le lien de partage",
"keyword": "Then",
"file": "screen.steps.ts",
"sourceCode": "Then('je peux voir le lien de partage', async function (this: FestipodWorld) {\n const source = this.getRenderedText();\n if (this.currentScreenId === 'share-profile') {\n // ShareProfileScreen.tsx has: \"Mon lien de profil\" text and profileLink variable\n expect(/Mon lien de profil/.test(source), 'Share profile should have \"Mon lien de profil\" text').to.be.true;\n expect(/festipod\\.app\\/u\\//.test(source), 'Share profile should have profile link URL').to.be.true;\n } else {\n // Share link is NOT on this screen\n this.attach(`NOT ON THIS SCREEN: Share link is on share-profile, not \"${this.currentScreenId}\"`, 'text/plain');\n return 'pending';\n }\n});",
"lineNumber": 92
},
{
"pattern": "un événement existe avec les données:",
"keyword": "Given",
"file": "screen.steps.ts",
"sourceCode": "Given('un événement existe avec les données:', async function (this: FestipodWorld, dataTable) {\n // Cannot set up test data without backend/database\n const eventData = dataTable.rowsHash();\n this.attach(`CANNOT TEST: Setting up event data requires backend: ${JSON.stringify(eventData)}`, 'text/plain');\n return 'pending';\n});",
"lineNumber": 105
},
{
"pattern": "un utilisateur existe avec les données:",
"keyword": "Given",
"file": "screen.steps.ts",
"sourceCode": "Given('un utilisateur existe avec les données:', async function (this: FestipodWorld, dataTable) {\n // Cannot set up test data without backend/database\n const userData = dataTable.rowsHash();\n this.attach(`CANNOT TEST: Setting up user data requires backend: ${JSON.stringify(userData)}`, 'text/plain');\n return 'pending';\n});",
"lineNumber": 112
"sourceCode": "Then('je peux voir le lien de partage', async function (this: FestipodWorld) {\n expect(this.currentScreenId, 'Share link should be on share-profile screen').to.equal('share-profile');\n const source = this.getRenderedText();\n // ShareProfileScreen.tsx has: \"Mon lien de profil\" text and profileLink variable\n expect(/Mon lien de profil/.test(source), 'Share profile should have \"Mon lien de profil\" text').to.be.true;\n expect(/festipod\\.app\\/u\\//.test(source), 'Share profile should have profile link URL').to.be.true;\n});",
"lineNumber": 86
},
{
"pattern": "je visualise l'événement {string}",
"keyword": "Given",
"file": "screen.steps.ts",
"sourceCode": "Given('je visualise l\\'événement {string}', async function (this: FestipodWorld, eventName: string) {\n this.navigateTo('#/demo/event-detail');\n expect(this.currentScreen, 'Event detail screen should be loaded').to.not.be.null;\n this.attach(`Viewing event: ${eventName}`, 'text/plain');\n});",
"lineNumber": 119
"lineNumber": 97
},
{
"pattern": "je visualise le profil de {string}",
"keyword": "Given",
"file": "screen.steps.ts",
"sourceCode": "Given('je visualise le profil de {string}', async function (this: FestipodWorld, userName: string) {\n this.navigateTo('#/demo/user-profile');\n expect(this.currentScreen, 'User profile screen should be loaded').to.not.be.null;\n this.attach(`Viewing profile: ${userName}`, 'text/plain');\n});",
"lineNumber": 125
"lineNumber": 103
},
{
"pattern": "l'écran affiche les informations de l'événement",
"keyword": "Then",
"file": "screen.steps.ts",
"sourceCode": "Then('l\\'écran affiche les informations de l\\'événement', async function (this: FestipodWorld) {\n expect(this.currentScreenId).to.equal('event-detail');\n const source = this.getRenderedText();\n // EventDetailScreen.tsx has: <Title>, 📅, 🕓, 📍 emojis, and \"À propos\" section\n expect(/<Title[^>]*>[^<]+<\\/Title>/.test(source), 'Event detail should have a Title').to.be.true;\n expect(/📅/.test(source), 'Event detail should have date emoji 📅').to.be.true;\n expect(/🕓/.test(source), 'Event detail should have time emoji 🕓').to.be.true;\n expect(/📍/.test(source), 'Event detail should have location emoji 📍').to.be.true;\n expect(/À propos/.test(source), 'Event detail should have \"À propos\" section').to.be.true;\n});",
"lineNumber": 131
"lineNumber": 109
},
{
"pattern": "l'écran affiche les informations du profil",
"keyword": "Then",
"file": "screen.steps.ts",
"sourceCode": "Then('l\\'écran affiche les informations du profil', async function (this: FestipodWorld) {\n const source = this.getRenderedText();\n if (this.currentScreenId === 'profile') {\n // ProfileScreen.tsx has: <Avatar initials=\"MD\" size=\"lg\" />, <Title>Marie Dupont</Title>, @mariedupont\n expect(/<Avatar[^>]*initials=\"MD\"/.test(source), 'Profile should have Avatar with initials=\"MD\"').to.be.true;\n expect(/<Title[^>]*>Marie Dupont<\\/Title>/.test(source), 'Profile should have Title \"Marie Dupont\"').to.be.true;\n expect(/@mariedupont/.test(source), 'Profile should have username @mariedupont').to.be.true;\n } else if (this.currentScreenId === 'user-profile') {\n // UserProfileScreen.tsx has: <Avatar initials=\"JD\" size=\"lg\" />, <Title>Jean Durand</Title>, @jeandurand\n expect(/<Avatar[^>]*initials=\"JD\"/.test(source), 'User profile should have Avatar with initials=\"JD\"').to.be.true;\n expect(/<Title[^>]*>Jean Durand<\\/Title>/.test(source), 'User profile should have Title \"Jean Durand\"').to.be.true;\n expect(/@jeandurand/.test(source), 'User profile should have username @jeandurand').to.be.true;\n } else {\n expect.fail(`Unexpected screen \"${this.currentScreenId}\" for profile info check`);\n }\n});",
"lineNumber": 142
},
{
"pattern": "je peux ajouter un commentaire",
"keyword": "Then",
"file": "screen.steps.ts",
"sourceCode": "Then('je peux ajouter un commentaire', async function (this: FestipodWorld) {\n // EventDetailScreen.tsx does NOT have comment functionality (no textarea, no \"commentaire\" text)\n // This feature is NOT implemented in the UI\n this.attach('NOT IMPLEMENTED: Comment functionality not in EventDetailScreen.tsx', 'text/plain');\n return 'pending';\n});",
"lineNumber": 159
},
{
"pattern": "je peux ajouter une note",
"keyword": "Then",
"file": "screen.steps.ts",
"sourceCode": "Then('je peux ajouter une note', async function (this: FestipodWorld) {\n // No screen has note functionality implemented\n // This feature is NOT implemented in the UI\n this.attach('NOT IMPLEMENTED: Note functionality not implemented in any screen', 'text/plain');\n return 'pending';\n});",
"lineNumber": 166
},
{
"pattern": "je peux filtrer les événements par période",
"keyword": "Then",
"file": "screen.steps.ts",
"sourceCode": "Then('je peux filtrer les événements par période', async function (this: FestipodWorld) {\n // EventsScreen.tsx has filter badges (Tous, Cette semaine, Proches, Amis) but NOT period filter (mois/trimestre/année)\n // This feature is NOT implemented in the UI\n this.attach('NOT IMPLEMENTED: Period filter (mois/trimestre/année) not in EventsScreen.tsx', 'text/plain');\n return 'pending';\n});",
"lineNumber": 173
},
{
"pattern": "je peux modifier un commentaire",
"keyword": "Then",
"file": "screen.steps.ts",
"sourceCode": "Then('je peux modifier un commentaire', async function (this: FestipodWorld) {\n // No comment edit functionality exists in any screen\n // This feature is NOT implemented in the UI\n this.attach('NOT IMPLEMENTED: Comment edit functionality not implemented', 'text/plain');\n return 'pending';\n});",
"lineNumber": 180
},
{
"pattern": "je peux supprimer un commentaire",
"keyword": "Then",
"file": "screen.steps.ts",
"sourceCode": "Then('je peux supprimer un commentaire', async function (this: FestipodWorld) {\n // No comment delete functionality exists in any screen\n // This feature is NOT implemented in the UI\n this.attach('NOT IMPLEMENTED: Comment delete functionality not implemented', 'text/plain');\n return 'pending';\n});",
"lineNumber": 187
"lineNumber": 120
},
{
"pattern": "je peux m'inscrire à l'événement",
"keyword": "Then",
"file": "screen.steps.ts",
"sourceCode": "Then('je peux m\\'inscrire à l\\'événement', async function (this: FestipodWorld) {\n expect(this.currentScreenId).to.equal('event-detail');\n const source = this.getRenderedText();\n // EventDetailScreen.tsx line 49: {isJoined ? '✓ Inscrit' : 'Participer'}\n // The button shows \"Participer\" when not joined\n const hasParticiperButton = /isJoined \\? '✓ Inscrit' : 'Participer'/.test(source);\n expect(hasParticiperButton, 'Event detail should have Participer/Inscrit toggle button').to.be.true;\n});",
"lineNumber": 194
"lineNumber": 140
},
{
"pattern": "je peux me désinscrire de l'événement",
"keyword": "Then",
"file": "screen.steps.ts",
"sourceCode": "Then('je peux me désinscrire de l\\'événement', async function (this: FestipodWorld) {\n expect(this.currentScreenId).to.equal('event-detail');\n const source = this.getRenderedText();\n // EventDetailScreen.tsx line 49: {isJoined ? '✓ Inscrit' : 'Participer'}\n // Same button toggles - clicking \"✓ Inscrit\" will unregister\n const hasInscritButton = /isJoined \\? '✓ Inscrit' : 'Participer'/.test(source);\n expect(hasInscritButton, 'Event detail should have Participer/Inscrit toggle button (click to unregister)').to.be.true;\n});",
"lineNumber": 203
"lineNumber": 149
},
{
"pattern": "je peux contacter l'utilisateur",
"keyword": "Then",
"file": "screen.steps.ts",
"sourceCode": "Then('je peux contacter l\\'utilisateur', async function (this: FestipodWorld) {\n expect(this.currentScreenId).to.equal('user-profile');\n const source = this.getRenderedText();\n // UserProfileScreen.tsx line 44: <Button>Contacter</Button>\n const hasContactButton = /<Button>Contacter<\\/Button>/.test(source);\n expect(hasContactButton, 'User profile should have \"Contacter\" button').to.be.true;\n});",
"lineNumber": 212
"lineNumber": 158
},
{
"pattern": "je peux voir les événements auxquels l'utilisateur a participé",
"keyword": "Then",
"file": "screen.steps.ts",
"sourceCode": "Then('je peux voir les événements auxquels l\\'utilisateur a participé', async function (this: FestipodWorld) {\n expect(this.currentScreenId).to.equal('user-profile');\n const source = this.getRenderedText();\n // UserProfileScreen.tsx line 52: \"Événements en commun\" section with pastEvents\n expect(/Événements en commun/.test(source), 'User profile should have \"Événements en commun\" section').to.be.true;\n expect(/pastEvents/.test(source), 'User profile should display pastEvents data').to.be.true;\n});",
"lineNumber": 220
"lineNumber": 166
},
{
"pattern": "je peux configurer mes notifications",
"keyword": "Then",
"file": "screen.steps.ts",
"sourceCode": "Then('je peux configurer mes notifications', async function (this: FestipodWorld) {\n expect(this.currentScreenId).to.equal('settings');\n const source = this.getRenderedText();\n // SettingsScreen.tsx line 25: <Text>Notifications</Text> with Toggle\n expect(/>Notifications</.test(source), 'Settings should have \"Notifications\" text').to.be.true;\n expect(/<Toggle[^>]*checked=\\{notifications\\}/.test(source), 'Settings should have Toggle for notifications').to.be.true;\n});",
"lineNumber": 228
},
{
"pattern": "je peux définir mon rayon de notification",
"keyword": "Then",
"file": "screen.steps.ts",
"sourceCode": "Then('je peux définir mon rayon de notification', async function (this: FestipodWorld) {\n // SettingsScreen.tsx has \"Localisation\" toggle but NOT \"rayon\" or \"km\" setting\n // This feature is NOT implemented in the UI\n this.attach('NOT IMPLEMENTED: Radius setting (rayon/km) is not in SettingsScreen.tsx', 'text/plain');\n return 'pending';\n});",
"lineNumber": 236
},
{
"pattern": "je peux définir mes thématiques d'intérêt",
"keyword": "Then",
"file": "screen.steps.ts",
"sourceCode": "Then('je peux définir mes thématiques d\\'intérêt', async function (this: FestipodWorld) {\n // SettingsScreen.tsx does NOT have thematic/interest settings\n // This feature is NOT implemented in the UI\n this.attach('NOT IMPLEMENTED: Thematic/interest settings not in SettingsScreen.tsx', 'text/plain');\n return 'pending';\n});",
"lineNumber": 243
"lineNumber": 174
}
];
+186 -114
View File
@@ -15,11 +15,11 @@ interface RawFeatureTestStatus {
const rawResults: RawFeatureTestStatus[] = [
{
"featureId": "us-13",
"totalScenarios": 5,
"totalScenarios": 7,
"passed": 4,
"failed": 0,
"skipped": 1,
"lastRun": "2026-01-19T09:27:22.847Z",
"skipped": 3,
"lastRun": "2026-01-19T11:47:58.183Z",
"scenarios": [
{
"name": "Accéder à la création d'événement",
@@ -29,10 +29,6 @@ const rawResults: RawFeatureTestStatus[] = [
"name": "Vérifier les champs obligatoires du formulaire",
"status": "passed"
},
{
"name": "Remplir le formulaire de création d'événement",
"status": "skipped"
},
{
"name": "Vérifier la présence du bouton de création",
"status": "passed"
@@ -40,16 +36,28 @@ const rawResults: RawFeatureTestStatus[] = [
{
"name": "Pouvoir annuler la création d'événement",
"status": "passed"
},
{
"name": "Modifier un événement",
"status": "skipped"
},
{
"name": "Supprimer un événement",
"status": "skipped"
},
{
"name": "Retirer une organisation (personne ou structure)",
"status": "skipped"
}
]
},
{
"featureId": "us-3",
"totalScenarios": 4,
"totalScenarios": 3,
"passed": 3,
"failed": 0,
"skipped": 1,
"lastRun": "2026-01-19T09:27:22.847Z",
"skipped": 0,
"lastRun": "2026-01-19T11:47:58.183Z",
"scenarios": [
{
"name": "Accéder aux détails d'un événement terminé",
@@ -62,20 +70,16 @@ const rawResults: RawFeatureTestStatus[] = [
{
"name": "Voir la liste des participants",
"status": "passed"
},
{
"name": "Vérifier les données affichées",
"status": "skipped"
}
]
},
{
"featureId": "us-5",
"totalScenarios": 4,
"totalScenarios": 5,
"passed": 0,
"failed": 0,
"skipped": 4,
"lastRun": "2026-01-19T09:27:22.847Z",
"skipped": 5,
"lastRun": "2026-01-19T11:47:58.183Z",
"scenarios": [
{
"name": "Voir les commentaires existants",
@@ -92,16 +96,20 @@ const rawResults: RawFeatureTestStatus[] = [
{
"name": "Supprimer un commentaire",
"status": "skipped"
},
{
"name": "Enregistrer les interactions avec des individus (Date/Heure/Lieu)",
"status": "skipped"
}
]
},
{
"featureId": "us-7",
"totalScenarios": 5,
"totalScenarios": 6,
"passed": 2,
"failed": 0,
"skipped": 3,
"lastRun": "2026-01-19T09:27:22.848Z",
"skipped": 4,
"lastRun": "2026-01-19T11:47:58.183Z",
"scenarios": [
{
"name": "Consulter un événement avant inscription",
@@ -122,16 +130,20 @@ const rawResults: RawFeatureTestStatus[] = [
{
"name": "Vérifier les données de l'écran",
"status": "skipped"
},
{
"name": "Rechercher dans une base existante (Mobilizon)",
"status": "skipped"
}
]
},
{
"featureId": "us-8",
"totalScenarios": 4,
"totalScenarios": 8,
"passed": 0,
"failed": 0,
"skipped": 4,
"lastRun": "2026-01-19T09:27:22.848Z",
"skipped": 8,
"lastRun": "2026-01-19T11:47:58.183Z",
"scenarios": [
{
"name": "Consulter un macro-événement",
@@ -148,16 +160,32 @@ const rawResults: RawFeatureTestStatus[] = [
{
"name": "Voir la consolidation des participants",
"status": "skipped"
},
{
"name": "Créer un macro-événement",
"status": "skipped"
},
{
"name": "Voir la consolidation des commentaires/liens/ressources",
"status": "skipped"
},
{
"name": "Rattacher à une thématique particulière",
"status": "skipped"
},
{
"name": "Gérer un événement répété sur plusieurs périodes",
"status": "skipped"
}
]
},
{
"featureId": "us-16",
"totalScenarios": 5,
"passed": 1,
"passed": 5,
"failed": 0,
"skipped": 4,
"lastRun": "2026-01-19T09:27:22.848Z",
"skipped": 0,
"lastRun": "2026-01-19T11:47:58.183Z",
"scenarios": [
{
"name": "Accéder aux points de rencontre",
@@ -165,19 +193,19 @@ const rawResults: RawFeatureTestStatus[] = [
},
{
"name": "Créer un point de rencontre",
"status": "skipped"
"status": "passed"
},
{
"name": "Définir le lieu de rencontre",
"status": "skipped"
"status": "passed"
},
{
"name": "Définir l'heure de rencontre",
"status": "skipped"
"status": "passed"
},
{
"name": "Échanger des liens de contact",
"status": "skipped"
"status": "passed"
}
]
},
@@ -187,7 +215,7 @@ const rawResults: RawFeatureTestStatus[] = [
"passed": 0,
"failed": 0,
"skipped": 5,
"lastRun": "2026-01-19T09:27:22.848Z",
"lastRun": "2026-01-19T11:47:58.183Z",
"scenarios": [
{
"name": "Partager un événement auquel je participe",
@@ -217,7 +245,7 @@ const rawResults: RawFeatureTestStatus[] = [
"passed": 1,
"failed": 0,
"skipped": 3,
"lastRun": "2026-01-19T09:27:22.848Z",
"lastRun": "2026-01-19T11:47:58.183Z",
"scenarios": [
{
"name": "Configurer les notifications de nouveaux participants",
@@ -240,10 +268,10 @@ const rawResults: RawFeatureTestStatus[] = [
{
"featureId": "us-19",
"totalScenarios": 5,
"passed": 1,
"passed": 3,
"failed": 0,
"skipped": 4,
"lastRun": "2026-01-19T09:27:22.848Z",
"skipped": 2,
"lastRun": "2026-01-19T11:47:58.183Z",
"scenarios": [
{
"name": "Voir les événements à venir sur l'accueil",
@@ -259,11 +287,11 @@ const rawResults: RawFeatureTestStatus[] = [
},
{
"name": "Voir mes inscriptions",
"status": "skipped"
"status": "passed"
},
{
"name": "Vérifier les données de l'accueil",
"status": "skipped"
"status": "passed"
}
]
},
@@ -273,7 +301,7 @@ const rawResults: RawFeatureTestStatus[] = [
"passed": 4,
"failed": 0,
"skipped": 1,
"lastRun": "2026-01-19T09:27:22.848Z",
"lastRun": "2026-01-19T11:47:58.183Z",
"scenarios": [
{
"name": "Accéder au profil d'un participant",
@@ -299,11 +327,11 @@ const rawResults: RawFeatureTestStatus[] = [
},
{
"featureId": "us-12",
"totalScenarios": 6,
"totalScenarios": 7,
"passed": 2,
"failed": 0,
"skipped": 4,
"lastRun": "2026-01-19T09:27:22.848Z",
"skipped": 5,
"lastRun": "2026-01-19T11:47:58.183Z",
"scenarios": [
{
"name": "Accéder à la liste des événements depuis le profil",
@@ -328,42 +356,50 @@ const rawResults: RawFeatureTestStatus[] = [
{
"name": "Vérifier les données de l'écran profil",
"status": "skipped"
}
]
},
{
"featureId": "us-15",
"totalScenarios": 4,
"passed": 3,
"failed": 0,
"skipped": 1,
"lastRun": "2026-01-19T09:27:22.848Z",
"scenarios": [
{
"name": "Accéder à la liste des inscrits",
"status": "passed"
},
{
"name": "Voir la liste triée",
"status": "passed"
},
{
"name": "Cliquer sur un inscrit pour voir son profil",
"status": "passed"
},
{
"name": "Vérifier les données de l'écran",
"name": "Voir la vue carte des événements",
"status": "skipped"
}
]
},
{
"featureId": "us-20",
"featureId": "us-15",
"totalScenarios": 5,
"passed": 3,
"failed": 0,
"skipped": 2,
"lastRun": "2026-01-19T09:27:22.848Z",
"lastRun": "2026-01-19T11:47:58.183Z",
"scenarios": [
{
"name": "Accéder à la liste des inscrits d'un événement",
"status": "passed"
},
{
"name": "Accéder à la liste des inscrits d'un atelier",
"status": "skipped"
},
{
"name": "Voir la liste des participants d'un événement",
"status": "passed"
},
{
"name": "Voir la liste des participants d'un atelier",
"status": "skipped"
},
{
"name": "Cliquer sur un inscrit pour voir son profil",
"status": "passed"
}
]
},
{
"featureId": "us-20",
"totalScenarios": 6,
"passed": 5,
"failed": 0,
"skipped": 1,
"lastRun": "2026-01-19T11:47:58.184Z",
"scenarios": [
{
"name": "Accéder à mon profil",
@@ -371,7 +407,7 @@ const rawResults: RawFeatureTestStatus[] = [
},
{
"name": "Voir mon réseau",
"status": "skipped"
"status": "passed"
},
{
"name": "Voir un profil de mon réseau",
@@ -383,6 +419,10 @@ const rawResults: RawFeatureTestStatus[] = [
},
{
"name": "Vérifier les données du profil",
"status": "passed"
},
{
"name": "Voir les profils publiques",
"status": "skipped"
}
]
@@ -393,7 +433,7 @@ const rawResults: RawFeatureTestStatus[] = [
"passed": 2,
"failed": 0,
"skipped": 3,
"lastRun": "2026-01-19T09:27:22.848Z",
"lastRun": "2026-01-19T11:47:58.184Z",
"scenarios": [
{
"name": "Accéder aux paramètres de profil",
@@ -419,37 +459,41 @@ const rawResults: RawFeatureTestStatus[] = [
},
{
"featureId": "us-22",
"totalScenarios": 4,
"passed": 0,
"totalScenarios": 5,
"passed": 5,
"failed": 0,
"skipped": 4,
"lastRun": "2026-01-19T09:27:22.848Z",
"skipped": 0,
"lastRun": "2026-01-19T11:47:58.184Z",
"scenarios": [
{
"name": "Accéder au partage de profil",
"status": "skipped"
"status": "passed"
},
{
"name": "Naviguer vers le partage de profil",
"status": "passed"
},
{
"name": "Voir le QR code de parrainage",
"status": "skipped"
"status": "passed"
},
{
"name": "Voir le lien de parrainage",
"status": "skipped"
"status": "passed"
},
{
"name": "Voir les statistiques de parrainage",
"status": "skipped"
"status": "passed"
}
]
},
{
"featureId": "us-23",
"totalScenarios": 5,
"passed": 2,
"passed": 5,
"failed": 0,
"skipped": 3,
"lastRun": "2026-01-19T09:27:22.848Z",
"skipped": 0,
"lastRun": "2026-01-19T11:47:58.184Z",
"scenarios": [
{
"name": "Accéder au partage depuis le profil",
@@ -457,11 +501,11 @@ const rawResults: RawFeatureTestStatus[] = [
},
{
"name": "Voir le QR code",
"status": "skipped"
"status": "passed"
},
{
"name": "Voir le lien de partage",
"status": "skipped"
"status": "passed"
},
{
"name": "Accéder à l'écran de partage dédié",
@@ -469,7 +513,7 @@ const rawResults: RawFeatureTestStatus[] = [
},
{
"name": "Vérifier les données du profil",
"status": "skipped"
"status": "passed"
}
]
},
@@ -479,7 +523,7 @@ const rawResults: RawFeatureTestStatus[] = [
"passed": 2,
"failed": 0,
"skipped": 1,
"lastRun": "2026-01-19T09:27:22.848Z",
"lastRun": "2026-01-19T11:47:58.184Z",
"scenarios": [
{
"name": "Accéder aux paramètres de notification",
@@ -501,7 +545,7 @@ const rawResults: RawFeatureTestStatus[] = [
"passed": 1,
"failed": 0,
"skipped": 2,
"lastRun": "2026-01-19T09:27:22.848Z",
"lastRun": "2026-01-19T11:47:58.184Z",
"scenarios": [
{
"name": "Accéder aux paramètres de notification",
@@ -520,14 +564,14 @@ const rawResults: RawFeatureTestStatus[] = [
{
"featureId": "us-26",
"totalScenarios": 4,
"passed": 2,
"passed": 3,
"failed": 0,
"skipped": 2,
"lastRun": "2026-01-19T09:27:22.848Z",
"skipped": 1,
"lastRun": "2026-01-19T11:47:58.184Z",
"scenarios": [
{
"name": "Accéder à la création d'événement",
"status": "skipped"
"status": "passed"
},
{
"name": "Définir le rayon d'intérêt",
@@ -545,15 +589,15 @@ const rawResults: RawFeatureTestStatus[] = [
},
{
"featureId": "us-9",
"totalScenarios": 4,
"passed": 2,
"totalScenarios": 5,
"passed": 4,
"failed": 0,
"skipped": 2,
"lastRun": "2026-01-19T09:27:22.848Z",
"skipped": 1,
"lastRun": "2026-01-19T11:47:58.184Z",
"scenarios": [
{
"name": "Accéder au profil pour voir la photo",
"status": "skipped"
"status": "passed"
},
{
"name": "Naviguer vers le profil depuis la liste des participants",
@@ -565,17 +609,21 @@ const rawResults: RawFeatureTestStatus[] = [
},
{
"name": "Vérifier les champs de données du profil",
"status": "passed"
},
{
"name": "Ajouter une photo personnelle sur une fiche existante",
"status": "skipped"
}
]
},
{
"featureId": "us-1",
"totalScenarios": 3,
"totalScenarios": 5,
"passed": 0,
"failed": 0,
"skipped": 3,
"lastRun": "2026-01-19T09:27:22.848Z",
"skipped": 5,
"lastRun": "2026-01-19T11:47:58.184Z",
"scenarios": [
{
"name": "Accéder aux détails d'un événement terminé",
@@ -588,6 +636,14 @@ const rawResults: RawFeatureTestStatus[] = [
{
"name": "Consulter les ressources d'un atelier",
"status": "skipped"
},
{
"name": "Consulter le programme détaillé par journée/heure",
"status": "skipped"
},
{
"name": "Accéder à la zone de partage collective",
"status": "skipped"
}
]
},
@@ -597,7 +653,7 @@ const rawResults: RawFeatureTestStatus[] = [
"passed": 0,
"failed": 0,
"skipped": 3,
"lastRun": "2026-01-19T09:27:22.848Z",
"lastRun": "2026-01-19T11:47:58.184Z",
"scenarios": [
{
"name": "Accéder au bilan consolidé",
@@ -615,11 +671,11 @@ const rawResults: RawFeatureTestStatus[] = [
},
{
"featureId": "us-14",
"totalScenarios": 5,
"passed": 1,
"totalScenarios": 7,
"passed": 0,
"failed": 0,
"skipped": 4,
"lastRun": "2026-01-19T09:27:22.848Z",
"skipped": 7,
"lastRun": "2026-01-19T11:47:58.184Z",
"scenarios": [
{
"name": "Accéder à la création d'atelier",
@@ -627,7 +683,7 @@ const rawResults: RawFeatureTestStatus[] = [
},
{
"name": "Vérifier les champs obligatoires pour créer un atelier",
"status": "passed"
"status": "skipped"
},
{
"name": "Créer un atelier",
@@ -640,16 +696,24 @@ const rawResults: RawFeatureTestStatus[] = [
{
"name": "Supprimer un atelier",
"status": "skipped"
},
{
"name": "Sélectionner mon événement parent",
"status": "skipped"
},
{
"name": "Définir les horaires de fin de l'atelier",
"status": "skipped"
}
]
},
{
"featureId": "us-2",
"totalScenarios": 4,
"totalScenarios": 5,
"passed": 0,
"failed": 0,
"skipped": 4,
"lastRun": "2026-01-19T09:27:22.848Z",
"skipped": 5,
"lastRun": "2026-01-19T11:47:58.184Z",
"scenarios": [
{
"name": "Accéder à la zone de notes personnelles",
@@ -666,16 +730,20 @@ const rawResults: RawFeatureTestStatus[] = [
{
"name": "Ajouter un lien/ressource",
"status": "skipped"
},
{
"name": "Consulter le programme détaillé des ateliers par journée/heure",
"status": "skipped"
}
]
},
{
"featureId": "us-4",
"totalScenarios": 4,
"totalScenarios": 5,
"passed": 0,
"failed": 0,
"skipped": 4,
"lastRun": "2026-01-19T09:27:22.848Z",
"skipped": 5,
"lastRun": "2026-01-19T11:47:58.184Z",
"scenarios": [
{
"name": "Voir les commentaires existants d'un atelier",
@@ -692,24 +760,28 @@ const rawResults: RawFeatureTestStatus[] = [
{
"name": "Supprimer un commentaire",
"status": "skipped"
},
{
"name": "Accéder à l'icône ajouter un commentaire",
"status": "skipped"
}
]
},
{
"featureId": "us-6",
"totalScenarios": 4,
"passed": 2,
"passed": 0,
"failed": 0,
"skipped": 2,
"lastRun": "2026-01-19T09:27:22.848Z",
"skipped": 4,
"lastRun": "2026-01-19T11:47:58.184Z",
"scenarios": [
{
"name": "Rechercher un événement public existant",
"status": "passed"
"name": "Voir les ateliers d'un événement",
"status": "skipped"
},
{
"name": "Voir les personnes pré-inscrites à un atelier",
"status": "passed"
"status": "skipped"
},
{
"name": "S'inscrire à un atelier",