summaryrefslogtreecommitdiff
path: root/qa/driver/browser-test.js
diff options
context:
space:
mode:
authorSomhairle H. Marisol <[email protected]>2026-09-22 04:59:12 +0800
committerSomhairle H. Marisol <[email protected]>2026-09-22 04:59:12 +0800
commit545f2a507fd0138f7fd50ed7fb2631d0273db625 (patch)
treef9eedee8d82b632474408e774cb95e9e01a9750d /qa/driver/browser-test.js
parent0183b86f18d9897ff9487e6d864898954397991d (diff)
downloadfund-lab-545f2a507fd0138f7fd50ed7fb2631d0273db625.tar.gz
Integrate bond and stock positions into fund valuation (3d-23)
Diffstat (limited to 'qa/driver/browser-test.js')
-rw-r--r--qa/driver/browser-test.js53
1 files changed, 52 insertions, 1 deletions
diff --git a/qa/driver/browser-test.js b/qa/driver/browser-test.js
index 14cffc7..8ad9ab5 100644
--- a/qa/driver/browser-test.js
+++ b/qa/driver/browser-test.js
@@ -41,6 +41,7 @@ let lastStockTradeResponse = null;
let lastStockPositionsResponse = null;
let lastBondTradeResponse = null;
let lastBondPositionsResponse = null;
+let lastValuationResponse = null;
function check(name, ok, detail) {
results.push({ name, ok, detail: detail || "" });
@@ -225,7 +226,12 @@ async function summaryLabelExists(page, label, name) {
lastBondPositionsResponse = await r.json();
} catch {}
}
- if (r.status() >= 400 && !/\/api\/instruments\//.test(r.url()) && !/\/api\/market\//.test(r.url()) && !/\/orders/.test(r.url()) && !/\/redemptions/.test(r.url()) && !/\/capital/.test(r.url()) && !/\/stock-trades/.test(r.url()) && !/\/stock-positions/.test(r.url()) && !/\/bond-trades/.test(r.url()) && !/\/bond-positions/.test(r.url())) {
+ if (/\/valuation$/i.test(new URL(r.url()).pathname) && r.request().method() === "GET" && r.status() < 400) {
+ try {
+ lastValuationResponse = await r.json();
+ } catch {}
+ }
+ if (r.status() >= 400 && !/\/api\/instruments\//.test(r.url()) && !/\/api\/market\//.test(r.url()) && !/\/orders/.test(r.url()) && !/\/redemptions/.test(r.url()) && !/\/capital/.test(r.url()) && !/\/stock-trades/.test(r.url()) && !/\/stock-positions/.test(r.url()) && !/\/bond-trades/.test(r.url()) && !/\/bond-positions/.test(r.url()) && !/\/valuation/.test(r.url())) {
consoleErrors.push("resource " + r.status() + ": " + r.url());
}
});
@@ -281,6 +287,7 @@ async function summaryLabelExists(page, label, name) {
await stockDailyScenario(page);
await stockTradeScenario(page);
await bondTradeScenario(page);
+ await valuationScenario(page);
} finally {
check("G1 无浏览器控制台/页面错误", consoleErrors.length === 0, consoleErrors.slice(0, 3).join(" | "));
await browser.close();
@@ -1071,6 +1078,50 @@ async function bondTradeScenario(page) {
await page.screenshot({ path: SHOTS + "/25-bond-trade.png" });
}
+async function valuationScenario(page) {
+ // B6: 股票+债券混合持仓组合估值(现金守恒 + 实时市值合计)。
+ await page.waitForSelector(".fund-valuation", { timeout: 10000 });
+
+ lastValuationResponse = null;
+ await page.click(".valuation-refresh-action");
+ await page.waitForFunction(
+ () => {
+ const element = document.querySelector(".valuation-content");
+ return element && element.textContent.includes("组合合计");
+ },
+ { timeout: 10000 }
+ );
+
+ const valuation = lastValuationResponse || {};
+ const positions = Array.isArray(valuation.positions) ? valuation.positions : [];
+ const stock = positions.find((item) => item.instrumentCode === "600519") || {};
+ const bond = positions.find((item) => item.instrumentCode === "110075") || {};
+
+ const cash = parseFloat(valuation.cash || "0");
+ const marketValue = parseFloat(valuation.positionsMarketValue || "0");
+ const portfolio = parseFloat(valuation.portfolioValue || "0");
+
+ const rowText = ((await page.textContent(".fund-valuation")) || "").trim();
+
+ check(
+ "B6 混合持仓估值现金守恒且实时市值合计正确",
+ valuation.portfolioValue &&
+ Math.abs(portfolio - (cash + marketValue)) < 0.005 &&
+ stock.status === "priced" &&
+ stock.priceSource === "live" &&
+ stock.marketValue === "125257.00" &&
+ bond.status === "priced" &&
+ bond.marketValue === "1063.68" &&
+ Math.abs(marketValue - 126320.68) < 0.005 &&
+ valuation.pricedPositions === 2 &&
+ valuation.unavailablePositions === 0 &&
+ rowText.includes("组合合计"),
+ `valuation=${JSON.stringify(valuation).slice(0, 240)}`
+ );
+
+ await page.screenshot({ path: SHOTS + "/26-valuation.png" });
+}
+
async function postInvestmentPlanViaApi(page, fundId, token) {
return page.evaluate(
async ({ fundId, token }) => {