summaryrefslogtreecommitdiff
path: root/qa/driver
diff options
context:
space:
mode:
authorSomhairle H. Marisol <[email protected]>2026-09-22 05:56:14 +0800
committerSomhairle H. Marisol <[email protected]>2026-09-22 05:56:14 +0800
commit79600c15aef9bd411abe88dcf36286a102b5abea (patch)
treee5e3bfbff6f60a48a3c0ff8b78b48da98c8f238a /qa/driver
parent6abd4c206fbfe8369b3fde4c905619d08f13c5d1 (diff)
downloadfund-lab-79600c15aef9bd411abe88dcf36286a102b5abea.tar.gz
Add daily market refresh endpoint, snapshot-first valuation and UI refresh (3d-25)
Diffstat (limited to 'qa/driver')
-rw-r--r--qa/driver/browser-test.js79
1 files changed, 79 insertions, 0 deletions
diff --git a/qa/driver/browser-test.js b/qa/driver/browser-test.js
index dd49263..b271fbb 100644
--- a/qa/driver/browser-test.js
+++ b/qa/driver/browser-test.js
@@ -42,6 +42,7 @@ let lastStockPositionsResponse = null;
let lastBondTradeResponse = null;
let lastBondPositionsResponse = null;
let lastValuationResponse = null;
+let lastMarketRefreshResponse = null;
let lastSipStatusResponse = null;
let lastSipAdvanceResponse = null;
@@ -233,6 +234,11 @@ async function summaryLabelExists(page, label, name) {
lastValuationResponse = await r.json();
} catch {}
}
+ if (/\/market-data\/refresh$/i.test(new URL(r.url()).pathname) && r.request().method() === "POST" && r.status() < 400) {
+ try {
+ lastMarketRefreshResponse = await r.json();
+ } catch {}
+ }
if (/\/sip\/plans\/[0-9a-f-]+\/(pause|resume)$/i.test(new URL(r.url()).pathname) && r.request().method() === "POST" && r.status() < 400) {
try {
lastSipStatusResponse = await r.json();
@@ -300,6 +306,7 @@ async function summaryLabelExists(page, label, name) {
await stockTradeScenario(page);
await bondTradeScenario(page);
await valuationScenario(page);
+ await marketRefreshScenario(page);
await sipStatusScenario(page);
await rebalanceArchiveScenario(page);
} finally {
@@ -1106,6 +1113,10 @@ async function valuationScenario(page) {
{ timeout: 10000 }
);
+ for (let i = 0; i < 200 && lastValuationResponse === null; i++) {
+ await page.waitForTimeout(100);
+ }
+
const valuation = lastValuationResponse || {};
const positions = Array.isArray(valuation.positions) ? valuation.positions : [];
const stock = positions.find((item) => item.instrumentCode === "600519") || {};
@@ -1136,6 +1147,74 @@ async function valuationScenario(page) {
await page.screenshot({ path: SHOTS + "/26-valuation.png" });
}
+async function marketRefreshScenario(page) {
+ // 3d-25: 刷新行情按钮 -> POST refresh 持久化最新行情 -> 估值改用快照定价。
+ await page.waitForSelector(".market-refresh-action", { timeout: 10000 });
+
+ const buttonText = ((await page.textContent(".market-refresh-action")) || "").trim();
+ check("F1 估值面板显示刷新行情按钮", buttonText === "刷新行情", buttonText);
+
+ lastMarketRefreshResponse = null;
+ lastValuationResponse = null;
+ await page.click(".market-refresh-action");
+
+ for (let i = 0; i < 200 && lastMarketRefreshResponse === null; i++) {
+ await page.waitForTimeout(100);
+ }
+
+ const refresh = lastMarketRefreshResponse || {};
+ const refreshed = Array.isArray(refresh.refreshed) ? refresh.refreshed : [];
+ const failures = Array.isArray(refresh.failures) ? refresh.failures : [];
+ const stock = refreshed.find((item) => item.instrumentCode === "600519") || {};
+ const bond = refreshed.find((item) => item.instrumentCode === "110075") || {};
+ const fund = refreshed.find((item) => item.instrumentCode === "000001") || {};
+
+ check(
+ "F2 刷新行情持久化股票/债券/基金最新行情且无失败",
+ refresh.asOfDate === "2026-09-21" &&
+ failures.length === 0 &&
+ stock.assetClass === "stock" &&
+ stock.snapshotDate === "2026-09-21" &&
+ stock.price === "1252.57000000" &&
+ bond.assetClass === "bond" &&
+ bond.price === "106.36800000" &&
+ fund.assetClass === "fund" &&
+ fund.snapshotDate === "2026-09-21" &&
+ fund.price === "1.19020000",
+ `refresh=${JSON.stringify(refresh).slice(0, 320)}`
+ );
+
+ for (let i = 0; i < 200 && lastValuationResponse === null; i++) {
+ await page.waitForTimeout(100);
+ }
+
+ const valuation = lastValuationResponse || {};
+ const positions = Array.isArray(valuation.positions) ? valuation.positions : [];
+ const stockRow = positions.find((item) => item.instrumentCode === "600519") || {};
+ const bondRow = positions.find((item) => item.instrumentCode === "110075") || {};
+
+ check(
+ "F3 刷新后估值改用持久化快照定价且市值不变",
+ valuation.asOfDate === "2026-09-21" &&
+ stockRow.status === "priced" &&
+ stockRow.priceSource === "snapshot" &&
+ stockRow.marketValue === "125257.00" &&
+ bondRow.priceSource === "snapshot" &&
+ bondRow.marketValue === "1063.68" &&
+ valuation.pricedPositions === 2,
+ `valuation=${JSON.stringify(valuation).slice(0, 320)}`
+ );
+
+ const messageText = ((await page.textContent(".market-refresh-message")) || "").trim();
+ check(
+ "F4 页面显示刷新结果摘要",
+ messageText.includes("行情刷新完成") && messageText.includes("2026-09-21"),
+ messageText.slice(0, 180)
+ );
+
+ await page.screenshot({ path: SHOTS + "/29-market-refresh.png" });
+}
+
async function postInvestmentPlanViaApi(page, fundId, token) {
return page.evaluate(
async ({ fundId, token }) => {