修复报销进度审批节点覆盖(07-27-yang-jun-reimbursement-readiness)
这个提交包含在:
@@ -79,6 +79,8 @@ export class ReimbursementDetailPageObject {
|
||||
}
|
||||
|
||||
async uploadInvoicePdf(fileName: string, buffer: Buffer) {
|
||||
const invoiceCards = this.invoices.locator(":scope > div");
|
||||
const invoiceCountBeforeUpload = await invoiceCards.count();
|
||||
await this.invoiceAddBtn.click();
|
||||
await expect(this.invoiceDialog).toBeVisible();
|
||||
|
||||
@@ -101,7 +103,7 @@ export class ReimbursementDetailPageObject {
|
||||
throw new Error(`上传发票后未返回票据 ID: ${JSON.stringify(uploadPayload)}`);
|
||||
}
|
||||
|
||||
await expect(this.invoices).toContainText(fileName, { timeout: 90_000 });
|
||||
await expect(invoiceCards).toHaveCount(invoiceCountBeforeUpload + 1, { timeout: 90_000 });
|
||||
await this.page.keyboard.press("Escape");
|
||||
await expect(this.invoiceDialog).toHaveCount(0);
|
||||
|
||||
|
||||
@@ -153,6 +153,7 @@ const reimbursementDetail = {
|
||||
stages: [
|
||||
{ key: "submitted", label: "申请提交", state: "completed", actorName: visualMe.name, occurredAt: "2026-05-27T09:00:00.000Z", result: "已提交", comment: null, detail: null, targetHref: null },
|
||||
{ key: "manager_approval", label: "主管审批", state: "current", actorName: visualMe.name, occurredAt: "2026-05-27T09:00:00.000Z", result: "处理中", comment: null, detail: "待主管审批处理", targetHref: null },
|
||||
{ key: "approval_extra-review", label: "负责人复核", state: "pending", actorName: null, occurredAt: null, result: null, comment: null, detail: "待处理", targetHref: null },
|
||||
{ key: "finance_review", label: "财务复核", state: "pending", actorName: null, occurredAt: null, result: null, comment: null, detail: "待处理", targetHref: null },
|
||||
{ key: "payment_batch_review", label: "付款批次复核", state: "pending", actorName: null, occurredAt: null, result: null, comment: null, detail: "待财务创建付款批次", targetHref: null },
|
||||
{ key: "payment_and_receipt", label: "付款与回单", state: "pending", actorName: null, occurredAt: null, result: null, comment: null, detail: "待付款批次复核后处理", targetHref: null },
|
||||
@@ -1096,6 +1097,7 @@ test("报销详情固定使用上海时区并收敛只读信息", async ({ page
|
||||
await expect(page.getByTestId("reimbursement-materials").getByRole("button", { name: /查看发票原件/ })).toHaveCount(1);
|
||||
await expect(page.getByTestId("reimbursement-materials").getByRole("button", { name: /查看补充附件/ })).toHaveCount(1);
|
||||
await expect(page.getByTestId("reimbursement-materials").getByRole("button", { name: /移除|删除/ })).toHaveCount(0);
|
||||
await expect(page.getByTestId("reimbursement-workflow-progress")).toContainText("负责人复核");
|
||||
await expect(page.getByTestId("reimbursement-workflow-progress")).toContainText("付款批次复核");
|
||||
await expect(page.getByTestId("reimbursement-workflow-progress")).not.toContainText(/第 \d+ 步/);
|
||||
|
||||
@@ -1107,6 +1109,7 @@ test("报销详情固定使用上海时区并收敛只读信息", async ({ page
|
||||
await expect(page.getByRole("heading", { name: "报销概况" })).toBeVisible();
|
||||
await expect(page.getByRole("heading", { name: "当前办理摘要" })).toHaveCount(0);
|
||||
await expect(page.getByTestId("mobile-reimbursement-detail-focus")).toContainText(visualMe.name);
|
||||
await expect(page.getByTestId("mobile-reimbursement-processing-progress")).toContainText("负责人复核");
|
||||
await expect(page.getByTestId("mobile-reimbursement-attachments")).toContainText("2026年5月27日 17:10");
|
||||
await expect(page.getByTestId("mobile-reimbursement-materials").getByRole("button", { name: /查看发票原件/ })).toHaveCount(1);
|
||||
await expect(page.getByTestId("mobile-reimbursement-materials").getByRole("button", { name: /查看补充附件/ })).toHaveCount(1);
|
||||
|
||||
@@ -6,8 +6,8 @@ import { openNavLink } from "./helpers/navigation";
|
||||
|
||||
async function firstEnabledExpenseTypeId(api: APIRequestContext) {
|
||||
const response = await api.get("/api/expense-types?enabled=true");
|
||||
const payload = await response.json() as { data?: { items?: Array<{ id: string; enabled?: boolean }> } };
|
||||
const item = payload.data?.items?.find((candidate) => candidate.enabled !== false) ?? payload.data?.items?.[0];
|
||||
const payload = await response.json() as { data?: { items?: Array<{ id: string; enabled?: boolean; category?: string | null }> } };
|
||||
const item = payload.data?.items?.find((candidate) => candidate.enabled !== false && candidate.category !== "travel");
|
||||
if (!response.ok() || !item?.id) {
|
||||
throw new Error(`无法读取费用类型:HTTP ${response.status()}`);
|
||||
}
|
||||
@@ -29,7 +29,7 @@ async function createReimbursementItem(api: APIRequestContext, reimbursementId:
|
||||
}
|
||||
}
|
||||
|
||||
test("E2E 报销处理进度:提交后详情页展示五阶段职责进度", async ({ page, reimbursementDetail }) => {
|
||||
test("E2E 报销处理进度:提交后按真实 workflow 展示职责进度", async ({ page, reimbursementDetail }) => {
|
||||
const apiClient = await createAuthenticatedApiClient(EMPLOYEE);
|
||||
await login(page, EMPLOYEE);
|
||||
|
||||
@@ -67,9 +67,10 @@ test("E2E 报销处理进度:提交后详情页展示五阶段职责进度", a
|
||||
|
||||
await expect(page.getByText(/reviewing|审批中/).first()).toBeVisible({ timeout: 30_000 });
|
||||
await expect(reimbursementDetail.workflowProgress).toBeVisible({ timeout: 30_000 });
|
||||
await expect(reimbursementDetail.workflowProgress.locator(":scope > li")).toHaveCount(4);
|
||||
await expect(reimbursementDetail.workflowProgress).toContainText("申请提交");
|
||||
await expect(reimbursementDetail.workflowProgress).toContainText("主管审批");
|
||||
await expect(reimbursementDetail.workflowProgress).toContainText("财务复核");
|
||||
await expect(reimbursementDetail.workflowProgress).toContainText("审批");
|
||||
await expect(reimbursementDetail.workflowProgress).not.toContainText("审批节点1");
|
||||
await expect(reimbursementDetail.workflowProgress).toContainText("付款批次复核");
|
||||
await expect(reimbursementDetail.workflowProgress).toContainText("付款与回单");
|
||||
await expect(reimbursementDetail.workflowProgress).not.toContainText(/第 \d+ 步/);
|
||||
|
||||
在新工单中引用
屏蔽一个用户