203 lines
6.9 KiB
TypeScript
203 lines
6.9 KiB
TypeScript
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",
|
||
};
|
||
|
||
describe("下一步行动建议测试", () => {
|
||
test.beforeEach(async ({ page }) => {
|
||
// 登录
|
||
const loginPage = new LoginPage(page);
|
||
await loginPage.goto();
|
||
await loginPage.login(TEST_USER.email, TEST_USER.password);
|
||
|
||
// 等待跳转到dashboard
|
||
try {
|
||
await page.waitForURL(/\/dashboard/, { timeout: 20000 });
|
||
} catch (e) {
|
||
// 如果超时,检查当前URL
|
||
console.log("Current URL after login timeout:", page.url());
|
||
throw e;
|
||
}
|
||
});
|
||
|
||
describe("Dashboard页面行动建议显示测试", () => {
|
||
test("Dashboard页面应显示下一步行动建议卡片", async ({ page }) => {
|
||
// 等待页面加载完成
|
||
await page.waitForLoadState("networkidle");
|
||
|
||
// 检查行动建议标题
|
||
const actionCardTitle = page.getByText("为您推荐的下一步行动");
|
||
await expect(actionCardTitle).toBeVisible({ timeout: 10000 });
|
||
});
|
||
|
||
test("行动建议卡片应包含标题和描述", async ({ page }) => {
|
||
await page.waitForLoadState("networkidle");
|
||
|
||
// 等待行动建议卡片加载
|
||
await expect(page.getByText("为您推荐的下一步行动")).toBeVisible({
|
||
timeout: 10000,
|
||
});
|
||
|
||
// 检查是否有行动项
|
||
const actionItems = page.locator(".space-y-3 > div").first();
|
||
await expect(actionItems).toBeVisible({ timeout: 5000 });
|
||
});
|
||
|
||
test("行动建议应包含操作按钮", async ({ page }) => {
|
||
await page.waitForLoadState("networkidle");
|
||
|
||
// 等待行动建议卡片加载
|
||
await expect(page.getByText("为您推荐的下一步行动")).toBeVisible({
|
||
timeout: 10000,
|
||
});
|
||
|
||
// 等待按钮加载
|
||
await page.waitForTimeout(1000);
|
||
|
||
// 检查是否有操作按钮 - 使用更通用的选择器
|
||
const actionButtons = page.getByRole("link").or(page.getByRole("button"));
|
||
await expect(actionButtons.first()).toBeVisible({ timeout: 5000 });
|
||
});
|
||
|
||
test("行动建议按钮应可点击并跳转", async ({ page }) => {
|
||
await page.waitForLoadState("networkidle");
|
||
|
||
// 等待行动建议卡片加载
|
||
await expect(page.getByText("为您推荐的下一步行动")).toBeVisible({
|
||
timeout: 10000,
|
||
});
|
||
|
||
// 等待按钮出现
|
||
await page.waitForTimeout(1000);
|
||
|
||
// 找到第一个行动按钮
|
||
const actionButton = page.locator("a[href], button").first();
|
||
if (await actionButton.isVisible()) {
|
||
const href = await actionButton.getAttribute("href");
|
||
// href可能为null如果它是button而不是link
|
||
expect(href !== null || (await actionButton.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 }) => {
|
||
await page.waitForLoadState("networkidle");
|
||
|
||
// 行动建议卡片应该可见
|
||
const actionCard = page
|
||
.getByText("为您推荐的下一步行动")
|
||
.locator("..")
|
||
.locator("..")
|
||
.locator("..");
|
||
if ((await actionCard.count()) > 0) {
|
||
await expect(actionCard).toBeVisible();
|
||
}
|
||
});
|
||
|
||
test("行动建议的主要行动应有视觉强调", async ({ page }) => {
|
||
await page.waitForLoadState("networkidle");
|
||
|
||
// 等待行动建议加载
|
||
await page.waitForTimeout(1000);
|
||
|
||
// 检查是否有橙色边框的主要行动(根据优先级颜色配置)
|
||
const primaryAction = page
|
||
.locator(".border-l-4.border-l-orange-500")
|
||
.first();
|
||
// 注意:可能没有匹配的元素,但我们检查页面结构
|
||
const actionSection = page.getByText("主要").first();
|
||
if ((await actionSection.count()) > 0) {
|
||
await expect(actionSection).toBeVisible();
|
||
}
|
||
});
|
||
|
||
test("点击行动建议应导航到对应页面", async ({ page }) => {
|
||
await page.waitForLoadState("networkidle");
|
||
|
||
// 等待行动建议加载
|
||
await page.waitForTimeout(1000);
|
||
|
||
// 找到查看详情按钮
|
||
const viewButton = page.locator("a[href*='/']").first();
|
||
if (await viewButton.isVisible()) {
|
||
await viewButton.click();
|
||
// 验证URL变化或页面跳转
|
||
await page.waitForLoadState("networkidle");
|
||
}
|
||
});
|
||
});
|
||
|
||
describe("空状态行动建议测试", () => {
|
||
test("无数据时显示默认引导", async ({ page }) => {
|
||
// 此测试需要空状态数据,这里检查组件是否能正常渲染
|
||
await page.waitForLoadState("networkidle");
|
||
|
||
// 行动建议卡片应该存在
|
||
const actionCardTitle = page.getByText("为您推荐的下一步行动");
|
||
await expect(actionCardTitle).toBeVisible();
|
||
});
|
||
});
|
||
});
|
||
|
||
describe("未登录状态测试", () => {
|
||
test("未登录用户访问dashboard应重定向到登录页", async ({ page }) => {
|
||
await page.goto("/dashboard");
|
||
await expect(page).toHaveURL(/\/login/);
|
||
});
|
||
|
||
test("未登录用户访问品牌页面应重定向到登录页", async ({ page }) => {
|
||
await page.goto("/brands");
|
||
await expect(page).toHaveURL(/\/login/);
|
||
});
|
||
|
||
test("未登录用户访问对比页面应重定向到登录页", async ({ page }) => {
|
||
await page.goto("/compare");
|
||
await expect(page).toHaveURL(/\/login/);
|
||
});
|
||
});
|