Skip to content

Commit 6be16c7

Browse files
committed
test(note): add regression tests for copy-sensitive token preservation
Add focused tests for wrapNoteMessage and note() that verify copy-sensitive tokens (paths, URLs, Windows paths) are preserved as unbroken lines, guarding against future regressions. Refs #94730
1 parent 5db49e5 commit 6be16c7

1 file changed

Lines changed: 64 additions & 0 deletions

File tree

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
// Terminal Core tests cover note wrapping behavior.
2+
import { describe, expect, it } from "vitest";
3+
import { wrapNoteMessage, note } from "./note.js";
4+
5+
describe("note copy-sensitive token preservation", () => {
6+
it("preserves long file paths as a single line in wrapNoteMessage", () => {
7+
const longPath =
8+
"~/.openclaw/agents/main/sessions/9c2acae5-841f-4aea-936b-fdb513b60202.jsonl.lock";
9+
const message = "Session lock: " + longPath;
10+
const wrapped = wrapNoteMessage(message, { columns: 80 });
11+
const lines = wrapped.split("\n");
12+
13+
// The path should appear intact on one line (not split across lines)
14+
const pathLine = lines.find((l) => l.includes(longPath));
15+
expect(pathLine).toBeDefined();
16+
});
17+
18+
it("preserves URLs as a single line in wrapNoteMessage", () => {
19+
const longUrl = "https://api.example.com/v1/users/123456789/sessions/abcdef0123456789/config";
20+
const message = "Endpoint: " + longUrl;
21+
const wrapped = wrapNoteMessage(message, { columns: 80 });
22+
const lines = wrapped.split("\n");
23+
24+
const urlLine = lines.find((l) => l.includes(longUrl));
25+
expect(urlLine).toBeDefined();
26+
});
27+
28+
it("preserves Windows paths as a single line in wrapNoteMessage", () => {
29+
const winPath = "C:\\Users\\Administrator\\.openclaw\\agents\\main\\sessions\\lock.jsonl.lock";
30+
const message = "Lock file: " + winPath;
31+
const wrapped = wrapNoteMessage(message, { columns: 80 });
32+
const lines = wrapped.split("\n");
33+
34+
const pathLine = lines.find((l) => l.includes(winPath));
35+
expect(pathLine).toBeDefined();
36+
});
37+
38+
it("does not re-break copy-sensitive tokens via clack note rendering", () => {
39+
// This test verifies the fix: clack's note() uses a wide virtual stream
40+
// so its internal wrap does not re-break copy-sensitive tokens.
41+
const longPath =
42+
"~/.openclaw/agents/main/sessions/9c2acae5-841f-4aea-936b-fdb513b60202.jsonl.lock";
43+
const message = "Session lock: " + longPath;
44+
45+
const output: string[] = [];
46+
const mockStream = {
47+
columns: 80,
48+
write: (chunk: string) => {
49+
output.push(chunk);
50+
return true;
51+
},
52+
isTTY: true,
53+
};
54+
55+
note(message, "Test", {
56+
output: mockStream as NodeJS.WriteStream,
57+
format: (line: string) => line,
58+
});
59+
60+
const result = output.join("");
61+
// The path should appear intact in the rendered output
62+
expect(result).toContain(longPath);
63+
});
64+
});

0 commit comments

Comments
 (0)