import { test, expect } from "@playwright/test"; /** * RPA Worker E2E(task-088) * 通过 mock API 模拟 RPA 正常/超时/失败场景 */ test.describe("RPA 链路 E2E mock", () => { test("TC-601:正常流程返回 4 档报价(items.length===4)", async ({ page }) => { let quoteItemCount = 0; await page.route("**/api/quotes", async (route) => { if (route.request().method() === "POST") { await route.fulfill({ status: 200, contentType: "application/json", body: JSON.stringify({ code: 0, message: "ok", data: { quote_id: "QTE_RPA_001", status: "processing", source_type: "rpa", }, }), }); return; } await route.continue(); }); await page.route("**/api/quotes/QTE_RPA_001", async (route) => { const payload = { code: 0, message: "ok", data: { quote_id: "QTE_RPA_001", request_id: "req-rpa", status: "done", source_type: "rpa", is_realtime: true, currency: "USD", valid_until: new Date(Date.now() + 180_000).toISOString(), quotes: [ { service_level: "standard", rate_option: "lowest", carrier: "M", transit_days: "5", transit_description: "最低", raw_freight: 320, surcharges: 0, raw_total: 320, markup_percent: 0, markup_amount: 0, final_total: 320, breakdown: [], }, { service_level: "standard", rate_option: "fastest", carrier: "M", transit_days: "3", transit_description: "最快", raw_freight: 365, surcharges: 0, raw_total: 365, markup_percent: 0, markup_amount: 0, final_total: 365, breakdown: [], }, { service_level: "guaranteed", rate_option: "lowest", carrier: "M", transit_days: "4", transit_description: "保价最低", raw_freight: 380, surcharges: 0, raw_total: 380, markup_percent: 0, markup_amount: 0, final_total: 380, breakdown: [], }, { service_level: "guaranteed", rate_option: "fastest", carrier: "M", transit_days: "2", transit_description: "保价最快", raw_freight: 410, surcharges: 0, raw_total: 410, markup_percent: 0, markup_amount: 0, final_total: 410, breakdown: [], }, ], }, }; quoteItemCount = payload.data.quotes.length; await route.fulfill({ status: 200, contentType: "application/json", body: JSON.stringify(payload), }); }); await page.goto("/embed-demo"); await expect( page.getByRole("heading", { name: "卡派查价" }), ).toBeVisible({ timeout: 30_000 }); 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"); await page.getByRole("button", { name: "获取报价" }).click(); await expect(page.getByRole("button", { name: "标准" })).toBeVisible({ timeout: 20_000, }); await expect(page.getByRole("button", { name: "保证送达" })).toBeVisible(); expect(quoteItemCount).toBe(4); }); test("TC-602:RPA 失败 → 错误提示", async ({ page }) => { await page.route("**/api/quotes", async (route) => { await route.fulfill({ status: 200, contentType: "application/json", body: JSON.stringify({ code: 0, message: "ok", data: { quote_id: "QTE_FAIL", status: "processing" }, }), }); }); await page.route("**/api/quotes/QTE_FAIL", async (route) => { await route.fulfill({ status: 200, contentType: "application/json", body: JSON.stringify({ code: 0, message: "ok", data: { quote_id: "QTE_FAIL", request_id: "req-fail", status: "failed", error_code: "RPA_FAILED", currency: "USD", }, }), }); }); await page.goto("/embed-demo"); await expect( page.getByRole("heading", { name: "卡派查价" }), ).toBeVisible({ timeout: 30_000 }); 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"); await page.getByRole("button", { name: "获取报价" }).click(); await expect( page.getByText("暂时无法获取报价"), ).toBeVisible({ timeout: 20_000 }); }); });