batchCooking/apps/web/cypress/e2e/recipes.ts
Nicolas a860363438 fix(web-tests): résout les steps Cucumber manquants dans recipe-sources.feature
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 <noreply@anthropic.com>
2026-08-20 16:22:12 +02:00

109 lines
3.2 KiB
TypeScript

import { Given, Then, When } from "@badeball/cypress-cucumber-preprocessor";
const oeufs = { id: 2, key: "eggs", kind: "ALLERGY" };
const omelette = {
id: 2,
name: "Omelette",
description: null,
picture: null,
portions: 2,
authorId: 1,
visibility: "PERSONAL",
allergens: [oeufs],
diets: [],
isFavorite: false,
};
const omeletteDetail = {
...omelette,
description: "Une omelette toute simple.",
ingredients: [
{
ingredient: {
id: 10,
key: "egg",
icon: "EGG",
category: "dairyAndCheese",
subcategory: "eggs",
allergens: [oeufs],
diets: [],
},
quantity: 3,
unit: { id: 1, key: "piece", type: "COUNT", toBaseFactor: 1 },
},
],
steps: [
{ id: 1, description: "Battre les œufs.", picture: null, order: 1, techSteps: [] },
{
id: 2,
description: "Cuire à la poêle.",
picture: null,
order: 2,
// "Cuire" -> the `cook` technique, matching real reference-seed-data.ts
// (`\bcui(re|sez|sant|sson)\b`) — "poêle" itself matches nothing
// (that's `panFry`'s "sauter", a different word).
techSteps: [{ techStep: { id: 1, key: "cook" }, start: 0, end: 5 }],
},
],
};
Given("the disliked ingredients list is empty", () => {
cy.intercept("GET", "**/profile/disliked-ingredients", { statusCode: 200, body: [] });
});
Given("the recipe catalog contains {string}", () => {
cy.intercept("GET", /\/recipes\?/, { statusCode: 200, body: [omelette] });
});
Given("recipe 2's detail is available", () => {
cy.intercept("GET", "**/recipes/2", { statusCode: 200, body: omeletteDetail }).as("getRecipe");
});
Given("toggling recipe 2's favorite will succeed", () => {
cy.intercept("POST", "**/recipes/2/favorite", { statusCode: 204 }).as("favorite");
});
Given("deleting recipe 2 will succeed", () => {
cy.intercept("DELETE", "**/recipes/2", { statusCode: 204 }).as("deleteRecipe");
});
Then("the recipe {string} should not be visible in the table", (name: string) => {
cy.contains(".recipe-table__name", name).should("not.exist");
});
Then("the recipe {string} should be marked as favorite", (name: string) => {
cy.contains(".recipe-table__name", name).find(".recipe-table__fav-mark").should("exist");
});
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");
});
When("I click the favorite star", () => {
cy.get(".favorite-star-button").click();
});
Then("the favorite request should have been made", () => {
cy.wait("@favorite");
});
Then("the favorite star should be marked as favorite", () => {
cy.get(".favorite-star-button").should("have.class", "is-favorite");
});
When("I click {string} in the recipe detail panel", (text: string) => {
cy.contains(".recipe-detail-panel__danger-button", text).click();
});
When("I confirm the deletion in the recipe detail panel", () => {
cy.contains(".recipe-detail-panel__danger-button", "Confirmer la suppression").click();
});
Then("the delete request should have been made", () => {
cy.wait("@deleteRecipe");
});
Then("the URL should match the recipes list", () => {
cy.url().should("match", /\/recettes\/?$/);
});