The autopilot's start line counts its steps and folds open to the latest checkpoints, and its result reads as a card. The composer's plus menu starts an autopilot with the draft as the order and a choice of until done, tomorrow morning or a time. Today lists the autopilots that run, wait or ended within a day, and their step runs no longer show one by one. Autopilot runs send no completion or failure push; only a pause notifies. Claude-Session: https://claude.ai/code/session_01UmSCnoCgXqBp2fU3vwz4o1 Co-authored-by: Claude <noreply@anthropic.com>
111 lines
5.5 KiB
TypeScript
111 lines
5.5 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("the autopilot works step by step until the order is done", async ({ page }, testInfo) => {
|
|
const stamp = Date.now();
|
|
await signup(page, `autopilot-${stamp}@rakazo.test`, "password12", "Autopilot");
|
|
await completeOnboarding(page);
|
|
|
|
await page.getByPlaceholder(/Message/).fill("Work through the night on the tickets.");
|
|
await page.keyboard.press("Enter");
|
|
|
|
const start = page.locator('[data-testid="autopilot-line"][data-event="autopilot.started"]');
|
|
await expect(start).toBeVisible({ timeout: 60_000 });
|
|
await expect(start).toContainText("Tidy up the tickets");
|
|
await expect(start).toContainText("Only tidy, change nothing else");
|
|
|
|
const finished = page.locator('[data-testid="autopilot-line"][data-event="autopilot.finished"]');
|
|
await expect(finished).toBeVisible({ timeout: 120_000 });
|
|
await expect(finished).toContainText("Tidied 5 tickets; nothing waits on you.");
|
|
// Once it is over, the start line has no Stop any more.
|
|
await expect(start.getByRole("button", { name: "Stop" })).toHaveCount(0);
|
|
|
|
await useAppearance(page, "light");
|
|
await finished.scrollIntoViewIfNeeded();
|
|
await captureScreenshot(page, testInfo, "autopilot-finished-light");
|
|
await useAppearance(page, "dark");
|
|
await finished.scrollIntoViewIfNeeded();
|
|
await captureScreenshot(page, testInfo, "autopilot-finished-dark");
|
|
});
|
|
|
|
test("an autopilot without progress pauses and stops on request", async ({ page }, testInfo) => {
|
|
const stamp = Date.now();
|
|
await signup(page, `autopilot-idle-${stamp}@rakazo.test`, "password12", "Autopilot Idle");
|
|
await completeOnboarding(page);
|
|
|
|
await page.getByPlaceholder(/Message/).fill("Work through the night, idle check.");
|
|
await page.keyboard.press("Enter");
|
|
|
|
const paused = page.locator('[data-testid="autopilot-line"][data-event="autopilot.paused"]');
|
|
await expect(paused).toBeVisible({ timeout: 120_000 });
|
|
await expect(paused).toContainText("No progress in 3 runs");
|
|
await expect(paused.getByRole("button", { name: "Continue" })).toBeVisible();
|
|
await useAppearance(page, "dark");
|
|
await paused.scrollIntoViewIfNeeded();
|
|
await captureScreenshot(page, testInfo, "autopilot-paused-dark");
|
|
|
|
await paused.getByRole("button", { name: "Stop" }).click();
|
|
const stopped = page.locator('[data-testid="autopilot-line"][data-event="autopilot.stopped"]');
|
|
await expect(stopped).toBeVisible({ timeout: 30_000 });
|
|
await expect(paused.getByRole("button", { name: "Continue" })).toHaveCount(0);
|
|
await useAppearance(page, "light");
|
|
await stopped.scrollIntoViewIfNeeded();
|
|
await captureScreenshot(page, testInfo, "autopilot-paused-light");
|
|
});
|
|
|
|
test("an autopilot started from the composer works overnight and reports in Today", async ({
|
|
page,
|
|
}, testInfo) => {
|
|
const stamp = Date.now();
|
|
await signup(page, `autopilot-night-${stamp}@rakazo.test`, "password12", "Autopilot Night");
|
|
await completeOnboarding(page);
|
|
|
|
await page.getByPlaceholder(/Message/).fill("Tidy the tickets");
|
|
await page.getByRole("button", { name: "Add" }).click();
|
|
await page.getByRole("menuitem", { name: "Autopilot" }).click();
|
|
const dialog = page.getByTestId("autopilot-dialog");
|
|
await expect(dialog.getByRole("textbox", { name: "Order" })).toHaveValue("Tidy the tickets");
|
|
await dialog.getByRole("radio", { name: "Until tomorrow morning" }).click();
|
|
await dialog.getByRole("button", { name: "Start" }).click();
|
|
await expect(dialog).toBeHidden();
|
|
await expect(page.getByPlaceholder(/Message/)).toHaveValue("");
|
|
|
|
const start = page.locator('[data-testid="autopilot-line"][data-event="autopilot.started"]');
|
|
await expect(start).toContainText("Tidy the tickets", { timeout: 60_000 });
|
|
await expect(start).toContainText(/until 8:00/);
|
|
const finished = page.locator('[data-testid="autopilot-line"][data-event="autopilot.finished"]');
|
|
await expect(finished).toBeVisible({ timeout: 120_000 });
|
|
await expect(finished.getByTestId("autopilot-result")).toHaveText(
|
|
"Tidied 5 tickets; nothing waits on you.",
|
|
);
|
|
await start.getByRole("button", { name: "5 steps" }).click();
|
|
await expect(start.getByTestId("autopilot-steps").locator("li")).toHaveCount(5);
|
|
await expect(start.getByTestId("autopilot-steps")).toContainText("Ticket 5 tidied");
|
|
|
|
await useAppearance(page, "light");
|
|
await start.scrollIntoViewIfNeeded();
|
|
await captureScreenshot(page, testInfo, "autopilot-night-light");
|
|
await useAppearance(page, "dark");
|
|
await start.scrollIntoViewIfNeeded();
|
|
await captureScreenshot(page, testInfo, "autopilot-night-dark");
|
|
|
|
// The morning summary: what the autopilot did, in Today.
|
|
await page.getByRole("button", { name: "Today", exact: true }).click();
|
|
const row = page.getByTestId("heute-autopilot-row");
|
|
await expect(row).toHaveAttribute("data-status", "finished", { timeout: 30_000 });
|
|
await expect(row).toContainText("Tidy the tickets");
|
|
await expect(row).toContainText("Tidied 5 tickets; nothing waits on you.");
|
|
await expect(row).toContainText("5 steps");
|
|
await captureScreenshot(page, testInfo, "autopilot-today-dark");
|
|
await row.click();
|
|
await expect(start).toBeVisible();
|
|
});
|