import { expect } from "@playwright/test"; import { test } from "../fixtures"; import { registerAndLogin, createList, createMealWithIngredients } from "../helpers"; test("a user can add a meal's ingredients to a list via the picker", async ({ page }) => { await registerAndLogin(page, "alice@example.com"); await createMealWithIngredients(page, "Spaghetti Bolognese", [ { name: "Penne", quantity: "500g" }, { name: "Tomato", quantity: "2" }, ]); await createList(page, "Weekly shop"); // Open the add-meal picker. await page.click(".add-meal-button"); const picker = page.locator(".meal-picker-backdrop"); await expect(picker).toBeVisible(); await expect(picker.locator(".meal-picker-button").filter({ hasText: "Spaghetti Bolognese" })).toBeVisible(); // Select the meal. await picker.locator(".meal-picker-button").filter({ hasText: "Spaghetti Bolognese" }).click(); // The picker closes and the meal's ingredients appear as items. await expect(picker).toHaveCount(0); await expect(page.locator(".item-row").filter({ hasText: "Penne" })).toBeVisible(); await expect(page.locator(".item-row").filter({ hasText: "Tomato" })).toBeVisible(); await expect(page.locator(".item-row").filter({ hasText: "Penne" }).locator(".item-qty")).toHaveText("(500g)"); }); test("the add-meal picker closes via the close button", async ({ page }) => { await registerAndLogin(page, "alice@example.com"); await createMealWithIngredients(page, "Spaghetti Bolognese", [{ name: "Penne" }]); await createList(page, "Weekly shop"); await page.click(".add-meal-button"); const picker = page.locator(".meal-picker-backdrop"); await expect(picker).toBeVisible(); await picker.locator(".meal-picker-close").click(); await expect(picker).toHaveCount(0); }); test("the add-meal picker closes when clicking outside", async ({ page }) => { await registerAndLogin(page, "alice@example.com"); await createMealWithIngredients(page, "Spaghetti Bolognese", [{ name: "Penne" }]); await createList(page, "Weekly shop"); await page.click(".add-meal-button"); const picker = page.locator(".meal-picker-backdrop"); await expect(picker).toBeVisible(); // Click the backdrop itself (outside the modal card), at the viewport corner. await page.mouse.click(10, 10); await expect(picker).toHaveCount(0); }); test("a meal added to a list is shown in the meals panel", async ({ page }) => { await registerAndLogin(page, "alice@example.com"); await createMealWithIngredients(page, "Spaghetti Bolognese", [ { name: "Penne", quantity: "500g" }, { name: "Tomato", quantity: "2" }, ]); await createList(page, "Weekly shop"); await page.click(".add-meal-button"); const picker = page.locator(".meal-picker-backdrop"); await picker.locator(".meal-picker-button").filter({ hasText: "Spaghetti Bolognese" }).click(); // The meal appears in the "Meals on this list" panel. const panel = page.locator("#list-meals-panel"); await expect(panel).toBeVisible(); await expect(panel.locator(".list-meal-row").filter({ hasText: "Spaghetti Bolognese" })).toBeVisible(); }); test("removing a meal from a list removes its ingredients", async ({ page }) => { await registerAndLogin(page, "alice@example.com"); await createMealWithIngredients(page, "Spaghetti Bolognese", [ { name: "Penne", quantity: "500g" }, { name: "Tomato", quantity: "2" }, ]); await createList(page, "Weekly shop"); await page.click(".add-meal-button"); const picker = page.locator(".meal-picker-backdrop"); await picker.locator(".meal-picker-button").filter({ hasText: "Spaghetti Bolognese" }).click(); await expect(page.locator(".item-row").filter({ hasText: "Penne" })).toBeVisible(); await expect(page.locator(".item-row").filter({ hasText: "Tomato" })).toBeVisible(); // Remove the meal from the list. const panel = page.locator("#list-meals-panel"); const row = panel.locator(".list-meal-row").filter({ hasText: "Spaghetti Bolognese" }); await row.locator(".list-meal-remove-button").click(); // The meal's ingredients are removed from the list. await expect(page.locator(".item-row").filter({ hasText: "Penne" })).toHaveCount(0); await expect(page.locator(".item-row").filter({ hasText: "Tomato" })).toHaveCount(0); await expect(row).toHaveCount(0); }); test("a meal can be checked off without removing it from the list", async ({ page }) => { await registerAndLogin(page, "alice@example.com"); await createMealWithIngredients(page, "Spaghetti Bolognese", [{ name: "Penne" }]); await createList(page, "Weekly shop"); await page.click(".add-meal-button"); const picker = page.locator(".meal-picker-backdrop"); await picker.locator(".meal-picker-button").filter({ hasText: "Spaghetti Bolognese" }).click(); const panel = page.locator("#list-meals-panel"); const row = panel.locator(".list-meal-row").filter({ hasText: "Spaghetti Bolognese" }); await expect(row).toBeVisible(); await expect(row.locator(".list-meal-check-button")).not.toHaveClass(/is-.*checked/); // Check the meal off as eaten. await row.locator(".list-meal-check-button").click(); await expect(row).toHaveClass(/is-checked/); await expect(row.locator(".list-meal-check-button")).toHaveText("✓"); // The meal is still on the list, not removed. await expect(row).toBeVisible(); await expect(page.locator(".item-row").filter({ hasText: "Penne" })).toBeVisible(); // Unchecking restores it. await row.locator(".list-meal-check-button").click(); await expect(row).not.toHaveClass(/is-checked/); await expect(row).toBeVisible(); });