import { test, expect } from "../fixtures"; import { DashboardPage } from "../pages/dashboard.page"; async function hasProjects(page: import("@playwright/test").Page): Promise { // 先导航到 dashboard 页面 await page.goto("/dashboard"); await page.waitForLoadState("networkidle"); const emptyMsg = page.getByText("开始优化您的AI可见性"); const errorTitle = page.getByText("数据加载失败"); const title = page.getByRole("heading", { name: "品牌健康中心" }); const hasTitle = await title.isVisible({ timeout: 15000 }).catch(() => false); if (!hasTitle) return false; const isEmpty = await emptyMsg.isVisible().catch(() => false); const isError = await errorTitle.isVisible().catch(() => false); return !isEmpty && !isError; } test.describe("内容工坊 - 页面加载测试", () => { test("内容工坊页面标题正确显示", async ({ authenticatedPage }) => { await authenticatedPage.goto("/dashboard/content"); await authenticatedPage.waitForLoadState("networkidle"); await expect(authenticatedPage.getByRole("heading", { name: "内容工坊" })).toBeVisible({ timeout: 15000 }); }); test("内容工坊页面副标题正确显示", async ({ authenticatedPage }) => { await authenticatedPage.goto("/dashboard/content"); await authenticatedPage.waitForLoadState("networkidle"); await expect(authenticatedPage.getByText("AI驱动的内容生产流水线")).toBeVisible({ timeout: 15000 }); }); test("内容工坊页面显示AI生成新内容按钮", async ({ authenticatedPage }) => { await authenticatedPage.goto("/dashboard/content"); await authenticatedPage.waitForLoadState("networkidle"); const generateBtn = authenticatedPage.getByRole("button", { name: /AI生成新内容/ }); await expect(generateBtn.first()).toBeVisible({ timeout: 15000 }); }); }); test.describe("内容工坊 - 内容列表测试", () => { test("有内容时显示内容卡片列表", async ({ authenticatedPage }) => { await authenticatedPage.goto("/dashboard/content"); await authenticatedPage.waitForLoadState("networkidle"); // 检查是否有空状态 const emptyState = authenticatedPage.getByText("还没有内容"); const hasEmpty = await emptyState.isVisible({ timeout: 10000 }).catch(() => false); if (hasEmpty) { test.skip(); return; } // 检查是否有错误 const errorBanner = authenticatedPage.getByText(/加载失败/); const hasError = await errorBanner.isVisible({ timeout: 3000 }).catch(() => false); if (hasError) { test.skip(); return; } // 使用更宽泛的选择器匹配内容卡片 const contentCards = authenticatedPage.locator("[class*='bg-white'][class*='rounded-xl'][class*='border']"); const count = await contentCards.count(); if (count === 0) { test.skip(); return; } expect(count).toBeGreaterThanOrEqual(1); }); test("内容卡片显示状态标签", async ({ authenticatedPage }) => { await authenticatedPage.goto("/dashboard/content"); await authenticatedPage.waitForLoadState("networkidle"); const emptyState = authenticatedPage.getByText("还没有内容"); const hasEmpty = await emptyState.isVisible({ timeout: 10000 }).catch(() => false); if (hasEmpty) { test.skip(); return; } const errorBanner = authenticatedPage.getByText(/加载失败/); const hasError = await errorBanner.isVisible({ timeout: 3000 }).catch(() => false); if (hasError) { test.skip(); return; } const statusBadge = authenticatedPage.getByText(/草稿|待审核|已审核|已发布|已归档/).first(); const hasBadge = await statusBadge.isVisible({ timeout: 5000 }).catch(() => false); if (!hasBadge) { test.skip(); return; } await expect(statusBadge).toBeVisible(); }); test("内容卡片显示类型标签", async ({ authenticatedPage }) => { await authenticatedPage.goto("/dashboard/content"); await authenticatedPage.waitForLoadState("networkidle"); const emptyState = authenticatedPage.getByText("还没有内容"); const hasEmpty = await emptyState.isVisible({ timeout: 10000 }).catch(() => false); if (hasEmpty) { test.skip(); return; } const errorBanner = authenticatedPage.getByText(/加载失败/); const hasError = await errorBanner.isVisible({ timeout: 3000 }).catch(() => false); if (hasError) { test.skip(); return; } const typeBadge = authenticatedPage.getByText(/文章|问答|知识库|社媒/).first(); const hasBadge = await typeBadge.isVisible({ timeout: 5000 }).catch(() => false); if (!hasBadge) { test.skip(); return; } await expect(typeBadge).toBeVisible(); }); test("空状态时显示引导文案和AI生成按钮", async ({ authenticatedPage }) => { await authenticatedPage.goto("/dashboard/content"); await authenticatedPage.waitForLoadState("networkidle"); const emptyState = authenticatedPage.getByText("还没有内容"); const hasEmpty = await emptyState.isVisible({ timeout: 10000 }).catch(() => false); if (!hasEmpty) { test.skip(); return; } await expect(emptyState).toBeVisible(); const generateBtn = authenticatedPage.getByRole("button", { name: /AI生成新内容/ }); await expect(generateBtn.first()).toBeVisible(); }); }); test.describe("内容工坊 - 内容生成测试", () => { test("点击AI生成新内容打开生成对话框", async ({ authenticatedPage }) => { await authenticatedPage.goto("/dashboard/content"); await authenticatedPage.waitForLoadState("networkidle"); const generateBtn = authenticatedPage.getByRole("button", { name: /AI生成新内容/ }).first(); await generateBtn.click(); await expect(authenticatedPage.getByRole("dialog")).toBeVisible({ timeout: 10000 }); }); test("生成对话框包含目标关键词输入框", async ({ authenticatedPage }) => { await authenticatedPage.goto("/dashboard/content"); await authenticatedPage.waitForLoadState("networkidle"); const generateBtn = authenticatedPage.getByRole("button", { name: /AI生成新内容/ }).first(); await generateBtn.click(); await expect(authenticatedPage.locator("#keyword")).toBeVisible({ timeout: 10000 }); }); test("生成对话框包含目标平台选择器", async ({ authenticatedPage }) => { await authenticatedPage.goto("/dashboard/content"); await authenticatedPage.waitForLoadState("networkidle"); const generateBtn = authenticatedPage.getByRole("button", { name: /AI生成新内容/ }).first(); await generateBtn.click(); await expect(authenticatedPage.locator("#platform")).toBeVisible({ timeout: 10000 }); }); test("未填写必填项时开始AI生成按钮禁用", async ({ authenticatedPage }) => { await authenticatedPage.goto("/dashboard/content"); await authenticatedPage.waitForLoadState("networkidle"); const generateBtn = authenticatedPage.getByRole("button", { name: /AI生成新内容/ }).first(); await generateBtn.click(); const submitBtn = authenticatedPage.getByRole("button", { name: /开始AI生成/ }); await expect(submitBtn).toBeDisabled({ timeout: 10000 }); }); test("填写关键词和平台后开始AI生成按钮启用", async ({ authenticatedPage }) => { await authenticatedPage.goto("/dashboard/content"); await authenticatedPage.waitForLoadState("networkidle"); const generateBtn = authenticatedPage.getByRole("button", { name: /AI生成新内容/ }).first(); await generateBtn.click(); const keywordInput = authenticatedPage.locator("#keyword"); await keywordInput.fill("AI营销"); const platformSelect = authenticatedPage.locator("#platform"); await platformSelect.click(); await authenticatedPage.getByText("通用").click(); const submitBtn = authenticatedPage.getByRole("button", { name: /开始AI生成/ }); await expect(submitBtn).toBeEnabled({ timeout: 10000 }); }); }); test.describe("监测优化 - 页面加载测试", () => { test("监测优化页面标题正确显示", async ({ authenticatedPage }) => { await authenticatedPage.goto("/dashboard/monitoring"); await authenticatedPage.waitForLoadState("networkidle"); await expect(authenticatedPage.getByRole("heading", { name: "监测优化" })).toBeVisible({ timeout: 15000 }); }); test("监测优化页面副标题正确显示", async ({ authenticatedPage }) => { await authenticatedPage.goto("/dashboard/monitoring"); await authenticatedPage.waitForLoadState("networkidle"); await expect(authenticatedPage.getByText("实时监控品牌AI可见性,及时响应告警通知")).toBeVisible({ timeout: 15000 }); }); test("监测优化页面显示告警配置按钮", async ({ authenticatedPage }) => { await authenticatedPage.goto("/dashboard/monitoring"); await authenticatedPage.waitForLoadState("networkidle"); const settingsBtn = authenticatedPage.getByRole("button", { name: /告警配置/ }); await expect(settingsBtn).toBeVisible({ timeout: 15000 }); }); test("监测优化页面显示监测记录和告警通知Tab", async ({ authenticatedPage }) => { await authenticatedPage.goto("/dashboard/monitoring"); await authenticatedPage.waitForLoadState("networkidle"); // 使用 waitFor 等待 tab 出现 const recordsTab = authenticatedPage.getByRole("tab", { name: "监测记录" }); const alertsTab = authenticatedPage.getByRole("tab", { name: "告警通知" }); // 至少一个 tab 应该可见 await expect(recordsTab.first()).toBeVisible({ timeout: 15000 }).catch(async () => { await expect(alertsTab.first()).toBeVisible({ timeout: 5000 }); }); }); }); test.describe("监测优化 - 监测记录测试", () => { test("无监测记录时显示空状态", async ({ authenticatedPage }) => { if (!(await hasProjects(authenticatedPage))) { test.skip(); return; } await authenticatedPage.goto("/dashboard/monitoring"); await authenticatedPage.waitForLoadState("networkidle"); const emptyState = authenticatedPage.getByText("暂无监测记录"); const hasEmpty = await emptyState.isVisible({ timeout: 10000 }).catch(() => false); if (!hasEmpty) { test.skip(); return; } await expect(emptyState).toBeVisible(); }); test("有监测记录时显示记录卡片", async ({ authenticatedPage }) => { if (!(await hasProjects(authenticatedPage))) { test.skip(); return; } await authenticatedPage.goto("/dashboard/monitoring"); await authenticatedPage.waitForLoadState("networkidle"); const emptyState = authenticatedPage.getByText("暂无监测记录"); const hasEmpty = await emptyState.isVisible({ timeout: 10000 }).catch(() => false); if (hasEmpty) { test.skip(); return; } const checkBtn = authenticatedPage.getByRole("button", { name: /立即检测/ }); const count = await checkBtn.count(); expect(count).toBeGreaterThanOrEqual(1); }); test("监测记录卡片包含立即检测按钮", async ({ authenticatedPage }) => { if (!(await hasProjects(authenticatedPage))) { test.skip(); return; } await authenticatedPage.goto("/dashboard/monitoring"); await authenticatedPage.waitForLoadState("networkidle"); const emptyState = authenticatedPage.getByText("暂无监测记录"); const hasEmpty = await emptyState.isVisible({ timeout: 10000 }).catch(() => false); if (hasEmpty) { test.skip(); return; } const checkBtn = authenticatedPage.getByRole("button", { name: /立即检测/ }).first(); await expect(checkBtn).toBeVisible({ timeout: 10000 }); }); test("监测记录卡片包含暂停/启用按钮", async ({ authenticatedPage }) => { if (!(await hasProjects(authenticatedPage))) { test.skip(); return; } await authenticatedPage.goto("/dashboard/monitoring"); await authenticatedPage.waitForLoadState("networkidle"); const emptyState = authenticatedPage.getByText("暂无监测记录"); const hasEmpty = await emptyState.isVisible({ timeout: 10000 }).catch(() => false); if (hasEmpty) { test.skip(); return; } const toggleBtn = authenticatedPage.getByRole("button", { name: /暂停|启用/ }).first(); const hasBtn = await toggleBtn.isVisible({ timeout: 5000 }).catch(() => false); if (!hasBtn) { test.skip(); return; } await expect(toggleBtn).toBeVisible(); }); }); test.describe("监测优化 - 告警通知测试", () => { test("点击告警通知Tab切换到告警列表", async ({ authenticatedPage }) => { await authenticatedPage.goto("/dashboard/monitoring"); await authenticatedPage.waitForLoadState("networkidle"); // 滚动到页面顶部确保 Tab 可见 await authenticatedPage.evaluate(() => window.scrollTo(0, 0)); const alertsTab = authenticatedPage.getByRole("tab", { name: /告警通知/ }); const hasTab = await alertsTab.isVisible({ timeout: 15000 }).catch(() => false); if (!hasTab) { // 尝试通过文本定位 const alertsText = authenticatedPage.getByText("告警通知").first(); const hasText = await alertsText.isVisible({ timeout: 5000 }).catch(() => false); if (!hasText) { test.skip(); return; } await alertsText.click(); } else { await alertsTab.click(); } // 分别检查两种可能的状态 — 使用 toBeVisible 确保等待 let found = false; try { await expect(authenticatedPage.getByText("告警列表")).toBeVisible({ timeout: 10000 }); found = true; } catch { try { await expect(authenticatedPage.getByText("暂无告警")).toBeVisible({ timeout: 5000 }); found = true; } catch { // 两者都不可见 } } expect(found).toBeTruthy(); }); test("告警通知Tab显示统计卡片", async ({ authenticatedPage }) => { await authenticatedPage.goto("/dashboard/monitoring"); await authenticatedPage.waitForLoadState("networkidle"); const alertsTab = authenticatedPage.getByRole("tab", { name: /告警通知/ }); const hasTab = await alertsTab.isVisible({ timeout: 10000 }).catch(() => false); if (!hasTab) { test.skip(); return; } await alertsTab.click(); const statCards = authenticatedPage.getByText(/未读告警|严重告警|今日新增|已处理/); const count = await statCards.count(); if (count === 0) { test.skip(); return; } expect(count).toBeGreaterThanOrEqual(1); }); }); test.describe("内容→监测完整流程测试", () => { test("从内容工坊导航到监测优化页面", async ({ authenticatedPage }) => { await authenticatedPage.goto("/dashboard/content"); await authenticatedPage.waitForLoadState("networkidle"); await expect(authenticatedPage.getByRole("heading", { name: "内容工坊" })).toBeVisible({ timeout: 15000 }); await authenticatedPage.goto("/dashboard/monitoring"); await authenticatedPage.waitForLoadState("networkidle"); await expect(authenticatedPage.getByRole("heading", { name: "监测优化" })).toBeVisible({ timeout: 15000 }); }); });