文件
hyb-oa/client/tests/e2e/interaction-pattern-unification.spec.ts
T

102 行
5.1 KiB
TypeScript

import { readFileSync, readdirSync } from "node:fs";
import path from "node:path";
import { expect, test } from "@playwright/test";
import { ApiError } from "../../src/api/types";
import { resolveErrorMessage } from "../../src/lib/resolveErrorMessage";
function source(relativePath: string) {
return readFileSync(path.resolve(process.cwd(), relativePath), "utf8");
}
function sourceFiles(relativeDirectory: string): string[] {
const absoluteDirectory = path.resolve(process.cwd(), relativeDirectory);
return readdirSync(absoluteDirectory, { withFileTypes: true }).flatMap((entry) => {
const relativePath = path.join(relativeDirectory, entry.name);
if (entry.isDirectory()) {
return sourceFiles(relativePath);
}
return /\.(ts|tsx)$/.test(entry.name) ? [relativePath] : [];
});
}
test("R12 普通用户错误消息只经过共享解析入口且不显示内部 code", () => {
const resolver = source("src/lib/resolveErrorMessage.ts");
expect(resolver).toContain("mapApiErrorMessage(error.code, error.details, error.message)");
expect(resolver).not.toMatch(/`\$\{error\.code\}:/);
const ordinaryFiles = ["src/pages", "src/components", "src/lib"]
.flatMap(sourceFiles)
.filter((file) => file !== "src/pages/AuditLogsPage.tsx");
const residuals = ordinaryFiles.filter((file) => {
const text = source(file);
return /\$\{[^}]*\.code\}:|\{[^}\n]*\.code\}:/.test(text);
});
const directMapperConsumers = ordinaryFiles.filter((file) => {
if (file === "src/lib/resolveErrorMessage.ts") return false;
return source(file).includes("mapApiErrorMessage");
});
const rawThrownMessageConsumers = ordinaryFiles.filter((file) => {
if (file === "src/lib/resolveErrorMessage.ts") return false;
return /\b(?:error|err)\.message\b/.test(source(file));
});
expect(residuals).toEqual([]);
expect(directMapperConsumers).toEqual([]);
expect(rawThrownMessageConsumers).toEqual([]);
expect(resolveErrorMessage(new ApiError({ status: 400, code: "VALID_001", message: "VALID_001: 请补充审批意见" }))).toBe("请补充审批意见");
expect(resolveErrorMessage(new Error("500: 保存失败"), "保存失败,请稍后重试")).toBe("保存失败");
expect(resolveErrorMessage(new Error("Failed to fetch /api/workflow/tasks"), "加载审批任务失败")).toBe("加载审批任务失败");
expect(resolveErrorMessage(new Error("读取失败 /tmp/private/payload.json"), "读取资料失败")).toBe("读取资料失败");
});
test("R10 移动审批与移动报销复用同一底部动作容器", () => {
const sharedActionBar = source("src/components/patterns/MobileStickyActionBar.tsx");
const businessEditTemplate = source("src/components/patterns/BusinessEditTemplate.tsx");
const mobileApprovals = source("src/pages/MobileApprovalsPage.tsx");
const mobileReimbursement = source("src/pages/MobileReimbursementDetailPage.tsx");
expect(sharedActionBar).toContain("mobile-sticky-action-surface fixed inset-x-0 bottom-0");
expect(sharedActionBar).toContain("env(safe-area-inset-bottom,0px)");
expect(businessEditTemplate).toContain("MOBILE_STICKY_ACTION_PAGE_CLASS");
expect(businessEditTemplate).toContain("<MobileStickyActionBar");
expect(mobileApprovals).toContain("<MobileStickyActionBar");
expect(mobileReimbursement).toContain("<MobileStickyActionBar");
expect(mobileApprovals).not.toContain('className="mobile-sticky-action-surface fixed');
expect(mobileReimbursement).not.toContain('className="mobile-sticky-action-surface fixed');
});
test("R1/R6 未知状态和个人事项状态不回落到技术枚举", () => {
const statusBadge = source("src/components/common/StatusBadge.tsx");
const todosPage = source("src/pages/TodosPage.tsx");
expect(statusBadge).toContain('label: "未知状态"');
expect(statusBadge).not.toContain('label: status, className: "badge-neutral"');
expect(todosPage).toContain('todo: "待处理"');
expect(todosPage).toContain('doing: "进行中"');
expect(todosPage).toContain('done: "已完成"');
expect(todosPage).toContain('cancelled: "已取消"');
});
test("R4 WelcomeDialog 只在存在权限过滤后的入口时打开", () => {
const portalHome = source("src/pages/PortalHomePage.tsx");
expect(portalHome).toContain("open={showWelcome && welcomeLinks.length > 0}");
expect(portalHome).toContain("if (roleCapabilities.canApproveTasks && hasAnyPermission(permissions, APPROVAL_PORTAL_PERMISSIONS))");
});
test("R9/R11 工作台加载失败提供重试且主要入口具有焦点样式", () => {
const portalHome = source("src/pages/PortalHomePage.tsx");
expect(portalHome).toContain('data-testid="portal-load-error"');
expect(portalHome).toContain('data-testid="portal-load-retry"');
expect(portalHome).toContain("portalQuery.refetch()");
expect(portalHome).toContain("focus-visible:ring-2 focus-visible:ring-blue-600");
});
test("R14 差旅列表不再自动选择第一条记录", () => {
const travelRequests = source("src/pages/TravelRequestsPage.tsx");
expect(travelRequests).not.toContain("listQuery.data?.items?.[0]?.id");
expect(travelRequests).toContain('const [searchParams, setSearchParams] = useSearchParams()');
});