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>
52 lines
2.3 KiB
TypeScript
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,
|
|
});
|
|
});
|