Files
yuxuanhui e256d6fef1
Deploy production / deploy (push) Successful in 56s
feat: add Super Alpha research, management and MCP workflows
2026-09-13 12:32:16 +08:00

220 lines
8.3 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { expect, test } from "@playwright/test";
const headers = { "X-WQ-Request": "1" };
test("Super Alpha web lifecycle, generic simulation, evidence and type routing", async ({
page,
}) => {
const errors: string[] = [];
page.on("pageerror", (e) => errors.push(e.message));
await page.goto("/#superalpha-research");
await page.getByLabel("密码", { exact: true }).fill("browser-test-password");
await page.getByRole("button", { name: "进入工作空间" }).click();
await expect(
page.getByRole("button", { name: "新建 Super Alpha 方案", exact: true }),
).toBeVisible();
await page.request.put("/api/v1/account/credentials", {
headers,
data: { email: "test@example.com", password: "synthetic-password" },
});
await page.request.post("/api/v1/account/connect", { headers });
await expect
.poll(
async () =>
(await (await page.request.get("/api/v1/account")).json())
.connection_status,
)
.toBe("connected");
await page
.getByRole("button", { name: "新建 Super Alpha 方案", exact: true })
.click();
await page.getByLabel("方案名称", { exact: true }).fill("浏览器 SUPER 验收");
await page
.getByLabel("研究假设", { exact: true })
.fill("比较低换手组件与等权基线");
await page
.getByLabel("Selection", { exact: true })
.fill("turnover < {threshold}");
await page.getByLabel("Combo", { exact: true }).fill("alpha");
await page
.getByLabel("参数候选 JSON", { exact: true })
.fill('{"threshold":{"kind":"number","values":[0.1,0.2]}}');
await page.getByRole("button", { name: "同步合法设置", exact: true }).click();
await page.getByRole("button", { name: "选择组合", exact: true }).click();
await page.getByRole("combobox", { name: "Region", exact: true }).click();
await page.getByRole("option").filter({ hasText: /^USA$/ }).click();
await page.getByRole("combobox", { name: "Universe", exact: true }).click();
await page
.getByRole("option")
.filter({ hasText: /^TOP3000$/ })
.click();
await page.getByRole("button", { name: "应用组合", exact: true }).click();
await page.getByRole("button", { name: "保存方案", exact: true }).click();
await expect(page.getByText("已保存版本 1", { exact: true })).toBeVisible();
await page
.getByRole("button", { name: "预览 Selection(首组参数)", exact: true })
.click();
await expect(page.locator(".super-components")).toContainText("已核实 2 个");
await page.getByRole("tab", { name: "固定候选", exact: true }).click();
const building = page.waitForResponse(
(r) =>
r.url().endsWith("/superalpha/candidates") &&
r.request().method() === "POST",
);
await page.getByRole("button", { name: "展开固定候选", exact: true }).click();
const experiment = await (await building).json();
expect(experiment.total).toBe(4);
const table = page.locator(
".super-research .semi-tabs-pane-active .workspace-table",
);
await expect(table.locator("tbody tr.semi-table-row")).toHaveCount(4);
expect(
Math.round(
(await table.locator("tbody tr.semi-table-row").first().boundingBox())!
.height,
),
).toBe(40);
await table.locator("thead .semi-checkbox").click();
await page
.getByRole("button", { name: "预览回测(4)", exact: true })
.click();
await expect(
page.getByText(/浏览器 SUPER 验收 · 4 条候选 · 4 个平台批次/),
).toBeVisible();
await expect(
page.getByText("SUPER · Selection: turnover < 0.1 · Combo: alpha", {
exact: true,
}),
).toBeVisible();
await page.getByRole("button", { name: "确认启动回测", exact: true }).click();
await expect(page.getByText("4 / 4 已保存", { exact: true })).toBeVisible({
timeout: 25000,
});
const result = await (
await page.request.get(
`/api/v1/superalpha/experiments/${experiment.id}/results`,
)
).json();
expect(
result.items.every(
(i: { persistence_status: string }) => i.persistence_status === "saved",
),
).toBe(true);
const alpha = result.items[0].alpha_id;
await page.goto(`/#alphas?alpha_id=${alpha}`);
await expect(
page.getByRole("button", { name: "Super Alpha 管理", exact: true }),
).toHaveAttribute("aria-current", "page");
await expect(page.locator(".alpha-detail")).toContainText(
"Selection rationale",
);
await page.getByRole("tab", { name: "组件证据", exact: true }).click();
await expect(page.locator(".alpha-detail .super-components")).toContainText(
"已核实 2 个",
);
await page
.getByRole("button", { name: "复制为研究方案", exact: true })
.click();
await expect(page.getByLabel("Selection", { exact: true })).toHaveValue(
result.items[0].selection,
);
await page.goto(`/#superalpha-research?experiment_id=${experiment.id}`);
await page.getByRole("tab", { name: "回测对照", exact: true }).click();
await expect(page.getByText("4 个回测项", { exact: true })).toBeVisible();
const checks = page.locator(
".super-research .semi-tabs-pane-active tbody input[type=checkbox]",
);
await checks.nth(0).focus();
await page.keyboard.press("Space");
await checks.nth(1).focus();
await page.keyboard.press("Space");
await page.getByRole("button", { name: "对照两项(2)" }).click();
await expect(page.getByRole("dialog")).toContainText("同池对照");
await page.keyboard.press("Escape");
await expect(page.getByRole("dialog")).not.toBeVisible();
for (const width of [1440, 850, 390]) {
await page.setViewportSize({ width, height: 950 });
expect(
await page.evaluate(
() => document.documentElement.scrollWidth <= innerWidth,
),
).toBe(true);
await page.screenshot({
path: `../output/playwright/superalpha-${width}.png`,
});
}
expect(errors).toEqual([]);
});
test("Super management scopes, saved views and cross-page selection", async ({
page,
}) => {
await page.goto("/#superalphas");
await page.getByLabel("密码", { exact: true }).fill("browser-test-password");
await page.getByRole("button", { name: "进入工作空间" }).click();
await expect(
page.getByRole("tab", { name: "待提交", exact: true }),
).toBeVisible();
await page.request.put("/api/v1/account/credentials", {
headers,
data: { email: "test@example.com", password: "synthetic-password" },
});
await page.request.post("/api/v1/account/connect", { headers });
await expect
.poll(
async () =>
(await (await page.request.get("/api/v1/account")).json())
.connection_status,
)
.toBe("connected");
const job = await (
await page.request.post("/api/v1/sync-jobs", {
headers,
data: {
kind: "daily_sync",
submission: "UNSUBMITTED",
date_from: "2025-01-01",
date_to: "2025-01-01",
},
})
).json();
await expect
.poll(
async () =>
(await (await page.request.get(`/api/v1/sync-jobs/${job.id}`)).json())
.status,
)
.toBe("completed");
await page.reload();
const panel = page.locator(".alpha-page-view:not([hidden])");
await expect(panel.locator(".alpha-link").first()).toBeVisible();
const data = await (
await page.request.get(
"/api/v1/alphas?management_scope=super&submission=UNSUBMITTED",
)
).json();
expect(
data.items.every((a: { alpha_type: string }) => a.alpha_type === "SUPER"),
).toBe(true);
await panel.locator("tbody .semi-checkbox").first().click();
await panel.locator(".semi-page-item").filter({ hasText: /^2$/ }).click();
await expect(panel.getByText("已选择 1 条", { exact: false })).toBeVisible();
await panel.getByRole("button", { name: "保存为新视图" }).click();
await page.getByLabel("视图名称").fill("SUPER 隔离视图");
await page.getByRole("button", { name: "保存视图", exact: true }).click();
await expect(
panel.getByRole("tab", { name: /SUPER 隔离视图/ }),
).toBeVisible();
await page.getByRole("button", { name: "Alpha 管理", exact: true }).click();
await expect(
page.getByRole("tab", { name: /SUPER 隔离视图/ }),
).not.toBeVisible();
const regular = await (
await page.request.get("/api/v1/alphas?management_scope=non_super")
).json();
expect(
regular.items.every(
(a: { alpha_type: string }) => a.alpha_type !== "SUPER",
),
).toBe(true);
});