import { test, expect, type APIRequestContext } from "@playwright/test"; async function login(page: import("@playwright/test").Page) { const res = await page.request.post("/api/auth/login", { data: { username: "admin", password: "admin123" }, }); expect(res.ok(), await res.text()).toBeTruthy(); await page.goto("/mails"); await expect(page).toHaveURL(/\/mails/, { timeout: 20_000 }); } async function injectFixture(request: APIRequestContext, fixtureId: string) { const res = await request.post("/api/test/inject", { data: { fixture_id: fixtureId }, }); if (res.status() === 404) { test.skip(true, "Server is not in TEST_MODE"); } expect(res.ok(), await res.text()).toBeTruthy(); return res.json() as Promise<{ ok: true; data: { mail_id: string; status: string; mail_type: string; last_error: string | null; version: number; subject: string; }; }>; } test.describe("TEST_MODE pipeline e2e", () => { test("inject forecast → UI 待确认 → submit → MockTargetAPI 收到柜号", async ({ page, }) => { const api = page.request; await login(page); await api.post("/api/test/reset"); const injected = await injectFixture(api, "01-normal-forecast"); const mailId = injected.data.mail_id; await page.goto(`/mails/${mailId}`); await expect(page.getByText(/待确认/).first()).toBeVisible({ timeout: 15_000 }); await expect(page.getByText(/WHSU8127240/).first()).toBeVisible(); const detail = await api.get(`/api/mails/${mailId}`); const body = await detail.json(); const shipments = body.data?.parse_result?.shipments || []; const indexes = shipments .filter((s: { row_status?: string; row_index: number }) => s.row_status === "VALID") .map((s: { row_index: number }) => s.row_index); const imported = await api.post(`/api/mails/${mailId}/import`, { data: { version: body.data.version, idempotency_key: `e2e-${Date.now()}`, F_TransMode: 0, F_OperationType: 0, container_header: { F_ContainerNo: `TPZU${String(Date.now()).slice(-7)}` }, selected_row_indexes: indexes, ack_unmapped_channels: true, force_skip_conflict: true, }, }); const importedJson = await imported.json(); expect(importedJson.ok, JSON.stringify(importedJson)).toBe(true); expect(importedJson.data?.mail_status).toBe("SUCCESS"); const rec = await api.get("/api/test/target-requests"); const recBody = await rec.json(); const saves = (recBody.data?.requests || []).filter( (r: { path: string }) => r.path === "/Container/SaveContainer", ); expect(saves.length).toBeGreaterThan(0); expect(JSON.stringify(saves[0].body)).toMatch(/LAS1|WHSU8127240|TPZU/); await page.reload(); await expect(page.getByText(/导入成功/).first()).toBeVisible({ timeout: 15_000 }); }); test("fault: missing attachment shows parse failure on detail", async ({ page }) => { await login(page); const injected = await injectFixture(page.request, "09-no-attachment"); await page.goto(`/mails/${injected.data.mail_id}`); await expect(page.getByText(/校验拒绝|未解析到货件/).first()).toBeVisible({ timeout: 15_000, }); }); test("fault: target 401 keeps mail failed with visible error", async ({ page }) => { const api = page.request; await login(page); await api.post("/api/test/reset"); const injected = await injectFixture(api, "01-normal-forecast"); const mailId = injected.data.mail_id; await api.post("/api/test/faults", { data: { target: "401", target_path: "/Container/SaveContainer" }, }); const detail = await api.get(`/api/mails/${mailId}`); const body = await detail.json(); const shipments = body.data?.parse_result?.shipments || []; const indexes = shipments .filter((s: { row_status?: string; row_index: number }) => s.row_status === "VALID") .map((s: { row_index: number }) => s.row_index); const imported = await api.post(`/api/mails/${mailId}/import`, { data: { version: body.data.version, idempotency_key: `e2e-401-${Date.now()}`, F_TransMode: 0, F_OperationType: 0, container_header: { F_ContainerNo: `TPZU${String(Date.now()).slice(-7)}` }, selected_row_indexes: indexes, ack_unmapped_channels: true, force_skip_conflict: true, }, }); const importedJson = await imported.json(); expect(importedJson.data?.mail_status || importedJson.error).toBeTruthy(); await page.goto(`/mails/${mailId}`); await expect(page.getByText(/导入失败|登录失败|权限|CarrierCentral/i).first()).toBeVisible({ timeout: 15_000, }); }); });