88 lines
3.7 KiB
TypeScript
88 lines
3.7 KiB
TypeScript
import { expect } from "@playwright/test";
|
|
import { test } from "../fixtures";
|
|
import { registerAndLogin, createMeal, addIngredient } from "../helpers";
|
|
|
|
test("a user can add an ingredient to a meal", async ({ page }) => {
|
|
await registerAndLogin(page, "alice@example.com");
|
|
await createMeal(page, "Spaghetti Bolognese", "");
|
|
|
|
await addIngredient(page, "Penne", "500g");
|
|
|
|
const row = page.locator(".ingredient-list").filter({ hasText: "Penne" });
|
|
await expect(row.locator(".item-qty")).toHaveText("(500g)");
|
|
await expect(row.locator("strong")).toHaveText("Penne");
|
|
});
|
|
|
|
test("a user can edit a meal name and description via the modal", async ({ page }) => {
|
|
await registerAndLogin(page, "alice@example.com");
|
|
await createMeal(page, "Spaghetti Bolognese", "A classic.");
|
|
|
|
await page.click('button:has-text("Edit")');
|
|
const dialog = page.locator("dialog#meal-edit-modal");
|
|
await expect(dialog).toBeVisible();
|
|
await dialog.locator("#meal-edit-name").fill("Pasta al Pomodoro");
|
|
await dialog.locator("#meal-edit-description").fill("## Ingredients\n\nA simple tomato sauce.");
|
|
await dialog.locator("#meal-edit-save").click();
|
|
|
|
await expect(page.locator("h1")).toContainText("Pasta al Pomodoro");
|
|
await expect(page.locator(".markdown h2")).toContainText("Ingredients");
|
|
});
|
|
|
|
test("a user can delete a meal", async ({ page }) => {
|
|
await registerAndLogin(page, "alice@example.com");
|
|
await createMeal(page, "Spaghetti Bolognese", "");
|
|
|
|
page.on("dialog", (dialog) => dialog.accept());
|
|
await page.click('button:has-text("Delete")');
|
|
await expect(page).toHaveURL(/\/meals$/);
|
|
await expect(page.locator(".list-card").filter({ hasText: "Spaghetti Bolognese" })).toHaveCount(0);
|
|
});
|
|
|
|
test("a user can edit an ingredient via the actions modal", async ({ page }) => {
|
|
await registerAndLogin(page, "alice@example.com");
|
|
await createMeal(page, "Spaghetti Bolognese", "");
|
|
await addIngredient(page, "Penne", "500g");
|
|
|
|
const row = page.locator(".ingredient-list").filter({ hasText: "Penne" });
|
|
await row.locator(".item-actions-button").click();
|
|
|
|
const dialog = row.locator("dialog.item-modal");
|
|
await expect(dialog).toBeVisible();
|
|
await dialog.locator('[id^="ingredient-edit-name"]').fill("Rigatoni");
|
|
await dialog.locator('[id^="ingredient-edit-quantity"]').fill("400g");
|
|
await dialog.locator('[id^="ingredient-edit-save"]').click();
|
|
|
|
const updated = page.locator(".ingredient-list").filter({ hasText: "Rigatoni" });
|
|
await expect(updated).toBeVisible();
|
|
await expect(updated.locator(".item-qty")).toHaveText("(400g)");
|
|
});
|
|
|
|
test("a user can delete an ingredient via the actions modal", async ({ page }) => {
|
|
await registerAndLogin(page, "alice@example.com");
|
|
await createMeal(page, "Spaghetti Bolognese", "");
|
|
await addIngredient(page, "Penne");
|
|
|
|
const row = page.locator(".ingredient-list").filter({ hasText: "Penne" });
|
|
await row.locator(".item-actions-button").click();
|
|
|
|
const dialog = row.locator("dialog.item-modal");
|
|
await expect(dialog).toBeVisible();
|
|
await dialog.locator('[id^="ingredient-edit-delete"]').click();
|
|
|
|
await expect(page.locator(".ingredient-list").filter({ hasText: "Penne" })).toHaveCount(0);
|
|
});
|
|
|
|
test("ingredients are grouped under their categories", async ({ page }) => {
|
|
await registerAndLogin(page, "alice@example.com");
|
|
await createMeal(page, "Spaghetti Bolognese", "");
|
|
|
|
// Add an ingredient in the default "Produce" category.
|
|
await addIngredient(page, "Tomato", "", "Produce");
|
|
|
|
// Add one without a category.
|
|
await addIngredient(page, "Penne");
|
|
|
|
await expect(page.locator(".category-heading").filter({ hasText: "Produce" })).toBeVisible();
|
|
await expect(page.locator(".category-heading").filter({ hasText: "Uncategorized" })).toBeVisible();
|
|
});
|