























@@ -33,6 +33,7 @@ import {
3333canConnectToLoopbackPort,
3434buildDiscordSmokeGuildsConfig,
3535buildRealUpdateEnv,
36+dashboardHtmlMarkerStatus,
3637CROSS_OS_FETCH_BODY_MAX_CHARS,
3738CROSS_OS_GATEWAY_READY_TIMEOUT_MS,
3839CROSS_OS_GATEWAY_STATUS_COMMAND_TIMEOUT_MS,
@@ -61,6 +62,7 @@ import {
6162readInstalledVersion,
6263readBoundedCrossOsResponseText,
6364readRunnerOverrideEnv,
65+resolveDashboardAssetUrls,
6466resolveCrossOsAgentTurnOptional,
6567runCommand,
6668resolveCommandSpawnInvocation,
@@ -85,6 +87,7 @@ import {
8587shouldSkipOptionalCrossOsAgentTurnError,
8688shouldUseManagedGatewayForInstallerRuntime,
8789shouldUseManagedGatewayService,
90+verifyDashboardAssetUrls,
8891verifyDevUpdateStatus,
8992verifyPackagedUpgradeUpdateResult,
9093verifyWindowsPackagedUpgradeFallbackInstall,
@@ -159,6 +162,40 @@ describe("scripts/openclaw-cross-os-release-checks", () => {
159162expect(CROSS_OS_FETCH_BODY_MAX_CHARS).toBeGreaterThan(1024);
160163});
161164165+it("requires dashboard root markers and same-origin asset URLs", () => {
166+const html = [
167+"<title>OpenClaw Control</title>",
168+"<openclaw-app></openclaw-app>",
169+'<link rel="stylesheet" href="/assets/index.css">',
170+'<script type="module" src="assets/index.js"></script>',
171+'<script type="module" src="https://example.com/assets/ignored.js"></script>',
172+].join("\n");
173+174+expect(dashboardHtmlMarkerStatus(html)).toEqual({ app: true, ready: true, title: true });
175+expect(resolveDashboardAssetUrls("http://127.0.0.1:18789/", html)).toEqual([
176+"http://127.0.0.1:18789/assets/index.css",
177+"http://127.0.0.1:18789/assets/index.js",
178+]);
179+});
180+181+it("fails dashboard readiness when assets are missing or unreachable", async () => {
182+await expect(verifyDashboardAssetUrls([])).resolves.toEqual({
183+failures: ["no dashboard asset URLs found"],
184+ok: false,
185+});
186+187+const result = await verifyDashboardAssetUrls(
188+["http://127.0.0.1:18789/assets/index.css", "http://127.0.0.1:18789/assets/index.js"],
189+async (url) =>
190+new Response("", {
191+status: String(url).endsWith(".js") ? 404 : 200,
192+}),
193+);
194+195+expect(result.ok).toBe(false);
196+expect(result.failures).toEqual(["http://127.0.0.1:18789/assets/index.js status=404"]);
197+});
198+162199it("keeps gateway RPC status probes patient enough for live release startup", () => {
163200expect(CROSS_OS_GATEWAY_STATUS_RPC_TIMEOUT_MS).toBeGreaterThanOrEqual(30_000);
164201expect(CROSS_OS_GATEWAY_STATUS_COMMAND_TIMEOUT_MS).toBeGreaterThan(
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。