import { test, expect, describe } from "@playwright/test"; import { DashboardPage } from "../pages/dashboard.page"; import { LoginPage } from "../pages/login.page"; const TEST_USER = { email: "admin@example.com", password: "admin@123", }; async function loginAndWait(page: import("@playwright/test").Page) { const loginPage = new LoginPage(page); await loginPage.goto(); await loginPage.login(TEST_USER.email, TEST_USER.password); try { await page.waitForURL(/\/dashboard/, { timeout: 60000 }); } catch { const currentUrl = page.url(); if (!currentUrl.includes("/dashboard")) { await loginPage.goto(); await loginPage.login(TEST_USER.email, TEST_USER.password); await page.waitForURL(/\/dashboard/, { timeout: 60000 }); } } await page.waitForLoadState("networkidle"); } async function hasProjects(page: import("@playwright/test").Page): Promise { const dashboardPage = new DashboardPage(page); await dashboardPage.waitForDashboardLoad(); const emptyMsg = page.getByText("开始优化您的AI可见性"); const errorTitle = page.getByText("数据加载失败"); const isEmpty = await emptyMsg.isVisible().catch(() => false); const isError = await errorTitle.isVisible().catch(() => false); return !isEmpty && !isError; } describe("下一步行动建议测试", () => { test.beforeEach(async ({ page }) => { await loginAndWait(page); }); describe("Dashboard页面推荐下一步显示测试", () => { test("Dashboard页面应显示推荐下一步卡片", async ({ page }) => { const dashboardPage = new DashboardPage(page); const hasRecommendation = await dashboardPage.recommendedNextStep.isVisible({ timeout: 10000 }).catch(() => false); if (!hasRecommendation) { test.skip(); return; } await expect(dashboardPage.recommendedNextStep).toBeVisible(); }); test("推荐下一步卡片应包含标题和描述", async ({ page }) => { const dashboardPage = new DashboardPage(page); const hasRecommendation = await dashboardPage.recommendedNextStep.isVisible({ timeout: 10000 }).catch(() => false); if (!hasRecommendation) { test.skip(); return; } const recommendationTitle = page.locator(".text-sm.font-semibold.text-gray-900").first(); await expect(recommendationTitle).toBeVisible({ timeout: 5000 }); }); test("推荐下一步应包含执行按钮", async ({ page }) => { const dashboardPage = new DashboardPage(page); const hasRecommendation = await dashboardPage.recommendedNextStep.isVisible({ timeout: 10000 }).catch(() => false); if (!hasRecommendation) { test.skip(); return; } const executeBtn = page.getByRole("button", { name: /执行/ }); await expect(executeBtn.first()).toBeVisible({ timeout: 5000 }); }); test("推荐下一步执行按钮应可点击", async ({ page }) => { const dashboardPage = new DashboardPage(page); const hasRecommendation = await dashboardPage.recommendedNextStep.isVisible({ timeout: 10000 }).catch(() => false); if (!hasRecommendation) { test.skip(); return; } const executeBtn = page.getByRole("button", { name: /执行/ }).first(); if (await executeBtn.isVisible()) { expect(await executeBtn.isEnabled()).toBeTruthy(); } }); }); describe("品牌详情页行动建议测试", () => { test("品牌详情页应显示行动建议卡片", async ({ page }) => { await page.goto("/brands"); await page.waitForLoadState("networkidle"); const brandsHeading = page.getByRole("heading", { name: /品牌/ }); if (await brandsHeading.isVisible()) { const brandLink = page .locator("table tbody tr:first-child a, .grid > div:first-child a") .first(); if ((await brandLink.count()) > 0 && (await brandLink.isVisible())) { await brandLink.click(); await page.waitForLoadState("networkidle"); const actionCardTitle = page.getByText("推荐下一步"); if ((await actionCardTitle.count()) > 0) { await expect(actionCardTitle).toBeVisible(); } } } }); }); describe("竞品对比页行动建议测试", () => { test("竞品对比页应显示行动建议卡片", async ({ page }) => { await page.goto("/compare"); await page.waitForLoadState("networkidle"); const actionCardTitle = page.getByText("推荐下一步"); if ((await actionCardTitle.count()) > 0) { await expect(actionCardTitle).toBeVisible(); } }); }); describe("推荐下一步功能测试", () => { test("推荐下一步应根据项目阶段显示不同内容", async ({ page }) => { if (!(await hasProjects(page))) { test.skip(); return; } const dashboardPage = new DashboardPage(page); const hasRecommendation = await dashboardPage.recommendedNextStep.isVisible({ timeout: 10000 }).catch(() => false); if (!hasRecommendation) { test.skip(); return; } const recommendationTitle = await dashboardPage.getRecommendationTitle(); expect(recommendationTitle).not.toBeNull(); }); test("推荐下一步的管理Agent按钮应有视觉强调", async ({ page }) => { if (!(await hasProjects(page))) { test.skip(); return; } const dashboardPage = new DashboardPage(page); const hasRecommendation = await dashboardPage.recommendedNextStep.isVisible({ timeout: 10000 }).catch(() => false); if (!hasRecommendation) { test.skip(); return; } const agentBtn = page.getByRole("button", { name: /管理Agent/ }); if (await agentBtn.isVisible()) { await expect(agentBtn).toBeVisible(); } }); test("点击推荐下一步执行按钮应导航到对应页面", async ({ page }) => { if (!(await hasProjects(page))) { test.skip(); return; } const dashboardPage = new DashboardPage(page); const hasRecommendation = await dashboardPage.recommendedNextStep.isVisible({ timeout: 10000 }).catch(() => false); if (!hasRecommendation) { test.skip(); return; } const executeBtn = page.getByRole("button", { name: /执行/ }).first(); if (await executeBtn.isVisible()) { await executeBtn.click(); await page.waitForLoadState("networkidle"); } }); }); describe("空状态推荐下一步测试", () => { test("无项目时显示空状态引导", async ({ page }) => { const emptyMsg = page.getByText("开始优化您的AI可见性"); const hasEmpty = await emptyMsg.isVisible({ timeout: 5000 }).catch(() => false); if (!hasEmpty) { test.skip(); return; } await expect(emptyMsg).toBeVisible(); const createBtn = page.getByRole("button", { name: /创建项目/ }); await expect(createBtn.first()).toBeVisible(); }); }); }); describe("未登录状态测试", () => { test("未登录用户访问dashboard应重定向到登录页", async ({ page }) => { await page.goto("/dashboard"); await expect(page).toHaveURL(/\/login/, { timeout: 15000 }); }); test("未登录用户访问品牌页面应重定向到登录页", async ({ page }) => { await page.goto("/brands"); await expect(page).toHaveURL(/\/login/, { timeout: 15000 }); }); test("未登录用户访问对比页面应重定向到登录页", async ({ page }) => { await page.goto("/compare"); await expect(page).toHaveURL(/\/login/, { timeout: 15000 }); }); });