From a86036343806914e2bdb4a17508f52543d9184e8 Mon Sep 17 00:00:00 2001 From: Nicolas Date: Thu, 20 Aug 2026 16:22:12 +0200 Subject: [PATCH] =?UTF-8?q?fix(web-tests):=20r=C3=A9sout=20les=20steps=20C?= =?UTF-8?q?ucumber=20manquants=20dans=20recipe-sources.feature?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit La CI a révélé que la résolution des steps Cucumber n'est pas globale sur tout cypress/e2e/ comme je le pensais — seuls le fichier/dossier de même nom que la .feature et cypress/support/step_definitions/ sont cherchés (voir le message d'erreur de la CI). recipes.ts vit directement dans cypress/e2e/ (pas dans step_definitions/), donc ses steps ne résolvaient que pour recipes.feature — recipe-sources.feature qui les réutilisait plantait avec "Step implementation missing". - Les steps génériques réellement partagés entre les deux features (heading du panneau détail, technique surlignée, tooltip) migrent vers common.steps.ts (step_definitions/, cherché globalement) plutôt que d'être dupliqués une deuxième fois. - Les steps propres à un fixture précis (recipe 2's detail, disliked ingredients, catalogue vide) sont redéclarés localement dans recipe-sources.ts avec leurs propres données minimales — même précédent que recipes.cy.ts, qui duplique déjà indépendamment le fixture omeletteDetail plutôt que de dépendre de recipes.ts. Co-Authored-By: Claude Sonnet 5 --- apps/web/cypress/e2e/recipe-sources.feature | 6 +-- apps/web/cypress/e2e/recipe-sources.ts | 51 +++++++++++++++++-- apps/web/cypress/e2e/recipes.ts | 20 -------- .../support/step_definitions/common.steps.ts | 26 ++++++++++ 4 files changed, 76 insertions(+), 27 deletions(-) diff --git a/apps/web/cypress/e2e/recipe-sources.feature b/apps/web/cypress/e2e/recipe-sources.feature index ff1a95b..2342e6c 100644 --- a/apps/web/cypress/e2e/recipe-sources.feature +++ b/apps/web/cypress/e2e/recipe-sources.feature @@ -10,7 +10,7 @@ Feature: Browsing external recipe sources And the planning request returns nothing Scenario: Prompts to enable a source when the household hasn't enabled any - Given the recipe catalog contains "Omelette" + Given the recipe catalog contains nothing And the sources reference list has options And the household's enabled sources are empty When I visit "/recettes" @@ -18,7 +18,7 @@ Feature: Browsing external recipe sources Then I should see "Aucune source n'est activée" Scenario: Browses an enabled source, distinguishing already-imported items from new ones - Given the recipe catalog contains "Omelette" + Given the recipe catalog contains nothing And the sources reference list has options And the household has enabled TheMealDB And browsing TheMealDB returns some items @@ -34,7 +34,7 @@ Feature: Browsing external recipe sources And the recipe detail panel heading should be "Omelette" Scenario: Previews a not-yet-imported item, highlighting its detected techniques - Given the recipe catalog contains "Omelette" + Given the recipe catalog contains nothing And the sources reference list has options And the household has enabled TheMealDB And browsing TheMealDB returns some items diff --git a/apps/web/cypress/e2e/recipe-sources.ts b/apps/web/cypress/e2e/recipe-sources.ts index e587fab..47c130d 100644 --- a/apps/web/cypress/e2e/recipe-sources.ts +++ b/apps/web/cypress/e2e/recipe-sources.ts @@ -4,10 +4,53 @@ import { Given, Then, When } from "@badeball/cypress-cucumber-preprocessor"; // .github/workflows/ci.yml); apps/api's own Mocha suite covers real API // behavior against a real database (see test/sources.test.ts). // -// "the sources reference list has options" (theMealDb id 1, marmiton id 2) -// and "recipe 2's detail is available" are shared with reference-data.steps.ts -// / recipes.ts respectively — Cucumber step matching is global across every -// step-definition file, not scoped per feature. +// "the sources reference list has options"/"the household's enabled +// sources are empty" resolve from cypress/support/step_definitions/ (the +// preprocessor's step-lookup is *not* global across cypress/e2e/ — only a +// feature's own same-named file/directory plus that shared folder are +// searched, see its error message when a step isn't found). recipes.ts +// sits directly in cypress/e2e/ (not that shared folder), so its own +// "the disliked ingredients list is empty"/"the recipe catalog +// contains"/"recipe 2's detail is available" are scoped to recipes.feature +// only — this file redeclares its own minimal equivalents rather than +// relocating shared infra, the same "each spec's own self-contained +// fixtures" precedent recipes.cy.ts already sets alongside recipes.ts. + +Given("the disliked ingredients list is empty", () => { + cy.intercept("GET", "**/profile/disliked-ingredients", { statusCode: 200, body: [] }); +}); + +Given("the recipe catalog contains nothing", () => { + cy.intercept("GET", /\/recipes\?/, { statusCode: 200, body: [] }); +}); + +Given("recipe 2's detail is available", () => { + cy.intercept("GET", "**/recipes/2", { + statusCode: 200, + body: { + id: 2, + name: "Omelette", + description: null, + picture: null, + portions: 2, + authorId: 1, + visibility: "PERSONAL", + allergens: [], + diets: [], + isFavorite: false, + ingredients: [], + steps: [ + { + id: 1, + description: "Cuire à la poêle.", + picture: null, + order: 1, + techSteps: [{ techStep: { id: 1, key: "cook" }, start: 0, end: 5 }], + }, + ], + }, + }); +}); Given("the household has enabled TheMealDB", () => { cy.intercept("GET", "**/house/current/sources", { statusCode: 200, body: [1] }); diff --git a/apps/web/cypress/e2e/recipes.ts b/apps/web/cypress/e2e/recipes.ts index 42e3f34..14a75f5 100644 --- a/apps/web/cypress/e2e/recipes.ts +++ b/apps/web/cypress/e2e/recipes.ts @@ -80,10 +80,6 @@ Then("the recipe {string} should not be marked as favorite", (name: string) => { cy.contains(".recipe-table__name", name).find(".recipe-table__fav-mark").should("not.exist"); }); -Then("the recipe detail panel heading should be {string}", (text: string) => { - cy.get(".recipe-detail-panel").contains("h2", text).should("be.visible"); -}); - When("I click the favorite star", () => { cy.get(".favorite-star-button").click(); }); @@ -111,19 +107,3 @@ Then("the delete request should have been made", () => { Then("the URL should match the recipes list", () => { cy.url().should("match", /\/recettes\/?$/); }); - -Then("I should see the highlighted technique {string}", (text: string) => { - // The steps section sits below the panel's header/photo/description, off - // the fold of `.app-content`'s own scroll (see layout.cy.ts) — a bare - // `.should("be.visible")` doesn't auto-scroll, same fix as - // household-settings.feature's sources-section scenario. - cy.contains(".step-tech-step", text).scrollIntoView().should("be.visible"); -}); - -When("I focus the highlighted technique {string}", (text: string) => { - cy.contains(".step-tech-step", text).focus(); -}); - -Then("the tooltip should show {string}", (label: string) => { - cy.get(".tooltip__bubble").contains(label).should("be.visible"); -}); diff --git a/apps/web/cypress/support/step_definitions/common.steps.ts b/apps/web/cypress/support/step_definitions/common.steps.ts index 86fd61a..3eb2c1d 100644 --- a/apps/web/cypress/support/step_definitions/common.steps.ts +++ b/apps/web/cypress/support/step_definitions/common.steps.ts @@ -133,6 +133,32 @@ When("I scroll to the section {string}", (legend: string) => { cy.contains("legend", legend).scrollIntoView(); }); +// `.recipe-detail-panel` is used by both a saved recipe's real detail +// (RecipeDetailPanel) and an unsaved source item's read-only preview +// (SourceItemPreviewPanel) — recipes.feature and recipe-sources.feature +// both need this. +Then("the recipe detail panel heading should be {string}", (text: string) => { + cy.get(".recipe-detail-panel").contains("h2", text).should("be.visible"); +}); + +// `.step-tech-step`/`.tooltip__bubble` come from StepDescription/Tooltip +// (components/ui/), rendered by both of those same two panels — same +// reasoning as the detail-panel-heading step above. +Then("I should see the highlighted technique {string}", (text: string) => { + // The steps section can sit below the panel's header/photo/description, + // off the fold of `.app-content`'s own scroll (see layout.cy.ts) — a + // bare `.should("be.visible")` doesn't auto-scroll. + cy.contains(".step-tech-step", text).scrollIntoView().should("be.visible"); +}); + +When("I focus the highlighted technique {string}", (text: string) => { + cy.contains(".step-tech-step", text).focus(); +}); + +Then("the tooltip should show {string}", (label: string) => { + cy.get(".tooltip__bubble").contains(label).should("be.visible"); +}); + Then("the checkbox {string} should be checked", (label: string) => { cy.contains("label", label).find("input[type=checkbox]").should("be.checked"); });