La CI de la refonte précédente (commitaaace15) a échoué : la découverte par défaut du préprocesseur ne charge, pour un fichier `foo.feature`, QUE `foo.ts` (co-localisé, même basename) et `cypress/support/step_definitions/**` — pas les autres `.ts` du dossier `cypress/e2e/`. onboarding.feature référençait donc des steps qui ne vivaient que dans preferences.ts, household-settings.ts et auth.ts, introuvables lors de son propre run. Déplace les steps réellement partagés entre plusieurs .feature vers cypress/support/step_definitions/ (chargé pour toutes les features) : - reference-data.steps.ts : mocks des listes de référence régimes/ allergies (options ou vides) — partagé entre auth.feature et onboarding.feature - household-mutations.steps.ts : création/adhésion à un foyer et leurs assertions — partagé entre household-settings.feature et onboarding.feature - profile-mutations.steps.ts : sélection du régime, mise à jour des allergies et leur assertion — partagé entre preferences.feature et onboarding.feature Les définitions d'origine sont retirées de auth.ts/household- settings.ts/onboarding.ts/preferences.ts pour éviter un step "Ambiguous" (chargé deux fois pour la feature qui les définissait déjà elle-même). Corrige aussi un second bug distinct révélé par la même CI : "the ingredient/diet catalog is available" (recipe-form.feature) contient un "/" non échappé — en syntaxe Cucumber Expression, "/" hors d'un paramètre {..} signifie une alternative de texte ("ingredient" OU "diet catalog is available"), jamais le caractère littéral. Le texte du .feature ne pouvait donc jamais matcher. Renommé sans "/" : "the ingredient and diet catalog is available". Le script de vérification statique utilisé pour valideraaace15avant push donnait une fausse confiance : il regroupait tous les steps de tous les fichiers comme disponibles globalement pour chaque feature, sans respecter ce scoping réel. Réécrit pour ne charger, par feature, que son fichier co-localisé + step_definitions/ — et pour détecter les patterns contenant un "/" non échappé. Résultat : toujours 246 steps, 0 non résolu, 0 ambigu, 0 pattern à slash non échappé, cette fois avec un modèle de résolution fidèle au comportement réel du préprocesseur.
78 lines
2.3 KiB
TypeScript
78 lines
2.3 KiB
TypeScript
import { type DataTable, Given, Then, When } from "@badeball/cypress-cucumber-preprocessor";
|
|
import { ErrorCode } from "@batch-cooking/shared";
|
|
|
|
const signupResponse = {
|
|
id: 1,
|
|
firstName: "Alice",
|
|
lastName: "Martin",
|
|
email: "alice@example.com",
|
|
tokenVersion: 0,
|
|
houseId: null as number | null,
|
|
dietId: null,
|
|
};
|
|
|
|
Given("the signup request will succeed", () => {
|
|
cy.intercept("POST", "**/auth/signup", { statusCode: 201, body: signupResponse }).as("signup");
|
|
});
|
|
|
|
Given("the signup request is being watched", () => {
|
|
cy.intercept("POST", "**/auth/signup").as("signup");
|
|
});
|
|
|
|
Given("the signup request will fail because the email is already used", () => {
|
|
cy.intercept("POST", "**/auth/signup", {
|
|
statusCode: 409,
|
|
body: { code: ErrorCode.EMAIL_ALREADY_IN_USE, message: "Email already in use" },
|
|
}).as("signup");
|
|
});
|
|
|
|
When("I sign up with:", (dataTable: DataTable) => {
|
|
const { firstName, lastName, email, password } = dataTable.rowsHash();
|
|
cy.visit("/signup");
|
|
cy.get("#firstName").type(firstName);
|
|
cy.get("#lastName").type(lastName);
|
|
cy.get("#email").type(email);
|
|
cy.get("#password").type(password);
|
|
cy.contains("button", "Créer mon profil").click();
|
|
});
|
|
|
|
Then("the signup request should have been made", () => {
|
|
cy.wait("@signup");
|
|
});
|
|
|
|
Then("the signup request should not have been made", () => {
|
|
cy.get("@signup.all").should("have.length", 0);
|
|
});
|
|
|
|
Given("the login request will succeed", () => {
|
|
cy.intercept("POST", "**/auth/login", {
|
|
statusCode: 200,
|
|
body: { ...signupResponse, houseId: 1 },
|
|
}).as("login");
|
|
});
|
|
|
|
Given("the login request will fail because the credentials are invalid", () => {
|
|
cy.intercept("POST", "**/auth/login", {
|
|
statusCode: 401,
|
|
body: { code: ErrorCode.INVALID_CREDENTIALS, message: "Invalid email or password" },
|
|
}).as("login");
|
|
});
|
|
|
|
When("I log in with email {string} and password {string}", (email: string, password: string) => {
|
|
cy.visit("/login");
|
|
cy.get("#email").type(email);
|
|
cy.get("#password").type(password);
|
|
cy.contains("button", "Se connecter").click();
|
|
});
|
|
|
|
Then("the login request should have been made", () => {
|
|
cy.wait("@login");
|
|
});
|
|
|
|
Given("the logout request will succeed", () => {
|
|
cy.intercept("POST", "**/auth/logout", { statusCode: 204 }).as("logout");
|
|
});
|
|
|
|
Then("the logout request should have been made", () => {
|
|
cy.wait("@logout");
|
|
});
|