import { Given, Then, When } from "@badeball/cypress-cucumber-preprocessor"; /** Bare `IngredientView` — only `key` drives the page's `catalog.ingredients.*` lookup. */ function ingredient(key: string) { return { id: 1, key, icon: "VEGETABLE", category: "freshProduce", subcategory: "vegetables", reproducible: false, allergens: [], diets: [], }; } Given( "the planning for this week has recipes {string} and {string}", (first: string, second: string) => { cy.intercept("GET", /\/planning\?/, { statusCode: 200, body: { id: 1, startDate: "2026-08-17T00:00:00.000Z", finishDate: "2026-08-23T00:00:00.000Z", items: [ { id: 1, weekDay: "lundi", meal: "dejeuner", portions: 4, recipe: { id: 1, name: first }, }, { id: 2, weekDay: "mardi", meal: "diner", portions: 4, recipe: { id: 2, name: second } }, ], }, }); }, ); Given( "the cooking plan for {string} pools {string} of {string} across both recipes", (date: string, _techniqueLabel: string, _ingredientLabel: string) => { // The page composes the headline itself from the technique/ingredient // *keys* via i18n — `chop`→"Hacher", `onion`→"Oignon" — so the fixture // carries keys; the `Then` step checks the rendered French labels the // feature line names. cy.intercept("GET", `**/cooking-session?date=${date}`, { statusCode: 200, body: { startDate: `${date}T00:00:00.000Z`, finishDate: "2026-08-23T00:00:00.000Z", recipes: [ { recipeId: 1, name: "Soupe à l'oignon", portions: 4 }, { recipeId: 2, name: "Tarte à l'oignon", portions: 4 }, ], phases: [ { index: 0, kind: "mise-en-place", background: [], notes: [], tasks: [ { id: "prep:chop:onion", kind: "merged-prep", technique: { id: 1, key: "chop" }, description: null, ingredients: [ { ingredient: ingredient("onion"), quantity: 5, unit: { id: 2, key: "piece", type: "COUNT", toBaseFactor: 1 }, }, ], utensils: [], temperatures: [], sourceRecipes: [ { recipeId: 1, name: "Soupe à l'oignon", portions: 4 }, { recipeId: 2, name: "Tarte à l'oignon", portions: 4 }, ], originalSteps: [], }, ], }, ], }, }); }, ); Then( "the pooled prep task should mention {string} and {string}", (techniqueLabel: string, ingredientLabel: string) => { cy.get(".cooking-task--merged-prep") .should("contain.text", techniqueLabel) .and("contain.text", ingredientLabel); }, ); Then("the pooled prep task should be flagged as shared", () => { cy.get(".cooking-task--merged-prep").contains("Mutualisé").should("be.visible"); }); Then("the pooled prep task should sit in the recipe section {string}", (sectionTitle: string) => { cy.contains(".cooking-phase__recipe-group", sectionTitle) .find(".cooking-task--merged-prep") .should("exist"); }); Given("the cooking plan for {string} has a mise en place then a cooking step", (date: string) => { // Two phases so the stepper actually has somewhere to step to: the // pooled `chop onion` prep, then a `simmer` cooking step. cy.intercept("GET", `**/cooking-session?date=${date}`, { statusCode: 200, body: { startDate: `${date}T00:00:00.000Z`, finishDate: "2026-08-23T00:00:00.000Z", recipes: [ { recipeId: 1, name: "Soupe à l'oignon", portions: 4 }, { recipeId: 2, name: "Tarte à l'oignon", portions: 6 }, ], phases: [ { index: 0, kind: "mise-en-place", background: [], notes: [], tasks: [ { id: "prep:chop:onion", kind: "merged-prep", technique: { id: 1, key: "chop" }, description: null, ingredients: [ { ingredient: ingredient("onion"), quantity: 5, unit: { id: 2, key: "piece", type: "COUNT", toBaseFactor: 1 }, }, ], utensils: [], temperatures: [], sourceRecipes: [ { recipeId: 1, name: "Soupe à l'oignon", portions: 4 }, { recipeId: 2, name: "Tarte à l'oignon", portions: 6 }, ], originalSteps: [], }, ], }, { index: 1, kind: "cooking", background: [], notes: [], tasks: [ { id: "step:0:1", kind: "step", technique: { id: 5, key: "simmer" }, description: "Faire mijoter le bouillon", ingredients: [], utensils: [], temperatures: [], sourceRecipes: [{ recipeId: 1, name: "Soupe à l'oignon", portions: 4 }], originalSteps: [], }, ], }, ], }, }); }); Given("the cooking plan for {string} needs the oven at 180 °C and 210 °C", (date: string) => { const celsius = (value: number) => ({ celsius: value, gasMark: null, qualitative: null }); const preheatStep = (id: string, recipe: { recipeId: number; name: string }, value: number) => ({ id, kind: "step", technique: { id: 9, key: "preheat" }, description: `Préchauffer le four à ${value}°C`, ingredients: [], utensils: [], temperatures: [celsius(value)], sourceRecipes: [recipe], originalSteps: [], }); const gratin = { recipeId: 1, name: "Gratin", portions: 4 }; const roti = { recipeId: 2, name: "Rôti", portions: 4 }; cy.intercept("GET", `**/cooking-session?date=${date}`, { statusCode: 200, body: { startDate: `${date}T00:00:00.000Z`, finishDate: "2026-08-23T00:00:00.000Z", recipes: [gratin, roti], phases: [ { index: 0, kind: "mise-en-place", background: [], notes: [ { kind: "appliance-temperature-conflict", technique: { id: 9, key: "preheat" }, temperatures: [celsius(180), celsius(210)], }, ], // Coolest first, as the optimizer emits them. tasks: [preheatStep("step:0:1", gratin, 180), preheatStep("step:1:2", roti, 210)], }, ], }, }); }); Then("I should see the oven conflict note {string}", (text: string) => { cy.get(".cooking-phase__note").should("contain.text", text); }); Then("I should see the recipe sections {string} and {string}", (first: string, second: string) => { cy.contains(".cooking-phase__recipe-group-title", first).should("be.visible"); cy.contains(".cooking-phase__recipe-group-title", second).should("be.visible"); }); When("I open the {string} cooking tab", (label: string) => { cy.contains(".cooking-session-page__tab", label).click(); }); // The task card is a `