R98 A5 支持 smoke 账号复核真实 OCR

这个提交包含在:
2026-05-06 20:44:57 +08:00
父节点 2d0c506a58
当前提交 8b8a27d0ac
共修改 3 个文件,包含 38 行新增和 8 行删除
@@ -1,5 +1,7 @@
import { expect, type Page } from "@playwright/test"; import { expect, type Page } from "@playwright/test";
import type { E2EUser } from "./auth";
export type LiveInvoiceOcrStatus = "available" | "ocr_failed"; export type LiveInvoiceOcrStatus = "available" | "ocr_failed";
export type LiveInvoiceOcrResult = { export type LiveInvoiceOcrResult = {
@@ -21,6 +23,31 @@ function extractField(detailText: string, label: string) {
return match?.[1]?.trim() || null; return match?.[1]?.trim() || null;
} }
export function resolveLiveOcrUser(fallback: E2EUser): E2EUser {
const identifier =
process.env.PLAYWRIGHT_OCR_LIVE_IDENTIFIER?.trim() ||
process.env.LIVE_SMOKE_EMPLOYEE_IDENTIFIER?.trim() ||
"";
const password =
process.env.PLAYWRIGHT_OCR_LIVE_PASSWORD?.trim() ||
process.env.LIVE_SMOKE_EMPLOYEE_PASSWORD?.trim() ||
"";
if (!identifier && !password) {
return fallback;
}
if (!identifier || !password) {
throw new Error("PLAYWRIGHT_OCR_LIVE_IDENTIFIER/PASSWORD 或 LIVE_SMOKE_EMPLOYEE_* 必须成对提供");
}
return {
identifier,
password,
name: process.env.PLAYWRIGHT_OCR_LIVE_NAME?.trim() || "Smoke Employee",
};
}
export async function openInvoicePool(page: Page) { export async function openInvoicePool(page: Page) {
await page.goto("/invoice-pool"); await page.goto("/invoice-pool");
await expect(page.getByTestId("invoice-pool-table")).toBeVisible(); await expect(page.getByTestId("invoice-pool-table")).toBeVisible();
@@ -2,8 +2,8 @@ import { existsSync, mkdirSync, readdirSync, statSync, writeFileSync } from "nod
import path from "node:path"; import path from "node:path";
import { expect, test } from "../helpers/fixtures"; import { expect, test } from "../helpers/fixtures";
import { EMPLOYEE, login, logout } from "../helpers/auth"; import { EMPLOYEE, login } from "../helpers/auth";
import { openInvoicePool, uploadLiveInvoiceAndWait, type LiveInvoiceOcrResult } from "../helpers/liveInvoiceOcr"; import { openInvoicePool, resolveLiveOcrUser, uploadLiveInvoiceAndWait, type LiveInvoiceOcrResult } from "../helpers/liveInvoiceOcr";
type BatchResult = LiveInvoiceOcrResult & { type BatchResult = LiveInvoiceOcrResult & {
filePath: string; filePath: string;
@@ -79,7 +79,8 @@ test("手工 live 腾讯 OCR 批量辅助复核:真实票样逐张上传并输
test.skip(!invoiceFiles.length, "需要提供 PLAYWRIGHT_OCR_LIVE_FILE / PLAYWRIGHT_OCR_LIVE_FILES / PLAYWRIGHT_OCR_LIVE_DIR"); test.skip(!invoiceFiles.length, "需要提供 PLAYWRIGHT_OCR_LIVE_FILE / PLAYWRIGHT_OCR_LIVE_FILES / PLAYWRIGHT_OCR_LIVE_DIR");
const results: BatchResult[] = []; const results: BatchResult[] = [];
await login(page, EMPLOYEE); const liveOcrUser = resolveLiveOcrUser(EMPLOYEE);
await login(page, liveOcrUser);
try { try {
await openInvoicePool(page); await openInvoicePool(page);
@@ -95,7 +96,7 @@ test("手工 live 腾讯 OCR 批量辅助复核:真实票样逐张上传并输
} }
} finally { } finally {
writeReport(results); writeReport(results);
await logout(page, EMPLOYEE.name).catch(() => undefined); await page.context().clearCookies().catch(() => undefined);
} }
const failures = results.filter((item) => item.status === "ocr_failed"); const failures = results.filter((item) => item.status === "ocr_failed");
@@ -1,8 +1,8 @@
import { existsSync } from "node:fs"; import { existsSync } from "node:fs";
import { test, expect } from "../helpers/fixtures"; import { test, expect } from "../helpers/fixtures";
import { EMPLOYEE, login, logout } from "../helpers/auth"; import { EMPLOYEE, login } from "../helpers/auth";
import { openInvoicePool, uploadLiveInvoiceAndWait } from "../helpers/liveInvoiceOcr"; import { openInvoicePool, resolveLiveOcrUser, uploadLiveInvoiceAndWait } from "../helpers/liveInvoiceOcr";
test("手工 live 腾讯 OCR 辅助复核:真实 VAT 发票上传后进入可处理状态", async ({ page }) => { test("手工 live 腾讯 OCR 辅助复核:真实 VAT 发票上传后进入可处理状态", async ({ page }) => {
test.skip(process.env.PLAYWRIGHT_MANUAL !== "1", "仅在显式手工 Playwright 模式下执行"); test.skip(process.env.PLAYWRIGHT_MANUAL !== "1", "仅在显式手工 Playwright 模式下执行");
@@ -11,7 +11,9 @@ test("手工 live 腾讯 OCR 辅助复核:真实 VAT 发票上传后进入可
const invoiceFilePath = process.env.PLAYWRIGHT_OCR_LIVE_FILE?.trim() ?? ""; const invoiceFilePath = process.env.PLAYWRIGHT_OCR_LIVE_FILE?.trim() ?? "";
test.skip(!invoiceFilePath || !existsSync(invoiceFilePath), "需要提供存在的 PLAYWRIGHT_OCR_LIVE_FILE"); test.skip(!invoiceFilePath || !existsSync(invoiceFilePath), "需要提供存在的 PLAYWRIGHT_OCR_LIVE_FILE");
await login(page, EMPLOYEE); const liveOcrUser = resolveLiveOcrUser(EMPLOYEE);
await login(page, liveOcrUser);
await openInvoicePool(page); await openInvoicePool(page);
const result = await uploadLiveInvoiceAndWait(page, invoiceFilePath); const result = await uploadLiveInvoiceAndWait(page, invoiceFilePath);
@@ -23,5 +25,5 @@ test("手工 live 腾讯 OCR 辅助复核:真实 VAT 发票上传后进入可
expect(result.totalAmount, JSON.stringify(result)).toBeTruthy(); expect(result.totalAmount, JSON.stringify(result)).toBeTruthy();
expect(result.totalAmount, JSON.stringify(result)).not.toBe("-"); expect(result.totalAmount, JSON.stringify(result)).not.toBe("-");
await logout(page, EMPLOYEE.name); await page.context().clearCookies().catch(() => undefined);
}); });