evOo-local/apps/web/e2e/recipe-card.spec.ts
2026-10-05 01:13:52 +02:00

72 lines
3.2 KiB
TypeScript

import { expect, type Page, test } from "@playwright/test";
import { captureScreenshot, completeOnboarding, openUserSettings, signup } from "./helpers";
async function useAppearance(page: Page, appearance: "light" | "dark") {
const settings = await openUserSettings(page);
await settings.getByTestId(`ui-appearance-${appearance}`).click();
await expect(page.locator("html")).toHaveAttribute("data-theme", appearance);
await settings.getByRole("button", { name: "Close user settings" }).click();
await expect(settings).toBeHidden();
}
test("a recipe card scales its ingredients and cooks step by step", async ({ page }, testInfo) => {
const stamp = Date.now();
await signup(page, `recipe-card-${stamp}@rakazo.test`, "password12", "Recipe Card");
await completeOnboarding(page);
await page.getByPlaceholder(/Message/).fill("Give me a pancake recipe.");
await page.keyboard.press("Enter");
const card = page.getByTestId("thread-card");
await expect(card).toBeVisible({ timeout: 60_000 });
await expect(card).toContainText("200 g");
await expect(card).toContainText("1 Egg");
await card.getByRole("button", { name: "More Servings" }).click();
await expect(card.getByTestId("card-stepper-value")).toHaveText("3");
await expect(card).toContainText("300 g");
await expect(card).toContainText("1½ Eggs");
await expect(card).toContainText("450 ml");
await useAppearance(page, "light");
await card.scrollIntoViewIfNeeded();
await captureScreenshot(page, testInfo, "recipe-card-light");
await useAppearance(page, "dark");
await card.scrollIntoViewIfNeeded();
await captureScreenshot(page, testInfo, "recipe-card-dark");
await card.getByRole("button", { name: "Cook" }).click();
const cooking = page.getByTestId("cooking-mode");
await expect(cooking).toContainText("Step 1 of 3");
await cooking.getByRole("button", { name: "Next" }).click();
await expect(cooking).toContainText("Step 2 of 3");
await expect(cooking).toContainText("Let the batter rest.");
await cooking.getByRole("button", { name: "Start timer" }).click();
await expect(cooking.getByRole("button", { name: "Stop timer" })).toContainText(/9:5\d/, {
timeout: 10_000,
});
await captureScreenshot(page, testInfo, "cooking-mode-dark");
await closeCookingMode(page);
await useAppearance(page, "light");
await card.getByRole("button", { name: "Cook" }).click();
await expect(cooking).toContainText("Step 2 of 3");
await captureScreenshot(page, testInfo, "cooking-mode-light");
await closeCookingMode(page);
// Servings, step and timer are stored on the card, so a reload keeps them.
await page.reload({ waitUntil: "domcontentloaded" });
const reloaded = page.getByTestId("thread-card");
await expect(reloaded.getByTestId("card-stepper-value")).toHaveText("3", { timeout: 30_000 });
await expect(reloaded).toContainText(/9:[45]\d/);
await reloaded.getByRole("button", { name: "Cook" }).click();
await expect(page.getByTestId("cooking-mode")).toContainText("Step 2 of 3");
await expect(
page.getByTestId("cooking-mode").getByRole("button", { name: "Stop timer" }),
).toBeVisible();
});
async function closeCookingMode(page: Page) {
await page.keyboard.press("Escape");
await expect(page.getByTestId("cooking-mode")).toBeHidden();
}