import { type DataTable, Given, Then, When } from "@badeball/cypress-cucumber-preprocessor"; /** * One data-table row → a fake `ShoppingListItemView` — same minimal-fixture * convention as `recipe-form.ts`'s ingredient fixtures (only the fields * `ShoppingListPage` actually reads at runtime: the ingredient's `key`/ * `icon`/`category` for `IngredientTypeIcon`/`CategoryIcon`/translation, the * unit's `key`; `id` only needs to be unique per row for the React list * key). `index` seeds both ids so two rows never collide. */ function buildShoppingListItem( row: { ingredientKey: string; icon: string; category: string; quantity: string; unitKey: string }, index: number, ) { return { ingredient: { id: index, key: row.ingredientKey, icon: row.icon, category: row.category, subcategory: row.category, reproducible: false, allergens: [], diets: [], }, quantity: Number(row.quantity), unit: { id: index, key: row.unitKey, type: "MASS", toBaseFactor: 1 }, }; } Given("the shopping list for {string} is empty", (date: string) => { cy.intercept("GET", `**/shopping-list?date=${date}`, { statusCode: 200, body: { startDate: date, finishDate: date, items: [] }, }); }); Given("the shopping list for {string} contains:", (date: string, dataTable: DataTable) => { const items = dataTable.hashes().map((row, i) => buildShoppingListItem(row, i + 1)); cy.intercept("GET", `**/shopping-list?date=${date}`, { statusCode: 200, body: { startDate: date, finishDate: date, items }, }); }); // Same class as PlanningPage's own week navigator (`WeekNavigator`, now // shared between the two pages) — `planning-page.cy.ts` already exercises // the prev/next arrows directly by class, same approach here. When("I click the next week arrow", () => { cy.get(".week-nav__arrow").last().click(); }); Then( "the shopping list group {string} should appear before {string}", (first: string, second: string) => { cy.get(".shopping-list__group-title").then(($titles) => { const texts = [...$titles].map((el) => el.textContent?.trim() ?? ""); const firstIndex = texts.findIndex((text) => text.includes(first)); const secondIndex = texts.findIndex((text) => text.includes(second)); expect(firstIndex, `"${first}" should be a rendered group`).to.be.greaterThan(-1); expect(secondIndex, `"${second}" should be a rendered group`).to.be.greaterThan(-1); expect(firstIndex).to.be.lessThan(secondIndex); }); }, ); Then( "the shopping list should show {string} at quantity {string}", (name: string, quantity: string) => { cy.contains(".shopping-list__item", name).should("contain.text", quantity); }, );