feat: add pending task drilldown

This commit is contained in:
Codex
2026-05-04 16:22:01 +00:00
parent 3207b9ecb1
commit 7e4dce47cd
9 changed files with 253 additions and 29 deletions
+1
View File
@@ -81,6 +81,7 @@ export function writeComposeEnv(config: UniDeskConfig, freshLogPrefix: boolean):
UNIDESK_SESSION_TTL_SECONDS: String(config.auth.sessionTtlSeconds),
UNIDESK_HEARTBEAT_INTERVAL_MS: String(config.providerGateway.heartbeatIntervalMs),
UNIDESK_HEARTBEAT_TIMEOUT_MS: "90000",
UNIDESK_TASK_PENDING_TIMEOUT_MS: "600000",
UNIDESK_RECONNECT_BASE_MS: String(config.providerGateway.reconnectBaseMs),
UNIDESK_RECONNECT_MAX_MS: String(config.providerGateway.reconnectMaxMs),
UNIDESK_MONITOR_DISK_PATH: config.providerGateway.metrics.diskPath,
+20
View File
@@ -269,9 +269,27 @@ async function frontendCheck(config: UniDeskConfig, urls: PublicUrls, checks: E2
await page.waitForFunction(() => document.querySelector('[data-testid="conn-text"]')?.textContent?.includes("核心在线"), undefined, { timeout: 15000 });
await page.waitForSelector(`text=${config.providerGateway.id}`, { timeout: 10000 });
await page.waitForSelector(`text=${config.providerGateway.name}`, { timeout: 10000 });
await page.setViewportSize({ width: 390, height: 860 });
const mobileRailHeights: number[] = [];
for (const moduleLabel of ["运行总览", "资源节点", "任务调度", "系统配置"]) {
await page.getByRole("button", { name: new RegExp(moduleLabel) }).click();
await page.waitForTimeout(80);
const height = await page.locator(".rail").evaluate((element) => Math.round(element.getBoundingClientRect().height));
mobileRailHeights.push(height);
}
const mobileRailMax = Math.max(...mobileRailHeights);
const mobileRailMin = Math.min(...mobileRailHeights);
await page.setViewportSize({ width: 1440, height: 920 });
await page.getByRole("button", { name: /运行总览/ }).click();
await page.getByRole("button", { name: /态势总览/ }).click();
const bodyText = await page.locator("body").innerText({ timeout: 5000 });
const rawBlocksBefore = await page.locator("pre.raw-json").count();
const nakedJsonText = bodyText.includes('{"') || bodyText.includes('"providerId"') || bodyText.includes('"labels"');
await page.getByTestId("pending-task-card").click();
await page.waitForSelector('[data-testid="pending-task-page"]', { timeout: 5000 });
const pendingTaskText = await page.locator('[data-testid="pending-task-page"]').innerText({ timeout: 5000 });
await page.getByRole("button", { name: /运行总览/ }).click();
await page.getByRole("button", { name: /态势总览/ }).click();
await page.screenshot({ path: screenshotPath, fullPage: true });
await page.getByTestId(`raw-node-${config.providerGateway.id.replace(/[^a-zA-Z0-9_-]/g, "_")}`).click();
await page.waitForSelector('[data-testid="raw-json"]', { timeout: 5000 });
@@ -301,6 +319,8 @@ async function frontendCheck(config: UniDeskConfig, urls: PublicUrls, checks: E2
}, undefined, { timeout: 10000 });
const dockerText = await page.locator('[data-testid="docker-status-page"]').innerText({ timeout: 5000 });
addCheck(checks, "frontend:login-provider-visible", bodyText.includes(config.providerGateway.id) && bodyText.includes(config.providerGateway.name) && bodyText.includes("核心在线"), { screenshotPath });
addCheck(checks, "frontend:mobile-nav-fixed-height", mobileRailMax - mobileRailMin <= 1 && mobileRailMax <= 44, { mobileRailHeights });
addCheck(checks, "frontend:pending-task-drilldown", pendingTaskText.includes("待处理任务") && (pendingTaskText.includes("当前无待处理任务") || (pendingTaskText.includes("Provider") && pendingTaskText.includes("已等待"))), { pendingTaskPreview: pendingTaskText.slice(0, 600) });
addCheck(checks, "frontend:no-naked-json-before-click", rawBlocksBefore === 0 && !nakedJsonText, { rawBlocksBefore, nakedJsonText });
addCheck(checks, "frontend:raw-json-explicit-button", rawText.includes('"providerId"') && rawText.includes(config.providerGateway.id), { rawTextPreview: rawText.slice(0, 400) });
addCheck(checks, "frontend:system-monitor-visible", monitorText.includes("任务管理器视图") && monitorText.includes("CPU") && monitorText.includes("Memory") && monitorText.includes("Disk") && monitorText.includes("不含缓存"), { monitorTextPreview: monitorText.slice(0, 800) });