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.

207 lines
5.3 KiB

import type { Page, Route } from "@playwright/test";
export const FOUR_TIER_QUOTES = [
{
service_level: "standard",
rate_option: "lowest",
carrier: "Mothership",
transit_days: "5-7",
transit_description: "最低价格",
raw_freight: 320,
surcharges: 15,
raw_total: 335,
markup_percent: 0,
markup_amount: 0,
final_total: 335,
breakdown: [
{ item: "基础运费", amount: 320 },
{ item: "附加费", amount: 15 },
{ item: "加价", amount: 0 },
],
},
{
service_level: "standard",
rate_option: "fastest",
carrier: "Mothership",
transit_days: "3-4",
transit_description: "最快送达",
raw_freight: 365,
surcharges: 0,
raw_total: 365,
markup_percent: 0,
markup_amount: 0,
final_total: 365,
breakdown: [
{ item: "基础运费", amount: 365 },
{ item: "附加费", amount: 0 },
{ item: "加价", amount: 0 },
],
},
{
service_level: "guaranteed",
rate_option: "lowest",
carrier: "Mothership",
transit_days: "4-5",
transit_description: "保价最低",
raw_freight: 380,
surcharges: 0,
raw_total: 380,
markup_percent: 0,
markup_amount: 0,
final_total: 380,
breakdown: [
{ item: "基础运费", amount: 380 },
{ item: "附加费", amount: 0 },
{ item: "加价", amount: 0 },
],
},
{
service_level: "guaranteed",
rate_option: "fastest",
carrier: "Mothership",
transit_days: "2-3",
transit_description: "保价最快",
raw_freight: 410,
surcharges: 0,
raw_total: 410,
markup_percent: 0,
markup_amount: 0,
final_total: 410,
breakdown: [
{ item: "基础运费", amount: 410 },
{ item: "附加费", amount: 0 },
{ item: "加价", amount: 0 },
],
},
];
type MockMode = "cache" | "processing" | "stale" | "error";
export async function mockQuoteApi(
page: Page,
mode: MockMode,
): Promise<void> {
let pollCount = 0;
await page.route("**/api/quotes", async (route: Route) => {
if (route.request().method() === "POST") {
if (mode === "error") {
await route.fulfill({
status: 400,
contentType: "application/json",
body: JSON.stringify({
code: "VALIDATION_FAILED",
message: "请求参数无效",
data: null,
}),
});
return;
}
const status = mode === "processing" ? "processing" : "done";
await route.fulfill({
status: 200,
contentType: "application/json",
body: JSON.stringify({
code: 0,
message: "ok",
data: {
quote_id: "QTE_E2E_001",
status,
source_type: mode === "stale" ? "stale" : "cache",
is_realtime: mode !== "stale",
},
}),
});
return;
}
await route.continue();
});
await page.route("**/api/quotes/*", async (route: Route) => {
if (route.request().method() !== "GET") {
await route.continue();
return;
}
if (mode === "processing") {
pollCount += 1;
if (pollCount < 2) {
await route.fulfill({
status: 200,
contentType: "application/json",
body: JSON.stringify({
code: 0,
message: "ok",
data: {
quote_id: "QTE_E2E_001",
request_id: "req-e2e",
status: "processing",
currency: "USD",
},
}),
});
return;
}
}
if (mode === "error") {
await route.fulfill({
status: 500,
contentType: "application/json",
body: JSON.stringify({
code: "INTERNAL_ERROR",
message: "服务异常",
data: null,
}),
});
return;
}
await route.fulfill({
status: 200,
contentType: "application/json",
body: JSON.stringify({
code: 0,
message: "ok",
data: {
quote_id: "QTE_E2E_001",
request_id: "req-e2e",
status: "done",
currency: "USD",
source_type: mode === "stale" ? "stale" : "cache",
is_realtime: mode !== "stale",
confidence_score: mode === "stale" ? 0.6 : 1,
valid_until: new Date(Date.now() + 180_000).toISOString(),
quotes: FOUR_TIER_QUOTES,
},
}),
});
});
}
export async function fillQuoteForm(page: Page): Promise<void> {
await page.locator('input[name="p_street"]').fill("1234 Warehouse Blvd");
await page.locator('input[name="p_city"]').fill("Los Angeles");
await page.locator('select[name="p_state"]').selectOption("CA");
await page.locator('input[name="p_zip"]').fill("90001");
await page
.getByRole("button")
.filter({ hasText: "Los Angeles" })
.first()
.click();
await page.locator('input[name="d_street"]').fill("5678 Distribution Dr");
await page.locator('input[name="d_city"]').fill("Dallas");
await page.locator('select[name="d_state"]').selectOption("TX");
await page.locator('input[name="d_zip"]').fill("75201");
await page
.getByRole("button")
.filter({ hasText: "Dallas" })
.first()
.click();
await page.locator('input[name="weight"]').fill("500");
await page.locator('input[name="pallet_count"]').fill("2");
}