mirror of
https://github.com/escalante29/WealthySmart.git
synced 2026-07-17 12:08:47 +02:00
114 lines
4.3 KiB
TypeScript
114 lines
4.3 KiB
TypeScript
import { expect, test, type Page } from "@playwright/test";
|
|
|
|
test.setTimeout(150_000);
|
|
|
|
async function startFreshAssistant(page: Page) {
|
|
await page.goto("/login");
|
|
await page.getByLabel("Username").fill(process.env.ADMIN_USERNAME!);
|
|
await page.getByLabel("Password").fill(process.env.ADMIN_PASSWORD!);
|
|
await page.getByRole("button", { name: /sign in/i }).click();
|
|
await page.waitForURL("/");
|
|
|
|
const initialConnect = page.waitForResponse((response) => {
|
|
if (!response.url().includes("/api/copilotkit") || response.request().method() !== "POST") {
|
|
return false;
|
|
}
|
|
try {
|
|
return JSON.parse(response.request().postData() ?? "{}").method === "agent/connect";
|
|
} catch {
|
|
return false;
|
|
}
|
|
});
|
|
await page.goto("/asistente");
|
|
await expect(page.getByRole("heading", { name: "Asistente" })).toBeVisible();
|
|
await (await initialConnect).finished();
|
|
|
|
const newConversation = page.getByRole("button", { name: "Nueva conversación" });
|
|
if (await newConversation.isEnabled()) {
|
|
await newConversation.click();
|
|
const reconnect = page.waitForResponse((response) => {
|
|
if (!response.url().includes("/api/copilotkit") || response.request().method() !== "POST") {
|
|
return false;
|
|
}
|
|
try {
|
|
return JSON.parse(response.request().postData() ?? "{}").method === "agent/connect";
|
|
} catch {
|
|
return false;
|
|
}
|
|
});
|
|
await page.getByRole("button", { name: "Borrar historial" }).click();
|
|
await (await reconnect).finished();
|
|
await expect(
|
|
page.getByRole("textbox", { name: "Escribe tu pregunta…" }),
|
|
).toBeEnabled({ timeout: 30_000 });
|
|
}
|
|
}
|
|
|
|
async function ask(page: Page, question: string, expectedTool: string) {
|
|
// The BFF response is the exact CopilotKit stream consumed by the browser.
|
|
// Checking it catches server-side RUN_ERROR events even if the UI changes.
|
|
const stream = page.waitForResponse(
|
|
(response) => {
|
|
if (
|
|
!response.url().includes("/api/copilotkit") ||
|
|
response.request().method() !== "POST"
|
|
) {
|
|
return false;
|
|
}
|
|
try {
|
|
return JSON.parse(response.request().postData() ?? "{}").method === "agent/run";
|
|
} catch {
|
|
return false;
|
|
}
|
|
},
|
|
);
|
|
const composer = page.getByRole("textbox", { name: "Escribe tu pregunta…" });
|
|
await expect(composer).toBeEnabled({ timeout: 30_000 });
|
|
await composer.fill(question);
|
|
const sendButton = page.getByTestId("copilot-send-button");
|
|
await expect(sendButton).toBeEnabled({ timeout: 30_000 });
|
|
await sendButton.click();
|
|
await expect(page.getByText(question, { exact: true }).last()).toBeVisible();
|
|
|
|
const response = await stream;
|
|
await response.finished();
|
|
const events = await response.text();
|
|
expect(events).not.toContain("RUN_ERROR");
|
|
expect(events).toContain(expectedTool);
|
|
|
|
// The HTTP stream may finish before CopilotKit has committed the tool run
|
|
// and released its client-side running state. Waiting for the page action
|
|
// avoids losing the next Enter keypress during that short interval.
|
|
await expect(page.getByRole("button", { name: "Nueva conversación" })).toBeEnabled({
|
|
timeout: 30_000,
|
|
});
|
|
}
|
|
|
|
test("Asistente completes Luna's read-only tool flows", async ({ page }) => {
|
|
const consoleErrors: string[] = [];
|
|
page.on("console", (message) => {
|
|
if (message.type() === "error") consoleErrors.push(message.text());
|
|
});
|
|
|
|
await startFreshAssistant(page);
|
|
|
|
await ask(page, "What date is it today?", "get_current_date");
|
|
await ask(page, "List my last 10 transactions.", "get_recent_transactions");
|
|
await ask(page, "What is my net worth?", "get_net_worth");
|
|
await ask(page, "How much did I spend today?", "get_daily_spending");
|
|
await ask(page, "Show my spending by category this month.", "render_spending_summary");
|
|
|
|
const spendingCard = page.getByTestId("spending-summary-card");
|
|
await expect(spendingCard).toBeVisible({ timeout: 30_000 });
|
|
await expect(page.getByRole("textbox", { name: "Escribe tu pregunta…" })).toBeEnabled({
|
|
timeout: 30_000,
|
|
});
|
|
|
|
await page.reload();
|
|
await expect(page.getByRole("heading", { name: "Asistente" })).toBeVisible();
|
|
await expect(page.getByText("Show my spending by category this month.", { exact: true })).toBeVisible();
|
|
await expect(page.getByTestId("spending-summary-card")).toBeVisible();
|
|
|
|
expect(consoleErrors.join("\n")).not.toContain("ChatClientException");
|
|
});
|