R98 A5 支持 smoke 账号复核真实 OCR
这个提交包含在:
@@ -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);
|
||||||
});
|
});
|
||||||
|
|||||||
在新工单中引用
屏蔽一个用户