import { test, expect } from "@playwright/test"; import { E2E_ADMIN, FIXED_CAPTCHA } from "../fixtures/test-users"; const MOCK_REPLY = "你好!这是一个测试回复。"; 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 }); }); });