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/diagnosis"); await authenticatedPage.waitForLoadState("networkidle"); await expect(authenticatedPage.getByRole("heading", { name: "诊断分析" })).toBeVisible({ timeout: 15000 }); }); test("诊断分析页面副标题正确显示", async ({ authenticatedPage }) => { await authenticatedPage.goto("/dashboard/diagnosis"); await authenticatedPage.waitForLoadState("networkidle"); await expect(authenticatedPage.getByText("全面评估品牌在搜索引擎和AI生成式引擎中的可见性")).toBeVisible({ timeout: 15000 }); }); test("无品牌时显示空状态", async ({ authenticatedPage }) => { if (await hasProjects(authenticatedPage)) { test.skip(); return; } await authenticatedPage.goto("/dashboard/diagnosis"); await authenticatedPage.waitForLoadState("networkidle"); const emptyTitle = authenticatedPage.getByText("暂无品牌数据"); const hasEmpty = await emptyTitle.isVisible({ timeout: 10000 }).catch(() => false); if (!hasEmpty) { test.skip(); return; } await expect(emptyTitle).toBeVisible(); }); }); test.describe("诊断分析 - 诊断流程测试", () => { test("有品牌时显示重新诊断按钮", async ({ authenticatedPage }) => { if (!(await hasProjects(authenticatedPage))) { test.skip(); return; } await authenticatedPage.goto("/dashboard/diagnosis"); await authenticatedPage.waitForLoadState("networkidle"); const refreshBtn = authenticatedPage.getByRole("button", { name: /重新诊断/ }); await expect(refreshBtn).toBeVisible({ timeout: 15000 }); }); test("诊断页面显示三个评分卡片", async ({ authenticatedPage }) => { if (!(await hasProjects(authenticatedPage))) { test.skip(); return; } await authenticatedPage.goto("/dashboard/diagnosis"); await authenticatedPage.waitForLoadState("networkidle"); await expect(authenticatedPage.getByText("综合评分")).toBeVisible({ timeout: 15000 }); await expect(authenticatedPage.getByText("SEO诊断评分")).toBeVisible(); await expect(authenticatedPage.getByText("GEO诊断评分")).toBeVisible(); }); test("诊断页面显示三个Tab标签", async ({ authenticatedPage }) => { if (!(await hasProjects(authenticatedPage))) { test.skip(); return; } await authenticatedPage.goto("/dashboard/diagnosis"); await authenticatedPage.waitForLoadState("networkidle"); // 分别检查每个 tab,避免 .or() strict mode 问题 const combinedTab = authenticatedPage.getByRole("tab", { name: "综合诊断" }); const seoTab = authenticatedPage.getByRole("tab", { name: "SEO诊断" }); const geoTab = authenticatedPage.getByRole("tab", { name: "GEO诊断" }); const hasCombined = await combinedTab.isVisible({ timeout: 10000 }).catch(() => false); const hasSeo = await seoTab.isVisible({ timeout: 3000 }).catch(() => false); const hasGeo = await geoTab.isVisible({ timeout: 3000 }).catch(() => false); expect(hasCombined || hasSeo || hasGeo).toBeTruthy(); }); test("点击SEO诊断Tab显示SEO诊断详情", async ({ authenticatedPage }) => { if (!(await hasProjects(authenticatedPage))) { test.skip(); return; } await authenticatedPage.goto("/dashboard/diagnosis"); await authenticatedPage.waitForLoadState("networkidle"); const seoTab = authenticatedPage.getByRole("tab", { name: "SEO诊断" }); const hasTab = await seoTab.isVisible({ timeout: 10000 }).catch(() => false); if (!hasTab) { test.skip(); return; } await seoTab.click(); // 分别检查两种可能的状态 const seoDetail = authenticatedPage.getByText("SEO诊断详情"); const seoEmpty = authenticatedPage.getByText("暂无SEO诊断数据"); const hasDetail = await seoDetail.isVisible({ timeout: 10000 }).catch(() => false); const hasEmpty = await seoEmpty.isVisible({ timeout: 3000 }).catch(() => false); expect(hasDetail || hasEmpty).toBeTruthy(); }); test("点击GEO诊断Tab显示GEO诊断详情", async ({ authenticatedPage }) => { if (!(await hasProjects(authenticatedPage))) { test.skip(); return; } await authenticatedPage.goto("/dashboard/diagnosis"); await authenticatedPage.waitForLoadState("networkidle"); const geoTab = authenticatedPage.getByRole("tab", { name: "GEO诊断" }); const hasTab = await geoTab.isVisible({ timeout: 10000 }).catch(() => false); if (!hasTab) { test.skip(); return; } await geoTab.click(); const geoDetail = authenticatedPage.getByText("GEO诊断详情"); const geoEmpty = authenticatedPage.getByText("暂无GEO诊断数据"); const hasDetail = await geoDetail.isVisible({ timeout: 10000 }).catch(() => false); const hasEmpty = await geoEmpty.isVisible({ timeout: 3000 }).catch(() => false); expect(hasDetail || hasEmpty).toBeTruthy(); }); test("诊断结果显示5维度评分", async ({ authenticatedPage }) => { if (!(await hasProjects(authenticatedPage))) { test.skip(); return; } await authenticatedPage.goto("/dashboard/diagnosis"); await authenticatedPage.waitForLoadState("networkidle"); const geoTab = authenticatedPage.getByRole("tab", { name: "GEO诊断" }); const hasTab = await geoTab.isVisible({ timeout: 10000 }).catch(() => false); if (!hasTab) { test.skip(); return; } await geoTab.click(); await authenticatedPage.waitForLoadState("networkidle"); const dimensionLabels = authenticatedPage.getByText(/内容可提取性|实体清晰度|E-E-A-T信号|Schema标记|主题权威|引用就绪度/); const count = await dimensionLabels.count(); if (count === 0) { test.skip(); return; } expect(count).toBeGreaterThanOrEqual(1); }); test("点击重新诊断按钮触发刷新", async ({ authenticatedPage }) => { if (!(await hasProjects(authenticatedPage))) { test.skip(); return; } await authenticatedPage.goto("/dashboard/diagnosis"); await authenticatedPage.waitForLoadState("networkidle"); const refreshBtn = authenticatedPage.getByRole("button", { name: /重新诊断/ }); if (await refreshBtn.isVisible()) { await refreshBtn.click(); await authenticatedPage.waitForLoadState("networkidle"); } }); }); test.describe("诊断分析 - 优先优化建议测试", () => { test("诊断结果包含优先优化建议", async ({ authenticatedPage }) => { if (!(await hasProjects(authenticatedPage))) { test.skip(); return; } await authenticatedPage.goto("/dashboard/diagnosis"); await authenticatedPage.waitForLoadState("networkidle"); const recommendations = authenticatedPage.getByText("优先优化建议"); const hasRecommendations = await recommendations.isVisible({ timeout: 10000 }).catch(() => false); if (!hasRecommendations) { test.skip(); return; } await expect(recommendations).toBeVisible(); }); test("建议列表包含基于诊断制定GEO方案按钮", async ({ authenticatedPage }) => { if (!(await hasProjects(authenticatedPage))) { test.skip(); return; } await authenticatedPage.goto("/dashboard/diagnosis"); await authenticatedPage.waitForLoadState("networkidle"); const geoPlanBtn = authenticatedPage.getByRole("button", { name: /基于诊断制定GEO方案/ }); const hasBtn = await geoPlanBtn.isVisible({ timeout: 10000 }).catch(() => false); if (!hasBtn) { test.skip(); return; } await expect(geoPlanBtn).toBeVisible(); }); test("点击基于诊断制定GEO方案跳转到策略页面", async ({ authenticatedPage }) => { if (!(await hasProjects(authenticatedPage))) { test.skip(); return; } await authenticatedPage.goto("/dashboard/diagnosis"); await authenticatedPage.waitForLoadState("networkidle"); const geoPlanBtn = authenticatedPage.getByRole("button", { name: /基于诊断制定GEO方案/ }); const hasBtn = await geoPlanBtn.isVisible({ timeout: 10000 }).catch(() => false); if (!hasBtn) { test.skip(); return; } await geoPlanBtn.click(); await expect(authenticatedPage).toHaveURL(/\/dashboard\/strategy/, { timeout: 15000 }); }); }); test.describe("策略制定 - 页面加载测试", () => { test("策略制定页面标题正确显示", async ({ authenticatedPage }) => { await authenticatedPage.goto("/dashboard/strategy"); await authenticatedPage.waitForLoadState("networkidle"); await expect(authenticatedPage.getByRole("heading", { name: "策略制定" })).toBeVisible({ timeout: 15000 }); }); test("策略制定页面副标题正确显示", async ({ authenticatedPage }) => { await authenticatedPage.goto("/dashboard/strategy"); await authenticatedPage.waitForLoadState("networkidle"); await expect(authenticatedPage.getByText("制定GEO优化策略、关键词规划与目标设定")).toBeVisible({ timeout: 15000 }); }); test("无方案时显示生成新方案按钮", async ({ authenticatedPage }) => { if (!(await hasProjects(authenticatedPage))) { test.skip(); return; } await authenticatedPage.goto("/dashboard/strategy"); await authenticatedPage.waitForLoadState("networkidle"); const generateBtn = authenticatedPage.getByRole("button", { name: /生成新方案|生成优化方案/ }); const hasBtn = await generateBtn.isVisible({ timeout: 10000 }).catch(() => false); if (!hasBtn) { test.skip(); return; } await expect(generateBtn.first()).toBeVisible(); }); }); test.describe("策略制定 - 方案详情测试", () => { test("有方案时显示诊断分数和目标分数", async ({ authenticatedPage }) => { if (!(await hasProjects(authenticatedPage))) { test.skip(); return; } await authenticatedPage.goto("/dashboard/strategy"); await authenticatedPage.waitForLoadState("networkidle"); const scoreLabel = authenticatedPage.getByText("诊断分数 → 目标分数"); const hasScore = await scoreLabel.isVisible({ timeout: 10000 }).catch(() => false); if (!hasScore) { test.skip(); return; } await expect(scoreLabel).toBeVisible(); }); test("有方案时显示预计周数", async ({ authenticatedPage }) => { if (!(await hasProjects(authenticatedPage))) { test.skip(); return; } await authenticatedPage.goto("/dashboard/strategy"); await authenticatedPage.waitForLoadState("networkidle"); const weeksLabel = authenticatedPage.getByText("预计周数"); const hasWeeks = await weeksLabel.isVisible({ timeout: 10000 }).catch(() => false); if (!hasWeeks) { test.skip(); return; } await expect(weeksLabel).toBeVisible(); }); test("有方案时显示行动项进度", async ({ authenticatedPage }) => { if (!(await hasProjects(authenticatedPage))) { test.skip(); return; } await authenticatedPage.goto("/dashboard/strategy"); await authenticatedPage.waitForLoadState("networkidle"); const progressLabel = authenticatedPage.getByText("行动项进度"); const hasProgress = await progressLabel.isVisible({ timeout: 10000 }).catch(() => false); if (!hasProgress) { test.skip(); return; } await expect(progressLabel).toBeVisible(); }); test("有方案时显示行动项列表", async ({ authenticatedPage }) => { if (!(await hasProjects(authenticatedPage))) { test.skip(); return; } await authenticatedPage.goto("/dashboard/strategy"); await authenticatedPage.waitForLoadState("networkidle"); const actionList = authenticatedPage.getByText("行动项列表"); const hasActions = await actionList.isVisible({ timeout: 10000 }).catch(() => false); if (!hasActions) { test.skip(); return; } await expect(actionList).toBeVisible(); }); test("行动项包含AI生成内容按钮", async ({ authenticatedPage }) => { if (!(await hasProjects(authenticatedPage))) { test.skip(); return; } await authenticatedPage.goto("/dashboard/strategy"); await authenticatedPage.waitForLoadState("networkidle"); const aiGenBtn = authenticatedPage.getByRole("button", { name: /AI生成内容/ }); const hasBtn = await aiGenBtn.isVisible({ timeout: 10000 }).catch(() => false); if (!hasBtn) { test.skip(); return; } await expect(aiGenBtn.first()).toBeVisible(); }); }); test.describe("诊断→策略完整流程测试", () => { test("从诊断页面导航到策略制定页面", async ({ authenticatedPage }) => { if (!(await hasProjects(authenticatedPage))) { test.skip(); return; } await authenticatedPage.goto("/dashboard/diagnosis"); await authenticatedPage.waitForLoadState("networkidle"); const geoPlanBtn = authenticatedPage.getByRole("button", { name: /基于诊断制定GEO方案/ }); const hasBtn = await geoPlanBtn.isVisible({ timeout: 10000 }).catch(() => false); if (!hasBtn) { test.skip(); return; } await geoPlanBtn.click(); await expect(authenticatedPage).toHaveURL(/\/dashboard\/strategy/, { timeout: 15000 }); await expect(authenticatedPage.getByRole("heading", { name: "策略制定" })).toBeVisible({ timeout: 15000 }); }); });