You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

129 lines
4.7 KiB

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,
});
});
});