





















@@ -0,0 +1,68 @@
1+import { spawn } from "node:child_process";
2+import { mkdtemp, readFile, rm } from "node:fs/promises";
3+import os from "node:os";
4+import path from "node:path";
5+import { fileURLToPath } from "node:url";
6+import { describe, expect, it } from "vitest";
7+8+const repoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../..");
9+const scriptPath = path.join(repoRoot, "scripts/e2e/lib/run-with-pty.mjs");
10+11+function runPtyProbe(logPath: string): Promise<{ code: number | null; stdout: string; stderr: string }> {
12+return new Promise((resolve, reject) => {
13+const child = spawn(
14+process.execPath,
15+[
16+scriptPath,
17+logPath,
18+"/bin/bash",
19+"-lc",
20+'printf "prompt\\n"; IFS= read -r value; printf "got:%s\\n" "$value"',
21+],
22+{ stdio: ["pipe", "pipe", "pipe"] },
23+);
24+let stdout = "";
25+let stderr = "";
26+const timeout = setTimeout(() => {
27+child.kill("SIGTERM");
28+reject(new Error("PTY probe timed out"));
29+}, 10_000);
30+31+child.stdout.setEncoding("utf8");
32+child.stderr.setEncoding("utf8");
33+child.stdout.on("data", (chunk) => {
34+stdout += chunk;
35+});
36+child.stderr.on("data", (chunk) => {
37+stderr += chunk;
38+});
39+child.on("error", (error) => {
40+clearTimeout(timeout);
41+reject(error);
42+});
43+child.on("close", (code) => {
44+clearTimeout(timeout);
45+resolve({ code, stdout, stderr });
46+});
47+child.stdin.end("abc\n");
48+});
49+}
50+51+describe("run-with-pty", () => {
52+it("forwards stdin through a PTY and writes the transcript log", async () => {
53+const tempRoot = await mkdtemp(path.join(os.tmpdir(), "openclaw-run-with-pty-"));
54+const logPath = path.join(tempRoot, "pty.log");
55+try {
56+const result = await runPtyProbe(logPath);
57+const log = await readFile(logPath, "utf8");
58+59+expect(result).toMatchObject({ code: 0, stderr: "" });
60+expect(result.stdout).toContain("prompt");
61+expect(result.stdout).toContain("got:abc");
62+expect(log).toContain("prompt");
63+expect(log).toContain("got:abc");
64+} finally {
65+await rm(tempRoot, { recursive: true, force: true });
66+}
67+});
68+});
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。