feat: land page aggregate and phase7 document ai mainline

- 收口 page aggregate 读取、本地状态与命令客户端\n- 接入 phase7 document ai sidecar 与前端编排入口\n- 更新 architecture 与 design 状态迁移
This commit is contained in:
lix-2026
2026-04-23 07:38:34 +08:00
parent 8353aea2f9
commit 41e958769e
93 changed files with 8778 additions and 2222 deletions
+14 -5
View File
@@ -8,7 +8,7 @@
const { chromium } = require("playwright");
const BASE_URL = process.env.MNOTE_UI_BASE_URL || "http://127.0.0.1:3000";
const MNOTE_WEB_BASE_URL = process.env.MNOTE_WEB_SMOKE_BASE_URL || "http://127.0.0.1:3104";
const MNOTE_WEB_BASE_URL = process.env.MNOTE_WEB_SMOKE_BASE_URL || "";
const REQUEST_TIMEOUT_MS = 20_000;
const UI_TIMEOUT_MS = 30_000;
const TEST_LOGIN_BUTTON_NAME = "测试账号快速登录";
@@ -19,6 +19,14 @@ function assert(condition, message) {
}
}
function requireMnoteWebSmokeBaseUrl() {
assert(
Boolean(MNOTE_WEB_BASE_URL),
"当前 smoke 仅用于 legacy mnote-web tree shell,对应端口已默认退役;如需执行,请显式设置 MNOTE_WEB_SMOKE_BASE_URL。",
);
return MNOTE_WEB_BASE_URL;
}
async function requestJson(requestContext, path, init = {}) {
const response = await requestContext.fetch(`${BASE_URL}${path}`, {
...init,
@@ -110,6 +118,7 @@ async function ensureAuthenticated(page, requestContext) {
}
async function runTreeShellRegression(page, requestContext, viewer, target) {
const runtimeBaseUrl = requireMnoteWebSmokeBaseUrl();
const uniqueSuffix = Date.now().toString();
const rootTitle = `task091-root-${uniqueSuffix}`;
const childTitle = `task091-child-${uniqueSuffix}`;
@@ -132,7 +141,7 @@ async function runTreeShellRegression(page, requestContext, viewer, target) {
const iframe = page.locator('iframe[title="mnote-web tree shell"]');
await iframe.waitFor({ state: "visible", timeout: UI_TIMEOUT_MS });
const iframeSrc = await iframe.getAttribute("src");
assert(iframeSrc && iframeSrc.includes(`${MNOTE_WEB_BASE_URL}/tree`), `Sidebar 未挂载 mnote-web tree shell${iframeSrc}`);
assert(iframeSrc && iframeSrc.includes(`${runtimeBaseUrl}/tree`), `Sidebar 未挂载 mnote-web tree shell${iframeSrc}`);
assert(iframeSrc.includes(`actorId=${encodeURIComponent(viewer.userId)}`), `tree shell 未透传当前用户 actorId${iframeSrc}`);
const getTreeFrame = () => page.frameLocator('iframe[title="mnote-web tree shell"]');
@@ -177,7 +186,7 @@ async function runTreeShellRegression(page, requestContext, viewer, target) {
const createResponsePromise = page.waitForResponse(
(response) =>
response.url().includes(`${MNOTE_WEB_BASE_URL}/api/tree/commands`) &&
response.url().includes(`${runtimeBaseUrl}/api/tree/commands`) &&
response.request().method() === "POST" &&
response.status() === 200 &&
(response.request().postData() || "").includes('"action":"create"'),
@@ -200,7 +209,7 @@ async function runTreeShellRegression(page, requestContext, viewer, target) {
page.once("dialog", (dialog) => dialog.accept(renamedTitle));
const renameResponsePromise = page.waitForResponse(
(response) =>
response.url().includes(`${MNOTE_WEB_BASE_URL}/api/tree/commands`) &&
response.url().includes(`${runtimeBaseUrl}/api/tree/commands`) &&
response.request().method() === "POST" &&
response.status() === 200 &&
(response.request().postData() || "").includes('"action":"rename"'),
@@ -220,7 +229,7 @@ async function runTreeShellRegression(page, requestContext, viewer, target) {
const moveResponsePromise = page.waitForResponse(
(response) =>
response.url().includes(`${MNOTE_WEB_BASE_URL}/api/tree/commands`) &&
response.url().includes(`${runtimeBaseUrl}/api/tree/commands`) &&
response.request().method() === "POST" &&
response.status() === 200 &&
(response.request().postData() || "").includes('"action":"move"'),