An autopilot per thread continues the user's order run after run, with no time limit. Each run reports a checkpoint; after three runs without progress or three failed runs it pauses with Continue and Stop. Start, pause, stop and finish show as quiet lines in the conversation. Approvals during an autopilot run are parked as suggestions, and the temporary approval rules end with the autopilot. Claude-Session: https://claude.ai/code/session_01UmSCnoCgXqBp2fU3vwz4o1 Co-authored-by: Claude <noreply@anthropic.com>
63 lines
3.1 KiB
TypeScript
63 lines
3.1 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");
|
|
});
|