import { test, expect } from "@playwright/test"; import { E2E_ADMIN, FIXED_CAPTCHA } from "../fixtures/test-users"; 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 }); } async function createDocViaAPI( request: import("@playwright/test").APIRequestContext, body: Record, ) { const res = await request.post("/api/agent-documents", { data: body }); return res; } test.describe("Agent 文档", () => { test("列表页可访问(空状态)", async ({ page, request }) => { await loginViaUI(page); await page.goto("/agent-documents"); await expect(page.locator(".agent-documents-page")).toBeVisible({ timeout: 10000 }); }); test("通过 API 创建文档后列表显示", async ({ page, request }) => { await loginViaUI(page); const title = `E2E测试文档_${Date.now()}`; const res = await createDocViaAPI(request, { title, content: "## 测试内容\n这是一个E2E测试创建的文档。", type: "document", tags: ["e2e", "test"], }); expect(res.ok()).toBeTruthy(); const json = await res.json(); expect(json.code).toBe(0); const docId = json.data.id; await page.goto("/agent-documents"); await expect(page.locator(".document-card").first()).toBeVisible({ timeout: 10000 }); await expect(page.locator(".document-card").first()).toContainText(title); await request.delete(`/api/agent-documents/${docId}`); }); test("详情页显示文档内容", async ({ page, request }) => { await loginViaUI(page); const title = `E2E详情测试_${Date.now()}`; const content = "## 详情页测试\nMarkdown渲染验证。"; const res = await createDocViaAPI(request, { title, content, type: "document", tags: ["detail"], }); const json = await res.json(); const docId = json.data.id; await page.goto(`/agent-documents/${docId}`); await expect(page.locator(".detail-title")).toContainText(title, { timeout: 10000 }); await expect(page.locator(".detail-content")).toBeVisible(); await request.delete(`/api/agent-documents/${docId}`); }); test("类型筛选工作正常", async ({ page, request }) => { await loginViaUI(page); const docRes = await createDocViaAPI(request, { title: `E2E文档类型_${Date.now()}`, content: "文档类型测试", type: "document", }); const memRes = await createDocViaAPI(request, { title: `E2E记忆类型_${Date.now()}`, content: "记忆类型测试", type: "memory", }); const docId = (await docRes.json()).data.id; const memId = (await memRes.json()).data.id; await page.goto("/agent-documents"); await page.click(".filter-tab", { text: "文档" }); await page.waitForTimeout(500); const docCards = page.locator(".document-card"); const count1 = await docCards.count(); expect(count1).toBeGreaterThan(0); for (let i = 0; i < count1; i++) { await expect(docCards.nth(i).locator(".type-badge")).toHaveClass(/document/); } await page.click(".filter-tab", { text: "记忆" }); await page.waitForTimeout(500); const memCards = page.locator(".document-card"); const count2 = await memCards.count(); expect(count2).toBeGreaterThan(0); for (let i = 0; i < count2; i++) { await expect(memCards.nth(i).locator(".type-badge")).toHaveClass(/memory/); } await request.delete(`/api/agent-documents/${docId}`); await request.delete(`/api/agent-documents/${memId}`); }); test("关键词搜索工作正常", async ({ page, request }) => { await loginViaUI(page); const unique = `E2E搜索关键词_${Date.now()}`; const res = await createDocViaAPI(request, { title: unique, content: "搜索测试内容", type: "document", }); const docId = (await res.json()).data.id; await page.goto("/agent-documents"); await page.fill(".search-input", unique); await page.waitForTimeout(600); const cards = page.locator(".document-card"); await expect(cards.first()).toBeVisible({ timeout: 10000 }); const count = await cards.count(); expect(count).toBeGreaterThanOrEqual(1); await expect(cards.first()).toContainText(unique); await request.delete(`/api/agent-documents/${docId}`); }); test("详情页编辑文档", async ({ page, request }) => { await loginViaUI(page); const res = await createDocViaAPI(request, { title: `E2E编辑前_${Date.now()}`, content: "编辑前内容", type: "document", }); const docId = (await res.json()).data.id; await page.goto(`/agent-documents/${docId}`); await page.click("button.action-btn", { text: "编辑" }); await expect(page.locator(".form-dialog")).toBeVisible({ timeout: 5000 }); await page.fill(".form-input", `E2E编辑后_${Date.now()}`); await page.click("button.btn-save"); await expect(page.locator(".Toastify__toast").first()).toBeVisible({ timeout: 10000 }); await page.waitForTimeout(500); await request.delete(`/api/agent-documents/${docId}`); }); test("详情页删除文档", async ({ page, request }) => { await loginViaUI(page); const res = await createDocViaAPI(request, { title: `E2E删除测试_${Date.now()}`, content: "待删除", type: "document", }); const docId = (await res.json()).data.id; await page.goto(`/agent-documents/${docId}`); await page.click("button.action-btn.danger"); await expect(page.locator(".confirm-dialog")).toBeVisible({ timeout: 5000 }); await page.click(".confirm-dialog .btn-save.danger"); await expect(page).toHaveURL(/\/agent-documents$/, { timeout: 10000 }); }); test("未登录访问列表页重定向到登录", async ({ page }) => { await page.goto("/agent-documents"); await expect(page).toHaveURL(/\/auth\/login/); }); test("未登录 API 返回 401", async ({ request }) => { const res = await request.get("/api/agent-documents"); expect(res.status()).toBe(401); }); test("导航栏包含文档入口", async ({ page }) => { await loginViaUI(page); await page.goto("/"); const docLink = page.locator(".nav-links a", { hasText: "文档" }); await expect(docLink).toBeVisible({ timeout: 10000 }); }); });