import { test, expect, describe } from "@playwright/test"; import { LoginPage } from "../pages/login.page"; import { DashboardPage } from "../pages/dashboard.page"; const TEST_USER = { email: process.env.E2E_TEST_EMAIL || "admin@example.com", password: process.env.E2E_TEST_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); }); test("内容工坊页面标题正确显示", async ({ page }) => { await page.goto("/dashboard/content"); await page.waitForLoadState("networkidle"); await expect(page.getByRole("heading", { name: "内容工坊" })).toBeVisible({ timeout: 15000 }); }); test("内容工坊页面副标题正确显示", async ({ page }) => { await page.goto("/dashboard/content"); await page.waitForLoadState("networkidle"); await expect(page.getByText("AI驱动的内容生产流水线")).toBeVisible({ timeout: 15000 }); }); test("内容工坊页面显示AI生成新内容按钮", async ({ page }) => { await page.goto("/dashboard/content"); await page.waitForLoadState("networkidle"); const generateBtn = page.getByRole("button", { name: /AI生成新内容/ }); await expect(generateBtn).toBeVisible({ timeout: 15000 }); }); }); describe("内容工坊 - 内容列表测试", () => { test.beforeEach(async ({ page }) => { await loginAndWait(page); }); test("有内容时显示内容卡片列表", async ({ page }) => { await page.goto("/dashboard/content"); await page.waitForLoadState("networkidle"); const emptyState = page.getByText("还没有内容"); const hasEmpty = await emptyState.isVisible({ timeout: 10000 }).catch(() => false); if (hasEmpty) { test.skip(); return; } const contentCards = page.locator(".bg-white.rounded-xl.border"); const count = await contentCards.count(); expect(count).toBeGreaterThanOrEqual(1); }); test("内容卡片显示状态标签", async ({ page }) => { await page.goto("/dashboard/content"); await page.waitForLoadState("networkidle"); const emptyState = page.getByText("还没有内容"); const hasEmpty = await emptyState.isVisible({ timeout: 10000 }).catch(() => false); if (hasEmpty) { test.skip(); return; } const statusBadge = page.getByText(/草稿|待审核|已审核|已发布|已归档/).first(); await expect(statusBadge).toBeVisible({ timeout: 10000 }); }); test("内容卡片显示类型标签", async ({ page }) => { await page.goto("/dashboard/content"); await page.waitForLoadState("networkidle"); const emptyState = page.getByText("还没有内容"); const hasEmpty = await emptyState.isVisible({ timeout: 10000 }).catch(() => false); if (hasEmpty) { test.skip(); return; } const typeBadge = page.getByText(/文章|问答|知识库|社媒/).first(); await expect(typeBadge).toBeVisible({ timeout: 10000 }); }); test("空状态时显示引导文案和AI生成按钮", async ({ page }) => { await page.goto("/dashboard/content"); await page.waitForLoadState("networkidle"); const emptyState = page.getByText("还没有内容"); const hasEmpty = await emptyState.isVisible({ timeout: 10000 }).catch(() => false); if (!hasEmpty) { test.skip(); return; } await expect(emptyState).toBeVisible(); const generateBtn = page.getByRole("button", { name: /AI生成新内容/ }); await expect(generateBtn).toBeVisible(); }); }); describe("内容工坊 - 内容生成测试", () => { test.beforeEach(async ({ page }) => { await loginAndWait(page); }); test("点击AI生成新内容打开生成对话框", async ({ page }) => { await page.goto("/dashboard/content"); await page.waitForLoadState("networkidle"); const generateBtn = page.getByRole("button", { name: /AI生成新内容/ }).first(); await generateBtn.click(); await expect(page.getByRole("dialog")).toBeVisible({ timeout: 10000 }); await expect(page.getByText("AI生成新内容")).toBeVisible(); }); test("生成对话框包含目标关键词输入框", async ({ page }) => { await page.goto("/dashboard/content"); await page.waitForLoadState("networkidle"); const generateBtn = page.getByRole("button", { name: /AI生成新内容/ }).first(); await generateBtn.click(); await expect(page.getByLabel("目标关键词")).toBeVisible({ timeout: 10000 }); }); test("生成对话框包含目标平台选择器", async ({ page }) => { await page.goto("/dashboard/content"); await page.waitForLoadState("networkidle"); const generateBtn = page.getByRole("button", { name: /AI生成新内容/ }).first(); await generateBtn.click(); await expect(page.getByLabel("目标平台")).toBeVisible({ timeout: 10000 }); }); test("未填写必填项时开始AI生成按钮禁用", async ({ page }) => { await page.goto("/dashboard/content"); await page.waitForLoadState("networkidle"); const generateBtn = page.getByRole("button", { name: /AI生成新内容/ }).first(); await generateBtn.click(); const submitBtn = page.getByRole("button", { name: /开始AI生成/ }); await expect(submitBtn).toBeDisabled({ timeout: 10000 }); }); test("填写关键词和平台后开始AI生成按钮启用", async ({ page }) => { await page.goto("/dashboard/content"); await page.waitForLoadState("networkidle"); const generateBtn = page.getByRole("button", { name: /AI生成新内容/ }).first(); await generateBtn.click(); const keywordInput = page.getByLabel("目标关键词"); await keywordInput.fill("AI营销"); const platformSelect = page.getByLabel("目标平台"); await platformSelect.click(); await page.getByText("通用").click(); const submitBtn = page.getByRole("button", { name: /开始AI生成/ }); await expect(submitBtn).toBeEnabled({ timeout: 10000 }); }); }); describe("监测优化 - 页面加载测试", () => { test.beforeEach(async ({ page }) => { await loginAndWait(page); }); test("监测优化页面标题正确显示", async ({ page }) => { await page.goto("/dashboard/monitoring"); await page.waitForLoadState("networkidle"); await expect(page.getByRole("heading", { name: "监测优化" })).toBeVisible({ timeout: 15000 }); }); test("监测优化页面副标题正确显示", async ({ page }) => { await page.goto("/dashboard/monitoring"); await page.waitForLoadState("networkidle"); await expect(page.getByText("实时监控品牌AI可见性,及时响应告警通知")).toBeVisible({ timeout: 15000 }); }); test("监测优化页面显示告警配置按钮", async ({ page }) => { await page.goto("/dashboard/monitoring"); await page.waitForLoadState("networkidle"); const settingsBtn = page.getByRole("button", { name: /告警配置/ }); await expect(settingsBtn).toBeVisible({ timeout: 15000 }); }); test("监测优化页面显示监测记录和告警通知Tab", async ({ page }) => { await page.goto("/dashboard/monitoring"); await page.waitForLoadState("networkidle"); await expect(page.getByRole("tab", { name: /监测记录/ })).toBeVisible({ timeout: 15000 }); await expect(page.getByRole("tab", { name: /告警通知/ })).toBeVisible(); }); }); describe("监测优化 - 监测记录测试", () => { test.beforeEach(async ({ page }) => { await loginAndWait(page); }); test("无监测记录时显示空状态", async ({ page }) => { if (!(await hasProjects(page))) { test.skip(); return; } await page.goto("/dashboard/monitoring"); await page.waitForLoadState("networkidle"); const emptyState = page.getByText("暂无监测记录"); const hasEmpty = await emptyState.isVisible({ timeout: 10000 }).catch(() => false); if (!hasEmpty) { test.skip(); return; } await expect(emptyState).toBeVisible(); }); test("有监测记录时显示记录卡片", async ({ page }) => { if (!(await hasProjects(page))) { test.skip(); return; } await page.goto("/dashboard/monitoring"); await page.waitForLoadState("networkidle"); const emptyState = page.getByText("暂无监测记录"); const hasEmpty = await emptyState.isVisible({ timeout: 10000 }).catch(() => false); if (hasEmpty) { test.skip(); return; } const recordCards = page.locator("div.flex.items-center.gap-4"); const count = await recordCards.count(); expect(count).toBeGreaterThanOrEqual(1); }); test("监测记录卡片包含立即检测按钮", async ({ page }) => { if (!(await hasProjects(page))) { test.skip(); return; } await page.goto("/dashboard/monitoring"); await page.waitForLoadState("networkidle"); const emptyState = page.getByText("暂无监测记录"); const hasEmpty = await emptyState.isVisible({ timeout: 10000 }).catch(() => false); if (hasEmpty) { test.skip(); return; } const checkBtn = page.getByRole("button", { name: /立即检测/ }).first(); await expect(checkBtn).toBeVisible({ timeout: 10000 }); }); test("监测记录卡片包含暂停/启用按钮", async ({ page }) => { if (!(await hasProjects(page))) { test.skip(); return; } await page.goto("/dashboard/monitoring"); await page.waitForLoadState("networkidle"); const emptyState = page.getByText("暂无监测记录"); const hasEmpty = await emptyState.isVisible({ timeout: 10000 }).catch(() => false); if (hasEmpty) { test.skip(); return; } const toggleBtn = page.getByRole("button", { name: /暂停|启用/ }).first(); await expect(toggleBtn).toBeVisible({ timeout: 10000 }); }); }); describe("监测优化 - 告警通知测试", () => { test.beforeEach(async ({ page }) => { await loginAndWait(page); }); test("点击告警通知Tab切换到告警列表", async ({ page }) => { await page.goto("/dashboard/monitoring"); await page.waitForLoadState("networkidle"); const alertsTab = page.getByRole("tab", { name: /告警通知/ }); await alertsTab.click(); await expect(page.getByText("告警列表").or(page.getByText("暂无告警"))).toBeVisible({ timeout: 10000 }); }); test("告警通知Tab显示统计卡片", async ({ page }) => { await page.goto("/dashboard/monitoring"); await page.waitForLoadState("networkidle"); const alertsTab = page.getByRole("tab", { name: /告警通知/ }); await alertsTab.click(); const statCards = page.getByText(/未读告警|严重告警|今日新增|已处理/); const count = await statCards.count(); expect(count).toBeGreaterThanOrEqual(1); }); }); describe("内容→监测完整流程测试", () => { test("从内容工坊导航到监测优化页面", async ({ page }) => { await loginAndWait(page); await page.goto("/dashboard/content"); await page.waitForLoadState("networkidle"); await expect(page.getByRole("heading", { name: "内容工坊" })).toBeVisible({ timeout: 15000 }); await page.goto("/dashboard/monitoring"); await page.waitForLoadState("networkidle"); await expect(page.getByRole("heading", { name: "监测优化" })).toBeVisible({ timeout: 15000 }); }); });