






























1+// Onboard Config Fixtures tests cover onboard E2E config writer/assertion helpers.
2+import { spawnSync } from "node:child_process";
3+import { readFileSync, writeFileSync } from "node:fs";
4+import path from "node:path";
5+import { afterEach, describe, expect, it } from "vitest";
6+import { cleanupTempDirs, makeTempDir } from "../helpers/temp-dir.js";
7+8+const ASSERT_CONFIG_SCRIPT = "scripts/e2e/lib/onboard/assert-config.mjs";
9+const WRITE_CONFIG_SCRIPT = "scripts/e2e/lib/onboard/write-config.mjs";
10+const tempDirs: string[] = [];
11+12+afterEach(() => {
13+cleanupTempDirs(tempDirs);
14+});
15+16+function runScript(scriptPath: string, args: string[]) {
17+return spawnSync(process.execPath, [scriptPath, ...args], {
18+encoding: "utf8",
19+env: { ...process.env },
20+});
21+}
22+23+function readJson(file: string) {
24+return JSON.parse(readFileSync(file, "utf8"));
25+}
26+27+describe("onboard config fixture helpers", () => {
28+it("writes reset fixtures consumed by the reset assertion", () => {
29+const root = makeTempDir(tempDirs, "openclaw-onboard-config-");
30+const configPath = path.join(root, "openclaw.json");
31+32+const writeResult = runScript(WRITE_CONFIG_SCRIPT, ["reset", configPath]);
33+34+expect(writeResult.status).toBe(0);
35+expect(readJson(configPath)).toEqual({
36+meta: {},
37+agents: { defaults: { workspace: "/root/old" } },
38+gateway: { mode: "remote", remote: { url: "ws://old.example:18789", token: "old-token" } },
39+});
40+expect(readFileSync(configPath, "utf8")).toMatch(/\n$/u);
41+42+writeFileSync(
43+configPath,
44+`${JSON.stringify(
45+ {
46+ gateway: { mode: "local" },
47+ wizard: { lastRunMode: "local" },
48+ },
49+ null,
50+ 2,
51+ )}\n`,
52+"utf8",
53+);
54+const assertResult = runScript(ASSERT_CONFIG_SCRIPT, ["reset", configPath]);
55+56+expect(assertResult.status).toBe(0);
57+expect(assertResult.stderr).toBe("");
58+});
59+60+it("writes skills fixtures consumed by the skills assertion", () => {
61+const root = makeTempDir(tempDirs, "openclaw-onboard-config-skills-");
62+const configPath = path.join(root, "openclaw.json");
63+64+const writeResult = runScript(WRITE_CONFIG_SCRIPT, ["skills", configPath]);
65+66+expect(writeResult.status).toBe(0);
67+expect(readJson(configPath)).toEqual({
68+meta: {},
69+skills: { allowBundled: ["__none__"], install: { nodeManager: "bun" } },
70+});
71+writeFileSync(
72+configPath,
73+`${JSON.stringify(
74+ {
75+ ...readJson(configPath),
76+ wizard: { lastRunCommand: "configure", lastRunMode: "local" },
77+ },
78+ null,
79+ 2,
80+ )}\n`,
81+"utf8",
82+);
83+84+const assertResult = runScript(ASSERT_CONFIG_SCRIPT, ["skills", configPath]);
85+86+expect(assertResult.status).toBe(0);
87+expect(assertResult.stderr).toBe("");
88+});
89+90+it("accepts local and remote onboard assertion fixtures", () => {
91+const root = makeTempDir(tempDirs, "openclaw-onboard-config-success-");
92+const workspace = path.join(root, "workspace");
93+const localConfigPath = path.join(root, "local.json");
94+const remoteConfigPath = path.join(root, "remote.json");
95+writeFileSync(
96+localConfigPath,
97+`${JSON.stringify(
98+ {
99+ agents: { defaults: { workspace } },
100+ gateway: { bind: "loopback", mode: "local", tailscale: { mode: "off" } },
101+ wizard: {
102+ lastRunAt: "2026-01-01T00:00:00.000Z",
103+ lastRunCommand: "onboard",
104+ lastRunMode: "local",
105+ lastRunVersion: "test-version",
106+ },
107+ },
108+ null,
109+ 2,
110+ )}\n`,
111+"utf8",
112+);
113+writeFileSync(
114+remoteConfigPath,
115+`${JSON.stringify(
116+ {
117+ gateway: {
118+ mode: "remote",
119+ remote: { url: "ws://gateway.local:18789", token: "remote-token" },
120+ },
121+ wizard: { lastRunMode: "remote" },
122+ },
123+ null,
124+ 2,
125+ )}\n`,
126+"utf8",
127+);
128+129+const localResult = runScript(ASSERT_CONFIG_SCRIPT, [
130+"local-basic",
131+localConfigPath,
132+workspace,
133+]);
134+const remoteResult = runScript(ASSERT_CONFIG_SCRIPT, [
135+"remote-non-interactive",
136+remoteConfigPath,
137+]);
138+139+expect(localResult.status).toBe(0);
140+expect(localResult.stderr).toBe("");
141+expect(remoteResult.status).toBe(0);
142+expect(remoteResult.stderr).toBe("");
143+});
144+145+it("accepts channel configuration assertions for scrubbed channel secrets", () => {
146+const root = makeTempDir(tempDirs, "openclaw-onboard-config-channels-");
147+const configPath = path.join(root, "channels.json");
148+writeFileSync(
149+configPath,
150+`${JSON.stringify(
151+ {
152+ wizard: { lastRunCommand: "configure", lastRunMode: "local" },
153+ },
154+ null,
155+ 2,
156+ )}\n`,
157+"utf8",
158+);
159+160+const result = runScript(ASSERT_CONFIG_SCRIPT, ["channels", configPath]);
161+162+expect(result.status).toBe(0);
163+expect(result.stderr).toBe("");
164+});
165+166+it("reports assertion mismatches with stable field labels", () => {
167+const root = makeTempDir(tempDirs, "openclaw-onboard-config-mismatch-");
168+const configPath = path.join(root, "openclaw.json");
169+writeFileSync(
170+configPath,
171+`${JSON.stringify(
172+ {
173+ gateway: { mode: "remote", bind: "lan", tailscale: { mode: "on" } },
174+ wizard: { lastRunCommand: "configure", lastRunMode: "remote" },
175+ },
176+ null,
177+ 2,
178+ )}\n`,
179+"utf8",
180+);
181+182+const result = runScript(ASSERT_CONFIG_SCRIPT, [
183+"local-basic",
184+configPath,
185+path.join(root, "workspace"),
186+]);
187+188+expect(result.status).toBe(1);
189+expect(result.stderr).toContain("agents.defaults.workspace mismatch");
190+expect(result.stderr).toContain("gateway.mode mismatch");
191+expect(result.stderr).toContain("gateway.bind mismatch");
192+expect(result.stderr).toContain("gateway.tailscale.mode mismatch");
193+expect(result.stderr).toContain("wizard.lastRunCommand mismatch");
194+});
195+196+it("rejects unknown writer and assertion scenarios", () => {
197+const root = makeTempDir(tempDirs, "openclaw-onboard-config-unknown-");
198+const configPath = path.join(root, "openclaw.json");
199+writeFileSync(configPath, "{}\n", "utf8");
200+201+const writeResult = runScript(WRITE_CONFIG_SCRIPT, ["unknown", configPath]);
202+const assertResult = runScript(ASSERT_CONFIG_SCRIPT, ["unknown", configPath]);
203+204+expect(writeResult.status).not.toBe(0);
205+expect(writeResult.stderr).toContain("unknown config scenario: unknown");
206+expect(assertResult.status).not.toBe(0);
207+expect(assertResult.stderr).toContain("unknown onboard assertion scenario: unknown");
208+});
209+});
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。