evOo-local/apps/web/e2e/suggestion-card.spec.ts
cynarAI 6fd136e944
feat: suggestions the user accepts or dismisses with one tap (#142)
Bots can offer an exact tool call as a card. Nothing runs until the user
taps Accept; the call then runs as its own approved run of the bot it was
meant for, and the card shows the outcome. Open suggestions also wait in
the inbox and expire after a week.


Claude-Session: https://claude.ai/code/session_01UmSCnoCgXqBp2fU3vwz4o1

Co-authored-by: Claude <noreply@anthropic.com>
2026-10-05 02:19:31 +02:00

52 lines
2.3 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 bot's suggestion runs only when the user accepts it", async ({ page }, testInfo) => {
const stamp = Date.now();
await signup(page, `suggestion-card-${stamp}@rakazo.test`, "password12", "Suggestion Card");
await completeOnboarding(page);
await page.getByPlaceholder(/Message/).fill("I should move more.");
await page.keyboard.press("Enter");
const card = page.getByTestId("thread-card");
await expect(card).toBeVisible({ timeout: 60_000 });
await expect(card).toContainText("Set up a routine");
await expect(card).toContainText("Morning walk");
await expect(card).toContainText("A nudge each morning makes it a habit.");
// Nothing ran yet.
await expect(page.getByTestId("routine-event-line")).toHaveCount(0);
await useAppearance(page, "light");
await card.scrollIntoViewIfNeeded();
await captureScreenshot(page, testInfo, "suggestion-card-light");
await useAppearance(page, "dark");
await card.scrollIntoViewIfNeeded();
await captureScreenshot(page, testInfo, "suggestion-card-dark");
await card.getByRole("button", { name: "Accept" }).click();
await expect(card.getByTestId("card-suggestion-status")).toContainText("Done", {
timeout: 60_000,
});
await expect(card.getByRole("button", { name: "Accept" })).toHaveCount(0);
const line = page.getByTestId("routine-event-line");
await expect(line).toBeVisible({ timeout: 30_000 });
await expect(line).toContainText("Morning walk");
await card.scrollIntoViewIfNeeded();
await captureScreenshot(page, testInfo, "suggestion-card-done-dark");
// The outcome is stored on the card, so a reload keeps it.
await page.reload({ waitUntil: "domcontentloaded" });
await expect(page.getByTestId("card-suggestion-status")).toContainText("Done", {
timeout: 30_000,
});
});