diff options
| author | Somhairle H. Marisol <[email protected]> | 2026-09-21 22:08:53 +0800 |
|---|---|---|
| committer | Somhairle H. Marisol <[email protected]> | 2026-09-21 22:08:53 +0800 |
| commit | 4c60174fc66927db5536bc2fe06574c753140055 (patch) | |
| tree | c18fb8650d097f584cd8e141903cff2ffae0d0fd /qa/driver | |
| parent | 722ec6c19c0c64ea5348c6bc3aefc0061bd96307 (diff) | |
| download | fund-lab-4c60174fc66927db5536bc2fe06574c753140055.tar.gz | |
Add dividend history visibility (3d-9a)
Expose a deterministic source key on booked dividend records and surface a read-only dividend history panel with empty state, backed by API tests and browser QA assertions.
Diffstat (limited to 'qa/driver')
| -rw-r--r-- | qa/driver/browser-test.js | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/qa/driver/browser-test.js b/qa/driver/browser-test.js index acc576d..4a4b799 100644 --- a/qa/driver/browser-test.js +++ b/qa/driver/browser-test.js @@ -174,6 +174,7 @@ async function summaryLabelExists(page, label, name) { await confirmScenario(page); await redeemScenario(page); await capitalScenario(page); + await dividendScenario(page); } finally { check("G1 无浏览器控制台/页面错误", consoleErrors.length === 0, consoleErrors.slice(0, 3).join(" | ")); await browser.close(); @@ -341,6 +342,75 @@ async function capitalScenario(page) { await page.screenshot({ path: SHOTS + "/14-capital-deposit.png" }); } +async function currentFundId(page) { + const rows = await page.$$eval(".fund-detail-row", (els) => + els.map((el) => ({ + label: (el.querySelector(".fund-detail-label")?.textContent || "").trim(), + value: (el.querySelector(".fund-detail-value")?.textContent || "").trim(), + })) + ); + const row = rows.find((r) => r.label === "基金ID"); + const m = row ? /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/i.exec(row.value) : null; + return m ? m[0] : ""; +} + +async function postDividendViaApi(page, fundId, token) { + return page.evaluate( + async ({ fundId, token }) => { + const randomKey = () => { + if (window.crypto && window.crypto.randomUUID) return window.crypto.randomUUID().replace(/-/g, ""); + return Math.random().toString(16).slice(2).padEnd(32, "0").slice(0, 32); + }; + const response = await fetch(`/api/funds/${fundId}/dividends`, { + method: "POST", + headers: { + Authorization: `Bearer ${token}`, + "Idempotency-Key": randomKey(), + "Content-Type": "application/json", + }, + body: JSON.stringify({ instrumentCode: "000001", navDate: "2026-09-21", dps: "0.10000000", mode: "cash" }), + }); + return response.status; + }, + { fundId, token } + ); +} + +async function dividendScenario(page) { + // L 系列: 分红派发记录可见性(只读历史)。K 场景后当前基金持有 000001 50.00000000 份。 + await page.waitForSelector(".dividend-panel", { timeout: 10000 }); + const fundId = await currentFundId(page); + const token = process.env.QA_TOKEN || "qa-token"; + + const status = await postDividendViaApi(page, fundId, token); + await page.click(".dividend-refresh-action"); + const rowAppeared = await page + .waitForSelector(".dividend-history .dividend-row", { timeout: 15000 }) + .then(() => true) + .catch(() => false); + const historyText = ((await page.textContent(".dividend-history")) || ""); + check( + "L1 现金分红入账并出现在只读历史(含来源 key)", + status === 200 && + rowAppeared && + historyText.includes("000001") && + historyText.includes("持仓日期 2026-09-21") && + historyText.includes("类型 现金") && + historyText.includes("每份分红 0.10000000") && + historyText.includes("入账现金 5.00") && + historyText.includes("dividend-scheme:"), + `status=${status} ${historyText.slice(0, 240)}` + ); + + // 幂等:同一方案(同基金/代码/日期/模式/每份额)重放只保留一条记录 + await postDividendViaApi(page, fundId, token); + await page.click(".dividend-refresh-action"); + await page.waitForTimeout(800); + const rowCount = await page.locator(".dividend-history .dividend-row").count(); + check("L2 同方案重放不产生第二条分红", rowCount === 1, `rows=${rowCount}`); + await page.screenshot({ path: SHOTS + "/15-dividend-history.png" }); +} + const failed = results.filter((r) => !r.ok); console.log(`\n==== ${results.length - failed.length}/${results.length} passed ====`); process.exit(failed.length > 0 ? 1 : 0); |
