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