Files
sustenance/e2e/tests/meal-categories.spec.ts
sbstp 3695fc68d6
ci/woodpecker/push/e2e Pipeline was successful
ci/woodpecker/push/fmt Pipeline failed
ci/woodpecker/push/test Pipeline was successful
meal categories
2026-08-03 21:29:33 -04:00

112 lines
4.9 KiB
TypeScript

import { expect } from "@playwright/test";
import { test } from "../fixtures";
import { registerAndLogin, createMeal } from "../helpers";
test("meals are grouped under their category on the meals page", async ({ page }) => {
await registerAndLogin(page, "alice@example.com");
await createMeal(page, "Beef Stew", "", "Beef");
await createMeal(page, "Chicken Curry", "", "Chicken");
await createMeal(page, "Plain Rice", "");
await page.goto("/meals");
// Each category appears as a heading with its meals beneath it.
const beef = page.locator(".category-group").filter({ hasText: "Beef" });
await expect(beef.locator(".category-heading")).toContainText("Beef");
await expect(beef.locator(".list-card").filter({ hasText: "Beef Stew" })).toBeVisible();
const chicken = page.locator(".category-group").filter({ hasText: "Chicken" });
await expect(chicken.locator(".list-card").filter({ hasText: "Chicken Curry" })).toBeVisible();
// Uncategorized meals land in their own group.
const uncategorized = page.locator(".category-group").filter({ hasText: "Uncategorized" });
await expect(uncategorized.locator(".list-card").filter({ hasText: "Plain Rice" })).toBeVisible();
});
test("a user can create a meal category", async ({ page }) => {
await registerAndLogin(page, "alice@example.com");
await page.goto("/meals");
await page.fill('form[action="/meals/categories"] input[name="name"]', "Breakfast");
await page.click('form[action="/meals/categories"] button[type="submit"]');
await expect(page).toHaveURL(/\/meals$/);
await expect(page.locator(".meal-category-name").filter({ hasText: "Breakfast" })).toBeVisible();
});
test("a user can delete a meal category and its meals become uncategorized", async ({ page }) => {
await registerAndLogin(page, "alice@example.com");
// Create a custom category and a meal in it.
await page.goto("/meals");
await page.fill('form[action="/meals/categories"] input[name="name"]', "Breakfast");
await page.click('form[action="/meals/categories"] button[type="submit"]');
await expect(page).toHaveURL(/\/meals$/);
await createMeal(page, "Pancakes", "", "Breakfast");
// Delete the category.
await page.goto("/meals");
const row = page.locator(".meal-category-row").filter({ hasText: "Breakfast" });
await row.locator(".meal-category-delete").click();
await expect(page).toHaveURL(/\/meals$/);
// The category is gone and the meal is now uncategorized.
await expect(page.locator(".meal-category-name").filter({ hasText: "Breakfast" })).toHaveCount(0);
const uncategorized = page.locator(".category-group").filter({ hasText: "Uncategorized" });
await expect(uncategorized.locator(".list-card").filter({ hasText: "Pancakes" })).toBeVisible();
});
test("a user can change a meal's category via the edit modal", async ({ page }) => {
await registerAndLogin(page, "alice@example.com");
await createMeal(page, "Beef Stew", "", "Beef");
await page.click('button:has-text("Edit")');
const dialog = page.locator("dialog#meal-edit-modal");
await expect(dialog).toBeVisible();
await dialog.locator("#meal-edit-category").selectOption({ label: "Chicken" });
await dialog.locator("#meal-edit-save").click();
await expect(page).toHaveURL(/\/meals\/\d+/);
await page.goto("/meals");
const chicken = page.locator(".category-group").filter({
has: page.locator(".category-heading", { hasText: "Chicken" }),
});
await expect(chicken.locator(".list-card").filter({ hasText: "Beef Stew" })).toBeVisible();
const beef = page.locator(".category-group").filter({
has: page.locator(".category-heading", { hasText: "Beef" }),
});
await expect(beef.locator(".list-card").filter({ hasText: "Beef Stew" })).toHaveCount(0);
});
test("a meal's category is shown on its page", async ({ page }) => {
await registerAndLogin(page, "alice@example.com");
await createMeal(page, "Beef Stew", "", "Beef");
await expect(page.locator(".meal-category-label")).toHaveText("(Beef)");
});
test("the add-meal picker groups meals by category", async ({ page }) => {
await registerAndLogin(page, "alice@example.com");
await createMeal(page, "Beef Stew", "", "Beef");
await createMeal(page, "Chicken Curry", "", "Chicken");
// Go to a list to open the picker.
await page.goto("/lists");
await page.fill("#list-name", "Weekly shop");
await page.click('button:has-text("Create list")');
await expect(page).toHaveURL(/\/lists\/\d+/);
await page.click(".add-meal-button");
const picker = page.locator(".meal-picker-backdrop");
await expect(picker).toBeVisible();
const beef = picker.locator(".category-group").filter({ hasText: "Beef" });
await expect(beef.locator(".meal-picker-button").filter({ hasText: "Beef Stew" })).toBeVisible();
const chicken = picker.locator(".category-group").filter({ hasText: "Chicken" });
await expect(chicken.locator(".meal-picker-button").filter({ hasText: "Chicken Curry" })).toBeVisible();
});