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
+9 -3
View File
@@ -23,9 +23,6 @@ Fonctionnalité: US-13 Créer/Modifier/Supprimer un événement
| Lieu |
| Thématique |
Scénario: Remplir le formulaire de création d'événement
* Scénario non implémenté
Scénario: Vérifier la présence du bouton de création
Étant donné que je suis sur la page "créer un événement"
Alors l'écran contient une section "Créer l'événement"
@@ -33,3 +30,12 @@ Fonctionnalité: US-13 Créer/Modifier/Supprimer un événement
Scénario: Pouvoir annuler la création d'événement
Étant donné que je suis sur la page "créer un événement"
Alors je peux annuler et revenir à l'écran précédent
Scénario: Modifier un événement
* Scénario non implémenté
Scénario: Supprimer un événement
* Scénario non implémenté
Scénario: Retirer une organisation (personne ou structure)
* Scénario non implémenté
@@ -20,6 +20,3 @@ Fonctionnalité: US-3 Visualiser un événement terminé
Scénario: Voir la liste des participants
Étant donné que je suis sur la page "détail événement"
Alors je peux voir la liste des participants
Scénario: Vérifier les données affichées
* Scénario non implémenté
@@ -20,3 +20,6 @@ Fonctionnalité: US-5 Ajouter/modifier/supprimer un commentaire à un événemen
Scénario: Supprimer un commentaire
* Scénario non implémenté
Scénario: Enregistrer les interactions avec des individus (Date/Heure/Lieu)
* Scénario non implémenté
@@ -25,3 +25,6 @@ Fonctionnalité: US-7 M'inscrire/me désinscrire à un événement
Scénario: Vérifier les données de l'écran
* Scénario non implémenté
Scénario: Rechercher dans une base existante (Mobilizon)
* Scénario non implémenté
@@ -20,3 +20,15 @@ Fonctionnalité: US-8 Consulter et m'inscrire à un macro-événement
Scénario: Voir la consolidation des participants
* Scénario non implémenté
Scénario: Créer un macro-événement
* Scénario non implémenté
Scénario: Voir la consolidation des commentaires/liens/ressources
* Scénario non implémenté
Scénario: Rattacher à une thématique particulière
* Scénario non implémenté
Scénario: Gérer un événement répété sur plusieurs périodes
* Scénario non implémenté
+14 -4
View File
@@ -15,13 +15,23 @@ Fonctionnalité: US-16 Indiquer un ou plusieurs points de rencontre
Alors je vois l'écran "meeting-points"
Scénario: Créer un point de rencontre
* Scénario non implémenté
Étant donné que je suis sur la page "points de rencontre"
Alors l'écran contient un bouton "Créer le point de rencontre"
Scénario: Définir le lieu de rencontre
* Scénario non implémenté
Étant donné que je suis sur la page "points de rencontre"
Alors l'écran contient une section "Proposer un point de rencontre"
Et l'écran contient un champ "Lieu"
Scénario: Définir l'heure de rencontre
* Scénario non implémenté
Étant donné que je suis sur la page "points de rencontre"
Alors l'écran contient un bouton "30 min avant"
Et l'écran contient un bouton "1h avant"
Et l'écran contient un bouton "Personnalisé"
Scénario: Échanger des liens de contact
* Scénario non implémenté
Étant donné que je suis sur la page "points de rencontre"
Alors l'écran contient une section "Échanger vos contacts"
Et l'écran contient un texte "Mon QR Code"
Et l'écran contient un bouton "Scanner un QR"
Et l'écran contient un bouton "Partager mon lien"
+5 -2
View File
@@ -22,7 +22,10 @@ Fonctionnalité: US-19 Recevoir un récapitulatif des prochaines rencontres
* Scénario non implémenté
Scénario: Voir mes inscriptions
* Scénario non implémenté
Étant donné que je suis sur la page "mon profil"
Alors l'écran contient une section "Mes événements à venir"
Scénario: Vérifier les données de l'accueil
* Scénario non implémenté
Étant donné que je suis sur la page "accueil"
Alors l'écran contient un texte "Barbecue d'été"
Et l'écran contient un texte "Soirée jeux de société"
+8 -50
View File
@@ -1,4 +1,4 @@
import { Given, When, Then } from '@cucumber/cucumber';
import { Given, Then } from '@cucumber/cucumber';
import { expect } from 'chai';
import type { FestipodWorld } from '../support/world';
@@ -13,31 +13,12 @@ Given('le formulaire de création est vide', async function (this: FestipodWorld
});
});
When('je remplis le champ {string} avec {string}', async function (this: FestipodWorld, fieldName: string, value: string) {
// Cannot fill form fields without browser automation
this.attach(`CANNOT TEST: Filling field "${fieldName}" with "${value}" requires browser automation`, 'text/plain');
return 'pending';
});
When('je laisse le champ {string} vide', async function (this: FestipodWorld, fieldName: string) {
// Cannot manipulate form fields without browser automation
this.attach(`CANNOT TEST: Leaving field "${fieldName}" empty requires browser automation`, 'text/plain');
return 'pending';
});
When('je soumets le formulaire', async function (this: FestipodWorld) {
// Cannot submit forms without browser automation
this.attach('CANNOT TEST: Form submission requires browser automation', 'text/plain');
return 'pending';
});
// Steps removed: Form interaction steps (je remplis le champ, je laisse le champ vide, je soumets le formulaire)
// require browser automation. Scenarios needing these use "* Scénario non implémenté" placeholder.
Then('le formulaire contient le champ obligatoire {string}', async function (this: FestipodWorld, fieldName: string) {
// This step is for form screens only (create-event)
// For display screens, use different steps
if (this.currentScreenId !== 'create-event') {
this.attach(`WRONG STEP: "le formulaire contient le champ obligatoire" is for forms. Screen "${this.currentScreenId}" is not a form.`, 'text/plain');
return 'pending';
}
expect(this.currentScreenId, 'This step is for form screens only').to.equal('create-event');
const source = this.getRenderedText();
// CreateEventScreen.tsx: Required fields have " *" after label: >Label *<
const escapedName = fieldName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
@@ -47,11 +28,7 @@ Then('le formulaire contient le champ obligatoire {string}', async function (thi
Then('le formulaire contient les champs obligatoires suivants:', async function (this: FestipodWorld, dataTable) {
// This step is for form screens only (create-event)
// For display screens, use different steps
if (this.currentScreenId !== 'create-event') {
this.attach(`WRONG STEP: "le formulaire contient les champs obligatoires" is for forms. Screen "${this.currentScreenId}" is not a form.`, 'text/plain');
return 'pending';
}
expect(this.currentScreenId, 'This step is for form screens only').to.equal('create-event');
const source = this.getRenderedText();
const expectedFields = dataTable.raw().flat();
expectedFields.forEach((fieldName: string) => {
@@ -73,32 +50,13 @@ Then('le champ {string} est facultatif', async function (this: FestipodWorld, fi
expect(requiredPattern.test(source), `Field "${fieldName}" should NOT be marked as required`).to.be.false;
});
Then('le champ {string} affiche {string}', async function (this: FestipodWorld, fieldName: string, expectedValue: string) {
// Cannot verify displayed field values without browser automation
this.attach(`CANNOT TEST: Verifying field "${fieldName}" displays "${expectedValue}" requires browser automation`, 'text/plain');
return 'pending';
});
Then('le champ {string} est présent', async function (this: FestipodWorld, fieldName: string) {
const source = this.getRenderedText();
// Check that field label exists in screen source
const escapedName = fieldName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
const pattern = new RegExp(`>${escapedName}[^<]*<`);
const found = pattern.test(source);
if (!found) {
this.attach(`NOT FOUND: Field "${fieldName}" not present in screen "${this.currentScreenId}"`, 'text/plain');
return 'pending';
}
expect(pattern.test(source), `Field "${fieldName}" should be present in screen`).to.be.true;
});
Then('une erreur de validation est affichée pour {string}', async function (this: FestipodWorld, fieldName: string) {
// Cannot verify validation errors without browser automation
this.attach(`CANNOT TEST: Validation error for "${fieldName}" requires browser automation`, 'text/plain');
return 'pending';
});
Then('le formulaire affiche {int} champs', async function (this: FestipodWorld, count: number) {
// Cannot count form fields without specific analysis
this.attach(`CANNOT TEST: Counting ${count} form fields requires more specific screen analysis`, 'text/plain');
return 'pending';
});
// Steps removed: Form display/validation steps (le champ affiche, erreur de validation, formulaire affiche N champs)
// require browser automation. Scenarios needing these use "* Scénario non implémenté" placeholder.
+25 -30
View File
@@ -27,6 +27,7 @@ const screenNameMap: Record<string, string> = {
'réglages': 'settings',
'points de rencontre': 'meeting-points',
'partage de profil': 'share-profile',
'partage profil': 'share-profile',
};
function resolveScreenId(pageName: string): string {
@@ -61,11 +62,7 @@ When('je clique sur {string}', async function (this: FestipodWorld, elementName:
// Check that a clickable element with this text exists (onClick handler + text content)
const escapedName = elementName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
const pattern = new RegExp(`onClick[^>]*>[^<]*${escapedName}`, 'i');
const found = pattern.test(source);
if (!found) {
this.attach(`MISSING: Clickable element "${elementName}" not found in screen "${this.currentScreenId}"`, 'text/plain');
return 'pending';
}
expect(pattern.test(source), `Clickable element "${elementName}" should exist in screen "${this.currentScreenId}"`).to.be.true;
});
When('je sélectionne {string}', async function (this: FestipodWorld, elementName: string) {
@@ -73,11 +70,7 @@ When('je sélectionne {string}', async function (this: FestipodWorld, elementNam
// Check that a selectable element with this text exists
const escapedName = elementName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
const pattern = new RegExp(`onClick[^>]*>[^<]*${escapedName}`, 'i');
const found = pattern.test(source);
if (!found) {
this.attach(`MISSING: Selectable element "${elementName}" not found in screen "${this.currentScreenId}"`, 'text/plain');
return 'pending';
}
expect(pattern.test(source), `Selectable element "${elementName}" should exist in screen "${this.currentScreenId}"`).to.be.true;
});
When('je clique sur le bouton {string}', async function (this: FestipodWorld, buttonName: string) {
@@ -85,11 +78,7 @@ When('je clique sur le bouton {string}', async function (this: FestipodWorld, bu
// Check that a Button component with this label exists
const escapedName = buttonName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
const pattern = new RegExp(`<Button[^>]*>[^<]*${escapedName}[^<]*</Button>`, 'i');
const found = pattern.test(source);
if (!found) {
this.attach(`MISSING: Button "${buttonName}" not found in screen "${this.currentScreenId}"`, 'text/plain');
return 'pending';
}
expect(pattern.test(source), `Button "${buttonName}" should exist in screen "${this.currentScreenId}"`).to.be.true;
});
When('je clique sur un participant', async function (this: FestipodWorld) {
@@ -116,11 +105,7 @@ Then('je reste sur la page {string}', async function (this: FestipodWorld, pageN
});
Then('l\'écran contient une section {string}', async function (this: FestipodWorld, sectionName: string) {
const found = this.hasText(sectionName);
if (!found) {
this.attach(`MISSING SECTION: "${sectionName}" not found in screen "${this.currentScreenId}"`, 'text/plain');
return 'pending';
}
expect(this.hasText(sectionName), `Section "${sectionName}" should be present in screen "${this.currentScreenId}"`).to.be.true;
});
Then('je peux annuler et revenir à l\'écran précédent', async function (this: FestipodWorld) {
@@ -136,11 +121,7 @@ Then('je peux naviguer vers {string}', async function (this: FestipodWorld, page
const source = this.getRenderedText();
// Check that a navigation link to this screen exists: navigate('screenId') or onClick={() => navigate('screenId')}
const pattern = new RegExp(`navigate\\s*\\(\\s*['"]${screenId}['"]\\s*\\)`);
const found = pattern.test(source);
if (!found) {
this.attach(`MISSING: Navigation to "${screenId}" not found in screen "${this.currentScreenId}"`, 'text/plain');
return 'pending';
}
expect(pattern.test(source), `Navigation to "${screenId}" should exist in screen "${this.currentScreenId}"`).to.be.true;
});
Then('la navigation affiche {string} comme actif', async function (this: FestipodWorld, menuItem: string) {
@@ -149,9 +130,23 @@ Then('la navigation affiche {string} comme actif', async function (this: Festipo
// Pattern: { icon: '...', label: 'menuItem', active: true }
const escapedItem = menuItem.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
const pattern = new RegExp(`label:\\s*['"]${escapedItem}['"][^}]*active:\\s*true`, 'i');
const found = pattern.test(source);
if (!found) {
this.attach(`MISSING: Menu item "${menuItem}" is not active in NavBar of screen "${this.currentScreenId}"`, 'text/plain');
return 'pending';
}
expect(pattern.test(source), `Menu item "${menuItem}" should be active in NavBar of screen "${this.currentScreenId}"`).to.be.true;
});
Then('l\'écran contient un bouton {string}', async function (this: FestipodWorld, buttonText: string) {
expect(this.hasText(buttonText), `Button "${buttonText}" should be present in screen "${this.currentScreenId}"`).to.be.true;
});
Then('l\'écran contient un champ {string}', async function (this: FestipodWorld, fieldLabel: string) {
expect(this.hasText(fieldLabel), `Field "${fieldLabel}" should be present in screen "${this.currentScreenId}"`).to.be.true;
});
Then('l\'écran contient un texte {string}', async function (this: FestipodWorld, text: string) {
expect(this.hasText(text), `Text "${text}" should be present in screen "${this.currentScreenId}"`).to.be.true;
});
Then('l\'écran contient un avatar', async function (this: FestipodWorld) {
const source = this.getRenderedText();
const hasAvatar = /<Avatar/.test(source);
expect(hasAvatar, `Avatar should be present in screen "${this.currentScreenId}"`).to.be.true;
});
+14 -79
View File
@@ -34,11 +34,8 @@ Then('je peux voir la section {string}', async function (this: FestipodWorld, se
expect(found, `Section "${sectionName}" should be visible on screen`).to.be.true;
});
Then('la page affiche {int} éléments', async function (this: FestipodWorld, count: number) {
// Cannot count rendered elements without browser automation
this.attach(`CANNOT TEST: Counting ${count} elements requires browser automation`, 'text/plain');
return 'pending';
});
// Step removed: "la page affiche N éléments" requires browser automation.
// Scenarios needing this use "* Scénario non implémenté" placeholder.
Then('je peux voir mon profil', async function (this: FestipodWorld) {
expect(this.currentScreenId).to.equal('profile');
@@ -67,8 +64,7 @@ Then('je peux voir la liste des événements', async function (this: FestipodWor
// EventsScreen.tsx has: EventCard components with event data
expect(/<Card[^>]*onClick/.test(source), 'Events screen should have clickable Card components').to.be.true;
} else {
this.attach(`UNEXPECTED SCREEN: "${this.currentScreenId}" is not expected to show events list`, 'text/plain');
return 'pending';
expect.fail(`Unexpected screen "${this.currentScreenId}" - events list should be on home or events screen`);
}
});
@@ -83,38 +79,20 @@ Then('je peux voir le QR code', async function (this: FestipodWorld) {
expect(/Mon QR Code/.test(source), 'Meeting points should have "Mon QR Code" text').to.be.true;
expect(/Scannez pour m'ajouter/.test(source), 'Meeting points should have "Scannez pour m\'ajouter" text').to.be.true;
} else {
// QR code is NOT on this screen
this.attach(`NOT ON THIS SCREEN: QR code is on share-profile or meeting-points, not "${this.currentScreenId}"`, 'text/plain');
return 'pending';
expect.fail(`QR code should be on share-profile or meeting-points, not "${this.currentScreenId}"`);
}
});
Then('je peux voir le lien de partage', async function (this: FestipodWorld) {
expect(this.currentScreenId, 'Share link should be on share-profile screen').to.equal('share-profile');
const source = this.getRenderedText();
if (this.currentScreenId === 'share-profile') {
// ShareProfileScreen.tsx has: "Mon lien de profil" text and profileLink variable
expect(/Mon lien de profil/.test(source), 'Share profile should have "Mon lien de profil" text').to.be.true;
expect(/festipod\.app\/u\//.test(source), 'Share profile should have profile link URL').to.be.true;
} else {
// Share link is NOT on this screen
this.attach(`NOT ON THIS SCREEN: Share link is on share-profile, not "${this.currentScreenId}"`, 'text/plain');
return 'pending';
}
// ShareProfileScreen.tsx has: "Mon lien de profil" text and profileLink variable
expect(/Mon lien de profil/.test(source), 'Share profile should have "Mon lien de profil" text').to.be.true;
expect(/festipod\.app\/u\//.test(source), 'Share profile should have profile link URL').to.be.true;
});
Given('un événement existe avec les données:', async function (this: FestipodWorld, dataTable) {
// Cannot set up test data without backend/database
const eventData = dataTable.rowsHash();
this.attach(`CANNOT TEST: Setting up event data requires backend: ${JSON.stringify(eventData)}`, 'text/plain');
return 'pending';
});
Given('un utilisateur existe avec les données:', async function (this: FestipodWorld, dataTable) {
// Cannot set up test data without backend/database
const userData = dataTable.rowsHash();
this.attach(`CANNOT TEST: Setting up user data requires backend: ${JSON.stringify(userData)}`, 'text/plain');
return 'pending';
});
// Steps removed: Data setup steps (un événement existe avec les données, un utilisateur existe avec les données)
// require backend/database. Scenarios needing these use "* Scénario non implémenté" placeholder.
Given('je visualise l\'événement {string}', async function (this: FestipodWorld, eventName: string) {
this.navigateTo('#/demo/event-detail');
@@ -156,40 +134,8 @@ Then('l\'écran affiche les informations du profil', async function (this: Festi
}
});
Then('je peux ajouter un commentaire', async function (this: FestipodWorld) {
// EventDetailScreen.tsx does NOT have comment functionality (no textarea, no "commentaire" text)
// This feature is NOT implemented in the UI
this.attach('NOT IMPLEMENTED: Comment functionality not in EventDetailScreen.tsx', 'text/plain');
return 'pending';
});
Then('je peux ajouter une note', async function (this: FestipodWorld) {
// No screen has note functionality implemented
// This feature is NOT implemented in the UI
this.attach('NOT IMPLEMENTED: Note functionality not implemented in any screen', 'text/plain');
return 'pending';
});
Then('je peux filtrer les événements par période', async function (this: FestipodWorld) {
// EventsScreen.tsx has filter badges (Tous, Cette semaine, Proches, Amis) but NOT period filter (mois/trimestre/année)
// This feature is NOT implemented in the UI
this.attach('NOT IMPLEMENTED: Period filter (mois/trimestre/année) not in EventsScreen.tsx', 'text/plain');
return 'pending';
});
Then('je peux modifier un commentaire', async function (this: FestipodWorld) {
// No comment edit functionality exists in any screen
// This feature is NOT implemented in the UI
this.attach('NOT IMPLEMENTED: Comment edit functionality not implemented', 'text/plain');
return 'pending';
});
Then('je peux supprimer un commentaire', async function (this: FestipodWorld) {
// No comment delete functionality exists in any screen
// This feature is NOT implemented in the UI
this.attach('NOT IMPLEMENTED: Comment delete functionality not implemented', 'text/plain');
return 'pending';
});
// Steps removed: Feature steps not implemented in UI (commentaire, note, filtrer par période, modifier/supprimer commentaire)
// Scenarios needing these use "* Scénario non implémenté" placeholder.
Then('je peux m\'inscrire à l\'événement', async function (this: FestipodWorld) {
expect(this.currentScreenId).to.equal('event-detail');
@@ -233,16 +179,5 @@ Then('je peux configurer mes notifications', async function (this: FestipodWorld
expect(/<Toggle[^>]*checked=\{notifications\}/.test(source), 'Settings should have Toggle for notifications').to.be.true;
});
Then('je peux définir mon rayon de notification', async function (this: FestipodWorld) {
// SettingsScreen.tsx has "Localisation" toggle but NOT "rayon" or "km" setting
// This feature is NOT implemented in the UI
this.attach('NOT IMPLEMENTED: Radius setting (rayon/km) is not in SettingsScreen.tsx', 'text/plain');
return 'pending';
});
Then('je peux définir mes thématiques d\'intérêt', async function (this: FestipodWorld) {
// SettingsScreen.tsx does NOT have thematic/interest settings
// This feature is NOT implemented in the UI
this.attach('NOT IMPLEMENTED: Thematic/interest settings not in SettingsScreen.tsx', 'text/plain');
return 'pending';
});
// Steps removed: Settings features not implemented in UI (rayon de notification, thématiques d'intérêt)
// Scenarios needing these use "* Scénario non implémenté" placeholder.
@@ -28,3 +28,6 @@ Fonctionnalité: US-12 Consulter la carte/tableau des événements
Scénario: Vérifier les données de l'écran profil
* Scénario non implémenté
Scénario: Voir la vue carte des événements
* Scénario non implémenté
@@ -9,18 +9,21 @@ Fonctionnalité: US-15 Visualiser les inscrits à un atelier/événement
Contexte:
Étant donné que je suis connecté en tant qu'utilisateur
Scénario: Accéder à la liste des inscrits
Scénario: Accéder à la liste des inscrits d'un événement
Étant donné que je suis sur la page "détail événement"
Alors je peux voir la liste des participants
Scénario: Voir la liste triée
Scénario: Accéder à la liste des inscrits d'un atelier
* Scénario non implémenté
Scénario: Voir la liste des participants d'un événement
Étant donné que je suis sur la page "détail événement"
Alors l'écran contient une section "Participants"
Scénario: Voir la liste des participants d'un atelier
* Scénario non implémenté
Scénario: Cliquer sur un inscrit pour voir son profil
Étant donné que je suis sur la page "détail événement"
Quand je clique sur un participant
Alors je vois l'écran "user-profile"
Scénario: Vérifier les données de l'écran
* Scénario non implémenté
+8 -1
View File
@@ -15,7 +15,9 @@ Fonctionnalité: US-20 Voir le profil des personnes faisant partie de mon résea
Alors je vois l'écran "profile"
Scénario: Voir mon réseau
* Scénario non implémenté
Étant donné que je suis sur la page "mon profil"
Alors l'écran contient un texte "Amis"
Et l'écran contient un texte "Mes amis"
Scénario: Voir un profil de mon réseau
Étant donné que je suis sur la page "mon profil"
@@ -28,4 +30,9 @@ Fonctionnalité: US-20 Voir le profil des personnes faisant partie de mon résea
Alors je vois l'écran "event-detail"
Scénario: Vérifier les données du profil
Étant donné que je suis sur la page "mon profil"
Alors l'écran contient un texte "Événements"
Et l'écran contient un texte "Participations"
Scénario: Voir les profils publiques
* Scénario non implémenté
+16 -4
View File
@@ -10,13 +10,25 @@ Fonctionnalité: US-22 Parrainer un nouvel utilisateur
Étant donné que je suis connecté en tant qu'utilisateur
Scénario: Accéder au partage de profil
* Scénario non implémenté
Étant donné que je suis sur la page "profil"
Alors l'écran contient un bouton "Partager"
Scénario: Naviguer vers le partage de profil
Étant donné que je suis sur la page "profil"
Quand je navigue vers "partage de profil"
Alors je vois l'écran "share-profile"
Scénario: Voir le QR code de parrainage
* Scénario non implémenté
Étant donné que je suis sur la page "partage profil"
Alors l'écran contient un texte "Scannez pour me retrouver sur Festipod"
Scénario: Voir le lien de parrainage
* Scénario non implémenté
Étant donné que je suis sur la page "partage profil"
Alors l'écran contient une section "Mon lien de profil"
Et l'écran contient un bouton "Copier"
Scénario: Voir les statistiques de parrainage
* Scénario non implémenté
Étant donné que je suis sur la page "partage profil"
Alors l'écran contient une section "Statistiques de parrainage"
Et l'écran contient un texte "Personnes parrainées"
Et l'écran contient un texte "Scans du QR code"
@@ -14,10 +14,12 @@ Fonctionnalité: US-23 Me connecter avec d'autres utilisateurs
Alors l'écran contient une section "Partager"
Scénario: Voir le QR code
* Scénario non implémenté
Étant donné que je suis sur la page "partage profil"
Alors l'écran contient un texte "Scannez pour me retrouver sur Festipod"
Scénario: Voir le lien de partage
* Scénario non implémenté
Étant donné que je suis sur la page "partage profil"
Alors l'écran contient une section "Mon lien de profil"
Scénario: Accéder à l'écran de partage dédié
Étant donné que je suis sur la page "mon profil"
@@ -25,4 +27,5 @@ Fonctionnalité: US-23 Me connecter avec d'autres utilisateurs
Alors je vois l'écran "share-profile"
Scénario: Vérifier les données du profil
* Scénario non implémenté
Étant donné que je suis sur la page "partage profil"
Alors l'écran contient un texte "Marie Dupont"
+3 -1
View File
@@ -10,7 +10,9 @@ Fonctionnalité: US-26 Définir la portée d'un événement
Étant donné que je suis connecté en tant qu'utilisateur
Scénario: Accéder à la création d'événement
* Scénario non implémenté
Étant donné que je suis sur la page "accueil"
Quand je navigue vers "créer un événement"
Alors je vois l'écran "create-event"
Scénario: Définir le rayon d'intérêt
* Scénario non implémenté
+7 -1
View File
@@ -10,7 +10,8 @@ Fonctionnalité: US-9 Visualiser la photo d'un individu
Étant donné que je suis connecté en tant qu'utilisateur
Scénario: Accéder au profil pour voir la photo
* Scénario non implémenté
Étant donné que je suis sur la page "mon profil"
Alors l'écran contient un avatar
Scénario: Naviguer vers le profil depuis la liste des participants
Étant donné que je suis sur la page "détail événement"
@@ -23,4 +24,9 @@ Fonctionnalité: US-9 Visualiser la photo d'un individu
Alors je peux voir la liste des participants
Scénario: Vérifier les champs de données du profil
Étant donné que je suis sur la page "mon profil"
Alors l'écran contient un texte "Marie Dupont"
Et l'écran contient un texte "@mariedupont"
Scénario: Ajouter une photo personnelle sur une fiche existante
* Scénario non implémenté
@@ -16,3 +16,9 @@ Fonctionnalité: US-1 Visualiser un événement terminé (ateliers)
Scénario: Consulter les ressources d'un atelier
* Scénario non implémenté
Scénario: Consulter le programme détaillé par journée/heure
* Scénario non implémenté
Scénario: Accéder à la zone de partage collective
* Scénario non implémenté
@@ -13,13 +13,7 @@ Fonctionnalité: US-14 Créer/Modifier/Supprimer un atelier
* Scénario non implémenté
Scénario: Vérifier les champs obligatoires pour créer un atelier
Étant donné que l'écran "create-event" est affiché
Alors le formulaire contient les champs obligatoires suivants:
| Nom de l'événement |
| Date |
| Heure de début |
| Lieu |
| Thématique |
* Scénario non implémenté
Scénario: Créer un atelier
* Scénario non implémenté
@@ -29,3 +23,9 @@ Fonctionnalité: US-14 Créer/Modifier/Supprimer un atelier
Scénario: Supprimer un atelier
* Scénario non implémenté
Scénario: Sélectionner mon événement parent
* Scénario non implémenté
Scénario: Définir les horaires de fin de l'atelier
* Scénario non implémenté
@@ -19,3 +19,6 @@ Fonctionnalité: US-2 Visualiser un événement terminé (notes)
Scénario: Ajouter un lien/ressource
* Scénario non implémenté
Scénario: Consulter le programme détaillé des ateliers par journée/heure
* Scénario non implémenté
@@ -20,3 +20,6 @@ Fonctionnalité: US-4 Ajouter/modifier/supprimer un commentaire à un atelier
Scénario: Supprimer un commentaire
* Scénario non implémenté
Scénario: Accéder à l'icône ajouter un commentaire
* Scénario non implémenté
@@ -1,21 +1,19 @@
# language: fr
@WORKSHOP @priority-3
Fonctionnalité: US-6 M'inscrire/me désinscrire à un événement (atelier)
Fonctionnalité: US-6 M'inscrire/me désinscrire à un atelier
En tant qu'utilisateur
Je peux m'inscrire/me désinscrire à un événement
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
Contexte:
Étant donné que je suis connecté en tant qu'utilisateur
Scénario: Rechercher un événement public existant
Étant donné que je suis sur la page "découvrir"
Alors je peux voir la liste des événements
Scénario: Voir les ateliers d'un événement
* Scénario non implémenté
Scénario: Voir les personnes pré-inscrites à un atelier
Étant donné que je suis sur la page "détail événement"
Alors je peux voir la liste des participants
* Scénario non implémenté
Scénario: S'inscrire à un atelier
* Scénario non implémenté