You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

211 lines
7.3 KiB

import { test, expect } from "@playwright/test";
import { readFileSync } from "node:fs";
import { E2E_ADMIN, FIXED_CAPTCHA } from "../fixtures/test-users";
const MOCK_REPLY = "你好!这是一个测试回复。";
function getLastSystemPrompt(): string {
try {
return readFileSync("/tmp/e2e-last-system-prompt.txt", "utf-8");
} catch {
return "";
}
}
async function loginViaUI(page: import("@playwright/test").Page) {
await page.goto("/auth/login");
await page.fill("#login-username", E2E_ADMIN.username);
await page.fill("#login-password", E2E_ADMIN.password);
await page.fill("#login-captcha", FIXED_CAPTCHA);
await page.click('button[type="submit"]');
await page.waitForURL("/", { timeout: 15000 });
await expect(page.locator(".agent-textarea")).toBeVisible({ timeout: 10000 });
await page.waitForTimeout(1000);
const newChatBtn = page.locator(".new-chat-btn").first();
if (await newChatBtn.isVisible()) {
await newChatBtn.click();
await page.waitForTimeout(500);
}
}
test.describe("Agent 对话", () => {
test("首页显示欢迎页和示例卡片", async ({ page }) => {
await loginViaUI(page);
await expect(page.locator(".agent-welcome")).toBeVisible({ timeout: 10000 });
await expect(page.locator(".welcome-title")).toContainText("有什么可以帮你的");
await expect(page.locator(".example-card")).toHaveCount(4);
});
test("输入框和发送按钮存在", async ({ page }) => {
await loginViaUI(page);
await expect(page.locator(".agent-textarea")).toBeVisible({ timeout: 10000 });
await expect(page.locator(".btn-send")).toBeVisible();
});
test("空消息时发送按钮禁用", async ({ page }) => {
await loginViaUI(page);
const sendBtn = page.locator(".btn-send");
await expect(sendBtn).toBeDisabled();
});
test("输入内容后发送按钮启用", async ({ page }) => {
await loginViaUI(page);
await page.fill(".agent-textarea", "测试消息");
await expect(page.locator(".btn-send")).toBeEnabled();
});
test("点击示例卡片直接发送消息", async ({ page }) => {
await loginViaUI(page);
const firstExample = page.locator(".example-card").first();
const exampleText = await firstExample.innerText();
await firstExample.click();
await expect(page.locator(".agent-message.is-user .user-bubble")).toContainText(exampleText, { timeout: 10000 });
});
test("发送消息后显示用户消息和助手回复", async ({ page }) => {
await loginViaUI(page);
const testMessage = "你好,这是一条测试消息";
await page.fill(".agent-textarea", testMessage);
await page.click(".btn-send");
await expect(page.locator(".agent-message.is-user .user-bubble")).toContainText(testMessage, { timeout: 10000 });
await expect(page.locator(".agent-message.is-assistant")).toBeVisible({ timeout: 10000 });
await expect(
page.locator(".agent-message.is-assistant .agent-markdown"),
).toContainText(MOCK_REPLY, { timeout: 30000 });
});
test("发送消息后显示加载动画", async ({ page }) => {
await loginViaUI(page);
await page.fill(".agent-textarea", "测试加载状态");
await page.click(".btn-send");
await expect(page.locator(".assistant-loading")).toBeVisible({ timeout: 5000 });
});
test("Enter 键发送消息", async ({ page }) => {
await loginViaUI(page);
const testMessage = "通过回车发送";
await page.fill(".agent-textarea", testMessage);
await page.press(".agent-textarea", "Enter");
await expect(page.locator(".agent-message.is-user .user-bubble")).toContainText(testMessage, { timeout: 10000 });
});
test("流式响应完成后消息内容完整", async ({ page }) => {
await loginViaUI(page);
await page.fill(".agent-textarea", "请回复");
await page.click(".btn-send");
await expect(
page.locator(".agent-message.is-assistant .agent-markdown"),
).toContainText(MOCK_REPLY, { timeout: 30000 });
await expect(page.locator(".btn-stop")).not.toBeVisible({ timeout: 15000 });
await expect(page.locator(".btn-send")).toBeVisible();
});
test("连续对话保留历史消息", async ({ page }) => {
await loginViaUI(page);
const firstMsg = "第一条消息";
await page.fill(".agent-textarea", firstMsg);
await page.click(".btn-send");
await expect(page.locator(".agent-message.is-user .user-bubble").first()).toContainText(firstMsg, { timeout: 10000 });
await expect(
page.locator(".agent-message.is-assistant .agent-markdown").first(),
).toContainText(MOCK_REPLY, { timeout: 30000 });
const secondMsg = "第二条消息";
await page.fill(".agent-textarea", secondMsg);
await page.click(".btn-send");
await expect(page.locator(".agent-message.is-user")).toHaveCount(2, { timeout: 10000 });
await expect(page.locator(".agent-message.is-assistant")).toHaveCount(2, { timeout: 30000 });
});
test("修改系统提示词后发送消息使用自定义提示词", async ({ page }) => {
await loginViaUI(page);
const createBody = await page.evaluate(async () => {
const res = await fetch("/api/agents/default/sessions", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ systemPrompt: "You are a pirate. Always respond in pirate speak." }),
});
return res.json();
});
const sessionId = createBody.data.id;
await page.goto(`/chat/default?session=${sessionId}`);
await page.waitForTimeout(1000);
const newChatBtn = page.locator(".new-chat-btn").first();
if (await newChatBtn.isVisible()) {
await newChatBtn.click();
await page.waitForTimeout(500);
}
await page.fill(".agent-textarea", "hello");
await page.click(".btn-send");
await expect(
page.locator(".agent-message.is-assistant .agent-markdown").first(),
).toContainText(MOCK_REPLY, { timeout: 30000 });
const lastPrompt = getLastSystemPrompt();
expect(lastPrompt).toBe("You are a pirate. Always respond in pirate speak.");
});
test("重置系统提示词后回退到 Agent 默认", async ({ page }) => {
await loginViaUI(page);
const createBody = await page.evaluate(async () => {
const res = await fetch("/api/agents/default/sessions", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ systemPrompt: "temporary custom prompt" }),
});
return res.json();
});
const sessionId = createBody.data.id;
await page.evaluate(async (id) => {
await fetch(`/api/agents/default/sessions/${id}/config`, {
method: "PUT",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ systemPrompt: null }),
});
}, sessionId);
await page.goto(`/chat/default?session=${sessionId}`);
await page.waitForTimeout(1000);
const newChatBtn = page.locator(".new-chat-btn").first();
if (await newChatBtn.isVisible()) {
await newChatBtn.click();
await page.waitForTimeout(500);
}
await page.fill(".agent-textarea", "hello again");
await page.click(".btn-send");
await expect(
page.locator(".agent-message.is-assistant .agent-markdown").first(),
).toContainText(MOCK_REPLY, { timeout: 30000 });
const lastPrompt = getLastSystemPrompt();
expect(lastPrompt).toBe("You are a helpful AI assistant.");
});
});