B1-B8 建立项目级流程与QA门禁
这个提交包含在:
@@ -2,16 +2,8 @@ import { expect, test } from "@playwright/test";
|
||||
import { createAuthenticatedApiClient, EMPLOYEE, FINANCE_MGR, login, logout, MANAGER } from "./helpers/auth";
|
||||
import { createAndSubmitTravelRequestViaUi, importTravelPaymentSeed } from "./helpers/travel";
|
||||
|
||||
function extractId(text: string, label: string) {
|
||||
const match = text.match(new RegExp(`${label}:([0-9a-f-]{36})`));
|
||||
if (!match?.[1]) {
|
||||
throw new Error(`Failed to parse ${label} from text: ${text}`);
|
||||
}
|
||||
return match[1];
|
||||
}
|
||||
|
||||
function extractInvoiceCode(text: string) {
|
||||
const match = text.match(/发票号:([A-Z0-9]+)-/);
|
||||
const match = text.match(/发票(?:号|号码):([A-Z0-9]+)-/);
|
||||
if (!match?.[1]) {
|
||||
throw new Error(`Failed to parse invoice code from text: ${text}`);
|
||||
}
|
||||
@@ -61,16 +53,25 @@ test("E2E 差旅支付主链路:申请→审批→支付→绑票", async ({ p
|
||||
|
||||
await page.goto("/invoice-pool");
|
||||
const invoiceFileName = `travel-payment-${Date.now()}.png`;
|
||||
const uploadResponsePromise = page.waitForResponse((response) => {
|
||||
const url = new URL(response.url());
|
||||
return response.request().method() === "POST" && url.pathname === "/api/invoice-pool/upload" && response.ok();
|
||||
});
|
||||
await page.getByTestId("invoice-upload-file").setInputFiles({
|
||||
name: invoiceFileName,
|
||||
mimeType: "image/png",
|
||||
buffer: Buffer.from(`TRAVEL_PAYMENT_${Date.now()}`, "utf8"),
|
||||
});
|
||||
await page.getByTestId("invoice-upload-submit").click();
|
||||
const uploadPayload = (await (await uploadResponsePromise).json()) as { data?: { invoicePoolId?: string | null } };
|
||||
const invoiceId = uploadPayload.data?.invoicePoolId;
|
||||
if (!invoiceId) {
|
||||
throw new Error(`上传发票后未返回票据 ID: ${JSON.stringify(uploadPayload)}`);
|
||||
}
|
||||
|
||||
await expect(page.getByTestId("invoice-detail-panel")).toBeVisible();
|
||||
await expect(page.getByTestId("invoice-detail-panel")).toContainText("状态:available", { timeout: 90_000 });
|
||||
await expect(page.getByTestId("invoice-detail-panel")).toContainText("状态:可用", { timeout: 90_000 });
|
||||
const invoiceDetailText = await page.getByTestId("invoice-detail-panel").innerText();
|
||||
const invoiceId = extractId(invoiceDetailText, "票据ID");
|
||||
const invoiceCode = extractInvoiceCode(invoiceDetailText);
|
||||
|
||||
await page.reload();
|
||||
|
||||
在新工单中引用
屏蔽一个用户