Simplify skipped scenario format with placeholder step

Replace @skip tag + placeholder step with just placeholder step.
Skipped scenarios now only need:
  Scénario: Name
    * Scénario non implémenté

- Remove @skip tags from all 26 feature files
- Add step definition returning 'skipped' for placeholder
- Update GherkinHighlighter to hide placeholder and make
  skipped scenarios non-expandable (no chevron, no click)
- Update documentation with new format

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Sylvain Duchesne
2026-01-19 10:31:42 +01:00
parent ed61c7081f
commit 7827479e9c
35 changed files with 1438 additions and 5621 deletions
+108 -1073
View File
File diff suppressed because it is too large Load Diff
+24 -17
View File
@@ -10,124 +10,131 @@ export interface StepDefinitionInfo {
}
export const stepDefinitions: StepDefinitionInfo[] = [
{
"pattern": "Scénario non implémenté",
"keyword": "Given",
"file": "navigation.steps.ts",
"sourceCode": "Given('Scénario non implémenté', async function (this: FestipodWorld) {\n return 'skipped';\n});",
"lineNumber": 7
},
{
"pattern": "je suis sur la page {string}",
"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": 31
"lineNumber": 37
},
{
"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": 36
"lineNumber": 42
},
{
"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": 40
"lineNumber": 46
},
{
"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": 44
"lineNumber": 50
},
{
"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": 48
"lineNumber": 54
},
{
"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": 53
"lineNumber": 59
},
{
"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": 65
"lineNumber": 71
},
{
"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": 77
"lineNumber": 83
},
{
"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": 89
"lineNumber": 95
},
{
"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": 93
"lineNumber": 99
},
{
"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": 97
"lineNumber": 103
},
{
"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": 102
"lineNumber": 108
},
{
"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": 107
"lineNumber": 113
},
{
"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": 112
"lineNumber": 118
},
{
"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": 120
"lineNumber": 126
},
{
"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": 128
"lineNumber": 134
},
{
"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": 140
"lineNumber": 146
},
{
"pattern": "l'écran {string} est affiché",
+44 -76
View File
@@ -19,7 +19,7 @@ const rawResults: RawFeatureTestStatus[] = [
"passed": 4,
"failed": 0,
"skipped": 1,
"lastRun": "2026-01-18T20:32:26.120Z",
"lastRun": "2026-01-19T09:27:22.847Z",
"scenarios": [
{
"name": "Accéder à la création d'événement",
@@ -49,7 +49,7 @@ const rawResults: RawFeatureTestStatus[] = [
"passed": 3,
"failed": 0,
"skipped": 1,
"lastRun": "2026-01-18T20:32:26.120Z",
"lastRun": "2026-01-19T09:27:22.847Z",
"scenarios": [
{
"name": "Accéder aux détails d'un événement terminé",
@@ -71,11 +71,11 @@ const rawResults: RawFeatureTestStatus[] = [
},
{
"featureId": "us-5",
"totalScenarios": 5,
"totalScenarios": 4,
"passed": 0,
"failed": 0,
"skipped": 5,
"lastRun": "2026-01-18T20:32:26.120Z",
"skipped": 4,
"lastRun": "2026-01-19T09:27:22.847Z",
"scenarios": [
{
"name": "Voir les commentaires existants",
@@ -92,10 +92,6 @@ const rawResults: RawFeatureTestStatus[] = [
{
"name": "Supprimer un commentaire",
"status": "skipped"
},
{
"name": "Vérifier les données de l'écran",
"status": "skipped"
}
]
},
@@ -105,7 +101,7 @@ const rawResults: RawFeatureTestStatus[] = [
"passed": 2,
"failed": 0,
"skipped": 3,
"lastRun": "2026-01-18T20:32:26.120Z",
"lastRun": "2026-01-19T09:27:22.848Z",
"scenarios": [
{
"name": "Consulter un événement avant inscription",
@@ -135,7 +131,7 @@ const rawResults: RawFeatureTestStatus[] = [
"passed": 0,
"failed": 0,
"skipped": 4,
"lastRun": "2026-01-18T20:32:26.120Z",
"lastRun": "2026-01-19T09:27:22.848Z",
"scenarios": [
{
"name": "Consulter un macro-événement",
@@ -157,11 +153,11 @@ const rawResults: RawFeatureTestStatus[] = [
},
{
"featureId": "us-16",
"totalScenarios": 6,
"passed": 2,
"totalScenarios": 5,
"passed": 1,
"failed": 0,
"skipped": 4,
"lastRun": "2026-01-18T20:32:26.120Z",
"lastRun": "2026-01-19T09:27:22.848Z",
"scenarios": [
{
"name": "Accéder aux points de rencontre",
@@ -177,14 +173,10 @@ const rawResults: RawFeatureTestStatus[] = [
},
{
"name": "Définir l'heure de rencontre",
"status": "passed"
},
{
"name": "Échanger des liens de contact",
"status": "skipped"
},
{
"name": "Vérifier les données requises",
"name": "Échanger des liens de contact",
"status": "skipped"
}
]
@@ -195,7 +187,7 @@ const rawResults: RawFeatureTestStatus[] = [
"passed": 0,
"failed": 0,
"skipped": 5,
"lastRun": "2026-01-18T20:32:26.121Z",
"lastRun": "2026-01-19T09:27:22.848Z",
"scenarios": [
{
"name": "Partager un événement auquel je participe",
@@ -221,11 +213,11 @@ const rawResults: RawFeatureTestStatus[] = [
},
{
"featureId": "us-18",
"totalScenarios": 5,
"totalScenarios": 4,
"passed": 1,
"failed": 0,
"skipped": 4,
"lastRun": "2026-01-18T20:32:26.121Z",
"skipped": 3,
"lastRun": "2026-01-19T09:27:22.848Z",
"scenarios": [
{
"name": "Configurer les notifications de nouveaux participants",
@@ -242,10 +234,6 @@ const rawResults: RawFeatureTestStatus[] = [
{
"name": "Voir les nouveaux participants sur l'accueil",
"status": "skipped"
},
{
"name": "Vérifier les données des paramètres",
"status": "skipped"
}
]
},
@@ -255,7 +243,7 @@ const rawResults: RawFeatureTestStatus[] = [
"passed": 1,
"failed": 0,
"skipped": 4,
"lastRun": "2026-01-18T20:32:26.121Z",
"lastRun": "2026-01-19T09:27:22.848Z",
"scenarios": [
{
"name": "Voir les événements à venir sur l'accueil",
@@ -285,7 +273,7 @@ const rawResults: RawFeatureTestStatus[] = [
"passed": 4,
"failed": 0,
"skipped": 1,
"lastRun": "2026-01-18T20:32:26.121Z",
"lastRun": "2026-01-19T09:27:22.848Z",
"scenarios": [
{
"name": "Accéder au profil d'un participant",
@@ -315,7 +303,7 @@ const rawResults: RawFeatureTestStatus[] = [
"passed": 2,
"failed": 0,
"skipped": 4,
"lastRun": "2026-01-18T20:32:26.121Z",
"lastRun": "2026-01-19T09:27:22.848Z",
"scenarios": [
{
"name": "Accéder à la liste des événements depuis le profil",
@@ -349,7 +337,7 @@ const rawResults: RawFeatureTestStatus[] = [
"passed": 3,
"failed": 0,
"skipped": 1,
"lastRun": "2026-01-18T20:32:26.121Z",
"lastRun": "2026-01-19T09:27:22.848Z",
"scenarios": [
{
"name": "Accéder à la liste des inscrits",
@@ -375,7 +363,7 @@ const rawResults: RawFeatureTestStatus[] = [
"passed": 3,
"failed": 0,
"skipped": 2,
"lastRun": "2026-01-18T20:32:26.121Z",
"lastRun": "2026-01-19T09:27:22.848Z",
"scenarios": [
{
"name": "Accéder à mon profil",
@@ -405,7 +393,7 @@ const rawResults: RawFeatureTestStatus[] = [
"passed": 2,
"failed": 0,
"skipped": 3,
"lastRun": "2026-01-18T20:32:26.121Z",
"lastRun": "2026-01-19T09:27:22.848Z",
"scenarios": [
{
"name": "Accéder aux paramètres de profil",
@@ -431,11 +419,11 @@ const rawResults: RawFeatureTestStatus[] = [
},
{
"featureId": "us-22",
"totalScenarios": 5,
"totalScenarios": 4,
"passed": 0,
"failed": 0,
"skipped": 5,
"lastRun": "2026-01-18T20:32:26.121Z",
"skipped": 4,
"lastRun": "2026-01-19T09:27:22.848Z",
"scenarios": [
{
"name": "Accéder au partage de profil",
@@ -452,10 +440,6 @@ const rawResults: RawFeatureTestStatus[] = [
{
"name": "Voir les statistiques de parrainage",
"status": "skipped"
},
{
"name": "Vérifier les données du profil",
"status": "skipped"
}
]
},
@@ -465,7 +449,7 @@ const rawResults: RawFeatureTestStatus[] = [
"passed": 2,
"failed": 0,
"skipped": 3,
"lastRun": "2026-01-18T20:32:26.121Z",
"lastRun": "2026-01-19T09:27:22.848Z",
"scenarios": [
{
"name": "Accéder au partage depuis le profil",
@@ -491,11 +475,11 @@ const rawResults: RawFeatureTestStatus[] = [
},
{
"featureId": "us-24",
"totalScenarios": 4,
"totalScenarios": 3,
"passed": 2,
"failed": 0,
"skipped": 2,
"lastRun": "2026-01-18T20:32:26.121Z",
"skipped": 1,
"lastRun": "2026-01-19T09:27:22.848Z",
"scenarios": [
{
"name": "Accéder aux paramètres de notification",
@@ -508,20 +492,16 @@ const rawResults: RawFeatureTestStatus[] = [
{
"name": "Voir les activités de mes contacts sur l'accueil",
"status": "skipped"
},
{
"name": "Vérifier les données des paramètres",
"status": "skipped"
}
]
},
{
"featureId": "us-25",
"totalScenarios": 4,
"totalScenarios": 3,
"passed": 1,
"failed": 0,
"skipped": 3,
"lastRun": "2026-01-18T20:32:26.121Z",
"skipped": 2,
"lastRun": "2026-01-19T09:27:22.848Z",
"scenarios": [
{
"name": "Accéder aux paramètres de notification",
@@ -534,10 +514,6 @@ const rawResults: RawFeatureTestStatus[] = [
{
"name": "Configurer les thématiques d'intérêt",
"status": "skipped"
},
{
"name": "Vérifier les données des paramètres",
"status": "skipped"
}
]
},
@@ -547,7 +523,7 @@ const rawResults: RawFeatureTestStatus[] = [
"passed": 2,
"failed": 0,
"skipped": 2,
"lastRun": "2026-01-18T20:32:26.121Z",
"lastRun": "2026-01-19T09:27:22.848Z",
"scenarios": [
{
"name": "Accéder à la création d'événement",
@@ -573,7 +549,7 @@ const rawResults: RawFeatureTestStatus[] = [
"passed": 2,
"failed": 0,
"skipped": 2,
"lastRun": "2026-01-18T20:32:26.121Z",
"lastRun": "2026-01-19T09:27:22.848Z",
"scenarios": [
{
"name": "Accéder au profil pour voir la photo",
@@ -595,11 +571,11 @@ const rawResults: RawFeatureTestStatus[] = [
},
{
"featureId": "us-1",
"totalScenarios": 4,
"passed": 1,
"totalScenarios": 3,
"passed": 0,
"failed": 0,
"skipped": 3,
"lastRun": "2026-01-18T20:32:26.121Z",
"lastRun": "2026-01-19T09:27:22.848Z",
"scenarios": [
{
"name": "Accéder aux détails d'un événement terminé",
@@ -607,25 +583,21 @@ const rawResults: RawFeatureTestStatus[] = [
},
{
"name": "Consulter la liste des participants d'un atelier",
"status": "passed"
},
{
"name": "Consulter les ressources d'un atelier",
"status": "skipped"
},
{
"name": "Vérifier les données affichées pour un atelier",
"name": "Consulter les ressources d'un atelier",
"status": "skipped"
}
]
},
{
"featureId": "us-11",
"totalScenarios": 4,
"totalScenarios": 3,
"passed": 0,
"failed": 0,
"skipped": 4,
"lastRun": "2026-01-18T20:32:26.121Z",
"skipped": 3,
"lastRun": "2026-01-19T09:27:22.848Z",
"scenarios": [
{
"name": "Accéder au bilan consolidé",
@@ -638,10 +610,6 @@ const rawResults: RawFeatureTestStatus[] = [
{
"name": "Voir la synthèse globale",
"status": "skipped"
},
{
"name": "Vérifier les données du bilan",
"status": "skipped"
}
]
},
@@ -651,7 +619,7 @@ const rawResults: RawFeatureTestStatus[] = [
"passed": 1,
"failed": 0,
"skipped": 4,
"lastRun": "2026-01-18T20:32:26.121Z",
"lastRun": "2026-01-19T09:27:22.848Z",
"scenarios": [
{
"name": "Accéder à la création d'atelier",
@@ -681,7 +649,7 @@ const rawResults: RawFeatureTestStatus[] = [
"passed": 0,
"failed": 0,
"skipped": 4,
"lastRun": "2026-01-18T20:32:26.121Z",
"lastRun": "2026-01-19T09:27:22.848Z",
"scenarios": [
{
"name": "Accéder à la zone de notes personnelles",
@@ -707,7 +675,7 @@ const rawResults: RawFeatureTestStatus[] = [
"passed": 0,
"failed": 0,
"skipped": 4,
"lastRun": "2026-01-18T20:32:26.121Z",
"lastRun": "2026-01-19T09:27:22.848Z",
"scenarios": [
{
"name": "Voir les commentaires existants d'un atelier",
@@ -733,7 +701,7 @@ const rawResults: RawFeatureTestStatus[] = [
"passed": 2,
"failed": 0,
"skipped": 2,
"lastRun": "2026-01-18T20:32:26.121Z",
"lastRun": "2026-01-19T09:27:22.848Z",
"scenarios": [
{
"name": "Rechercher un événement public existant",