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.

119 lines
3.4 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

import { describe, expect, it, vi } from "vitest";
import type { Page } from "playwright";
import { fillCargoStep } from "@/workers/rpa/kernel/steps/cargo-step";
vi.mock("@/workers/rpa/fill-cargo-in-drawer", () => ({
fillCargoInDrawer: vi.fn().mockResolvedValue({
weightDisplay: {
displayValue: "500",
unit: "lb",
weightLbPerPallet: 500,
},
expected: {
palletCount: 2,
weight: {
displayValue: "500",
unit: "lb",
weightLbPerPallet: 500,
palletCount: 2,
},
},
}),
}));
vi.mock("@/workers/rpa/cargo-lock", () => ({
assertBothAddressesLocked: vi.fn().mockResolvedValue(undefined),
settleAddressFieldsForCargo: vi.fn().mockResolvedValue(undefined),
waitForCargoCommittedState: vi.fn().mockResolvedValue({
hasSummaryChip: true,
visibleEditableCargoInputs: 0,
editorOpen: false,
internalPalletCount: 2,
internalWeight: 500,
widgetTextPreview: "",
}),
}));
const stateCalls: string[] = [];
function mockCtx() {
const page = {
waitForTimeout: vi.fn().mockResolvedValue(undefined),
locator: vi.fn().mockReturnValue({
last: vi.fn().mockReturnValue({
locator: vi.fn().mockReturnValue({ first: vi.fn() }),
}),
filter: vi.fn().mockReturnValue({ nth: vi.fn() }),
first: vi.fn(),
}),
url: vi.fn().mockReturnValue("https://example.com"),
} as unknown as Page;
return {
page,
selectors: {
specs: vi.fn().mockReturnValue(["input"]),
optionalEnv: vi.fn().mockReturnValue(undefined),
resolve: vi.fn().mockReturnValue("#widget"),
widget: vi.fn(),
},
exec: {
evaluateOnLocator: vi.fn().mockResolvedValue(false),
},
runtime: {
evaluateOnLocator: vi.fn(),
},
getWidgetScrollAt: vi.fn().mockReturnValue(0),
setWidgetScrollAt: vi.fn(),
state: {
triggerCargoSection: vi.fn().mockResolvedValue(undefined),
settleAddressEditing: vi.fn(async () => {
stateCalls.push("settle");
}),
},
};
}
describe("fillCargoStep UI flow", () => {
it("顺序fillCargoInDrawer → waitForCargoCommittedState", async () => {
const { fillCargoInDrawer } = await import("@/workers/rpa/fill-cargo-in-drawer");
const { waitForCargoCommittedState } = await import("@/workers/rpa/cargo-lock");
const ctx = mockCtx() as never;
await fillCargoStep(ctx, {
cargoHash: "t",
pickup: {} as never,
delivery: {} as never,
weightLb: 500,
dimsIn: { l: 48, w: 40, h: 48 },
palletCount: 2,
cargoType: "general_freight",
});
expect(fillCargoInDrawer).toHaveBeenCalled();
expect(waitForCargoCommittedState).toHaveBeenCalled();
});
it("fillCargoInDrawer 失败时向上抛出", async () => {
const { fillCargoInDrawer } = await import("@/workers/rpa/fill-cargo-in-drawer");
const { RpaError } = await import("@/modules/rpa/errors");
vi.mocked(fillCargoInDrawer).mockRejectedValueOnce(
new RpaError("STRUCT_CHANGE", "货物 drawer 内未找到任何重量输入框", {
retryable: true,
}),
);
const ctx = mockCtx() as never;
await expect(
fillCargoStep(ctx, {
cargoHash: "t",
pickup: {} as never,
delivery: {} as never,
weightLb: 500,
dimsIn: { l: 48, w: 40, h: 48 },
palletCount: 2,
cargoType: "general_freight",
}),
).rejects.toMatchObject({ code: "STRUCT_CHANGE" });
});
});