项目从单体结构重构为 pnpm monorepo (shared/backend/frontend), 新增 YouTube、Instagram、Twitter/X、哔哩哔哩、微博 5 个平台适配器, 包含完整的单元测试和 E2E 测试覆盖。 - 完成 T-031~T-044: 5 个适配器实现、注册、配置和测试 - 重构前后端分离: Hono 后端 + Next.js 前端 - 151 个单元测试 + 21 个 Mock E2E + 25 个真实 E2E - 适配器基于真实 TikHub API 响应结构实现 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
74 lines
2.3 KiB
TypeScript
74 lines
2.3 KiB
TypeScript
import { test, expect } from "@playwright/test";
|
|
|
|
test.describe("设置流程", () => {
|
|
test("导航到设置页", async ({ page }) => {
|
|
await page.goto("/settings");
|
|
|
|
await expect(page.getByRole("heading", { name: "设置" })).toBeVisible();
|
|
await expect(page.getByText("TikHub API Key")).toBeVisible();
|
|
});
|
|
|
|
test("保存 API Key", async ({ page }) => {
|
|
await page.route(/\/api\/settings/, async (route) => {
|
|
if (route.request().method() === "POST") {
|
|
await route.fulfill({
|
|
status: 200,
|
|
contentType: "application/json",
|
|
body: JSON.stringify({ success: true }),
|
|
});
|
|
}
|
|
});
|
|
|
|
await page.goto("/settings");
|
|
await page.getByTestId("apikey-input").fill("test-api-key-123");
|
|
await page.getByTestId("apikey-save").click();
|
|
|
|
// Verify success toast
|
|
await expect(page.getByText("API Key 已保存")).toBeVisible();
|
|
});
|
|
|
|
test("空 Key 校验", async ({ page }) => {
|
|
await page.goto("/settings");
|
|
await page.getByTestId("apikey-save").click();
|
|
|
|
// Verify error toast
|
|
await expect(page.getByText("请输入 API Key")).toBeVisible();
|
|
});
|
|
|
|
test("保存失败", async ({ page }) => {
|
|
await page.route(/\/api\/settings/, async (route) => {
|
|
if (route.request().method() === "POST") {
|
|
await route.fulfill({
|
|
status: 500,
|
|
contentType: "application/json",
|
|
body: JSON.stringify({ error: "服务器错误" }),
|
|
});
|
|
}
|
|
});
|
|
|
|
await page.goto("/settings");
|
|
await page.getByTestId("apikey-input").fill("test-api-key-123");
|
|
await page.getByTestId("apikey-save").click();
|
|
|
|
// Verify failure toast
|
|
await expect(page.getByText("保存失败,请重试")).toBeVisible();
|
|
});
|
|
|
|
test("刷新间隔切换", async ({ page }) => {
|
|
await page.goto("/settings");
|
|
|
|
// Default is 30 minutes — it should have selected styles
|
|
const thirtyMinBtn = page.getByRole("button", { name: "30 分钟" });
|
|
await expect(thirtyMinBtn).toHaveClass(/border-blue-500/);
|
|
|
|
// Click 10 minutes
|
|
const tenMinBtn = page.getByRole("button", { name: "10 分钟" });
|
|
await tenMinBtn.click();
|
|
|
|
// 10 min should now be selected
|
|
await expect(tenMinBtn).toHaveClass(/border-blue-500/);
|
|
// 30 min should be deselected
|
|
await expect(thirtyMinBtn).not.toHaveClass(/border-blue-500/);
|
|
});
|
|
});
|