summaryrefslogtreecommitdiff
path: root/qa/driver/browser-test.js
diff options
context:
space:
mode:
Diffstat (limited to 'qa/driver/browser-test.js')
-rw-r--r--qa/driver/browser-test.js70
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);