import { test, expect, type Page } from "@playwright/test"; import { mockContentList, mockDetailItem } from "./fixtures"; async function mockTrendingAPI(page: Page, items = mockContentList) { await page.route(/\/api\/tikhub\//, async (route) => { const url = route.request().url(); if (url.includes("/detail")) { await route.fulfill({ status: 200, contentType: "application/json", body: JSON.stringify({ data: mockDetailItem }), }); return; } const match = url.match(/\/api\/tikhub\/(\w+)/); const platform = match?.[1]; const filtered = items.filter((i) => i.platform === platform); await route.fulfill({ status: 200, contentType: "application/json", body: JSON.stringify({ data: filtered }), }); }); } test.describe("首页浏览流程", () => { test("首页加载并显示内容卡片", async ({ page }) => { await mockTrendingAPI(page); await page.goto("/"); await expect(page.getByTestId("content-grid")).toBeVisible(); const cards = page.getByTestId("content-card"); await expect(cards).toHaveCount(9); }); test("平台切换", async ({ page }) => { await mockTrendingAPI(page); await page.goto("/"); await expect(page.getByTestId("content-grid")).toBeVisible(); // Switch to douyin — 2 items (dy-001, dy-004) await page.getByTestId("platform-tab-douyin").click(); await expect(page.getByTestId("content-card")).toHaveCount(2); // Switch to tiktok — 1 item (tt-002) await page.getByTestId("platform-tab-tiktok").click(); await expect(page.getByTestId("content-card")).toHaveCount(1); // Switch to xiaohongshu — 1 item (xhs-003) await page.getByTestId("platform-tab-xiaohongshu").click(); await expect(page.getByTestId("content-card")).toHaveCount(1); // Switch to youtube — 1 item (yt-005) await page.getByTestId("platform-tab-youtube").click(); await expect(page.getByTestId("content-card")).toHaveCount(1); // Switch to instagram — 1 item (ig-006) await page.getByTestId("platform-tab-instagram").click(); await expect(page.getByTestId("content-card")).toHaveCount(1); // Switch to twitter — 1 item (tw-007) await page.getByTestId("platform-tab-twitter").click(); await expect(page.getByTestId("content-card")).toHaveCount(1); // Switch to bilibili — 1 item (bl-008) await page.getByTestId("platform-tab-bilibili").click(); await expect(page.getByTestId("content-card")).toHaveCount(1); // Switch to weibo — 1 item (wb-009) await page.getByTestId("platform-tab-weibo").click(); await expect(page.getByTestId("content-card")).toHaveCount(1); // Switch back to all — 9 items await page.getByTestId("platform-tab-all").click(); await expect(page.getByTestId("content-card")).toHaveCount(9); }); test("排序功能", async ({ page }) => { await mockTrendingAPI(page); await page.goto("/"); await expect(page.getByTestId("content-grid")).toBeVisible(); // Default: play_count desc — YouTube (10M) first await expect(page.getByTestId("content-card").first()).toContainText( "YouTube Top Music" ); // Switch sort field to like_count await page.getByTestId("sort-select").selectOption("like_count"); // like_count desc: yt-005(500K) first await expect(page.getByTestId("content-card").first()).toContainText( "YouTube Top Music" ); // Toggle to ascending await page.getByTestId("sort-order").click(); // like_count asc: dy-004(35K) first await expect(page.getByTestId("content-card").first()).toContainText( "生活小妙招" ); }); test("卡片导航到详情页", async ({ page }) => { await mockTrendingAPI(page); await page.goto("/"); await expect(page.getByTestId("content-grid")).toBeVisible(); // Default sort: play_count desc → first card is YouTube (yt-005, 10M) await page.getByTestId("content-card").first().click(); await expect(page).toHaveURL(/\/detail\/youtube\/yt-005/); }); test("空状态", async ({ page }) => { await mockTrendingAPI(page, []); await page.goto("/"); await expect(page.getByTestId("empty-state")).toBeVisible(); await expect(page.getByText("暂无内容")).toBeVisible(); }); test("错误状态和重试", async ({ page }) => { await page.route(/\/api\/tikhub\//, async (route) => { await route.fulfill({ status: 500, contentType: "application/json", body: JSON.stringify({ error: "服务器错误" }), }); }); await page.goto("/"); await expect(page.getByText("加载失败")).toBeVisible({ timeout: 30_000 }); await expect(page.getByTestId("error-retry")).toBeVisible(); }); });