import { test, expect } from "@playwright/test"; import { makeEntry, mockApi, 登录 } from "../测试夹具"; test.describe("多币种:外币记账与异步换算", () => { test("01-外币账目在汇率返回前也可以完成记账", async ({ page }) => { const state = await mockApi(page); await 登录(page); await page.getByRole("button", { name: "记一笔" }).click(); await page.getByRole("button", { name: /切换币种/ }).click(); await page.getByRole("button", { name: /美元/ }).click(); await page.getByRole("button", { name: "5", exact: true }).click(); const started = Date.now(); await page.getByRole("button", { name: "完成记账" }).click(); await expect(page.getByText("已记入账本")).toBeVisible(); expect(Date.now() - started).toBeLessThan(1500); expect(state.requestPaths.some((path) => path.includes("exchange-rates"))).toBeTruthy(); }); test("02-汇率失败时保留原币账目并显示待换算状态", async ({ page }) => { const state = await mockApi(page, { initialEntries: [makeEntry({ id: "entry-usd", currency: "USD", amount: 1000, baseAmount: null, exchangeRate: null, exchangeRateEffectiveDate: null, conversionStatus: "pending" })] }); await 登录(page); await page.route("**/api/exchange-rates/**", (route) => route.abort("failed")); await page.reload(); await expect(page.getByRole("status")).toContainText("等待换算"); await expect(page.getByText("立即换算")).toBeVisible(); expect(state.entries).toHaveLength(1); }); test("03-已换算账目切换显示模式不会重复出现等待换算提示", async ({ page }) => { await mockApi(page, { initialEntries: [makeEntry({ id: "entry-usd", currency: "USD", amount: 1000, baseAmount: 720, exchangeRate: "7.2", exchangeRateEffectiveDate: "2026-08-01", conversionStatus: "exact" })] }); await 登录(page); await page.getByRole("button", { name: "更多" }).click(); await page.getByRole("menuitem", { name: "设置" }).click(); await page.getByLabel("流水金额显示").selectOption("original"); await page.getByRole("button", { name: "保存设置" }).click(); await page.goBack(); await expect(page.getByText("等待换算")).not.toBeVisible(); }); });