R74-A2 A3 A4 压榨试运行自动化空间
这个提交包含在:
@@ -0,0 +1,67 @@
|
||||
import { expect, type Page } from "@playwright/test";
|
||||
|
||||
export type LiveInvoiceOcrStatus = "available" | "ocr_failed";
|
||||
|
||||
export type LiveInvoiceOcrResult = {
|
||||
status: LiveInvoiceOcrStatus;
|
||||
detailText: string;
|
||||
bannerText: string;
|
||||
durationMs: number;
|
||||
invoiceId: string | null;
|
||||
invoiceCode: string | null;
|
||||
invoiceNumber: string | null;
|
||||
sellerName: string | null;
|
||||
totalAmount: string | null;
|
||||
invoiceDate: string | null;
|
||||
};
|
||||
|
||||
function extractField(detailText: string, label: string) {
|
||||
const escaped = label.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
||||
const match = detailText.match(new RegExp(`${escaped}([^\\n]+)`));
|
||||
return match?.[1]?.trim() || null;
|
||||
}
|
||||
|
||||
export async function openInvoicePool(page: Page) {
|
||||
await page.goto("/invoice-pool");
|
||||
await expect(page.getByTestId("invoice-pool-table")).toBeVisible();
|
||||
}
|
||||
|
||||
export async function uploadLiveInvoiceAndWait(page: Page, invoiceFilePath: string, timeout = 180_000): Promise<LiveInvoiceOcrResult> {
|
||||
const startedAt = Date.now();
|
||||
|
||||
await page.getByTestId("invoice-upload-file").setInputFiles(invoiceFilePath);
|
||||
await page.getByTestId("invoice-upload-submit").click();
|
||||
|
||||
const detailPanel = page.getByTestId("invoice-detail-panel");
|
||||
await expect(detailPanel).toBeVisible({ timeout: 30_000 });
|
||||
|
||||
await expect
|
||||
.poll(async () => {
|
||||
const text = await detailPanel.innerText().catch(() => "");
|
||||
if (text.includes("状态:available")) return "available";
|
||||
if (text.includes("状态:ocr_failed")) return "ocr_failed";
|
||||
return "pending_ocr";
|
||||
}, { timeout })
|
||||
.not.toBe("pending_ocr");
|
||||
|
||||
const detailText = await detailPanel.innerText();
|
||||
const bannerText = await page.getByTestId("invoice-ocr-status-banner").innerText().catch(() => "");
|
||||
const status = detailText.includes("状态:ocr_failed") ? "ocr_failed" : "available";
|
||||
const invoiceNo = extractField(detailText, "发票号:");
|
||||
const [invoiceCode, invoiceNumber] = invoiceNo && invoiceNo.includes("-")
|
||||
? invoiceNo.split("-", 2).map((item) => item.trim() || null)
|
||||
: [invoiceNo, null];
|
||||
|
||||
return {
|
||||
status,
|
||||
detailText,
|
||||
bannerText,
|
||||
durationMs: Date.now() - startedAt,
|
||||
invoiceId: extractField(detailText, "票据ID:"),
|
||||
invoiceCode,
|
||||
invoiceNumber,
|
||||
sellerName: extractField(detailText, "销售方:"),
|
||||
totalAmount: extractField(detailText, "总金额:"),
|
||||
invoiceDate: extractField(detailText, "开票日期:"),
|
||||
};
|
||||
}
|
||||
在新工单中引用
屏蔽一个用户