Skip to content

Commit 10b9513

Browse files
authored
Merge pull request #9018 from uinstinct/cli-wait-for-tests
chore: update slashCommands tests with waitForCondition
2 parents 34fdeb8 + bf2a8a4 commit 10b9513

File tree

1 file changed

+52
-20
lines changed

1 file changed

+52
-20
lines changed

extensions/cli/src/ui/__tests__/TUIChat.slashCommands.test.tsx

Lines changed: 52 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,18 @@
11
import { renderInMode, testBothModes } from "./TUIChat.dualModeHelper.js";
2-
import { waitForCondition, waitForNextRender } from "./TUIChat.testHelper.js";
2+
import { waitForCondition } from "./TUIChat.testHelper.js";
33

44
describe("TUIChat - Slash Commands Tests", () => {
55
testBothModes("shows slash when user types /", async (mode) => {
66
const { lastFrame, stdin } = renderInMode(mode);
77

88
// Type / to trigger slash command
99
stdin.write("/");
10-
await waitForNextRender();
1110

12-
const frame = lastFrame();
11+
let frame = "";
12+
await waitForCondition(() => {
13+
frame = lastFrame() ?? "";
14+
return frame.includes("/");
15+
});
1316

1417
// Should show the slash character
1518
expect(frame).toContain("/");
@@ -51,14 +54,21 @@ describe("TUIChat - Slash Commands Tests", () => {
5154
testBothModes("handles tab key after slash command", async (mode) => {
5255
const { lastFrame, stdin } = renderInMode(mode);
5356

54-
// Type /exi and then tab
5557
stdin.write("/exi");
56-
await waitForNextRender();
58+
59+
let frame = "";
60+
await waitForCondition(() => {
61+
frame = lastFrame() ?? "";
62+
return frame.includes("/exi");
63+
});
5764

5865
stdin.write("\t");
59-
await waitForNextRender();
6066

61-
const frameAfterTab = lastFrame();
67+
let frameAfterTab = "";
68+
await waitForCondition(() => {
69+
frameAfterTab = lastFrame() ?? "";
70+
return frameAfterTab.length > 0;
71+
});
6272

6373
// Should not crash after tab
6474
expect(frameAfterTab).toBeDefined();
@@ -77,11 +87,13 @@ describe("TUIChat - Slash Commands Tests", () => {
7787
testBothModes("shows slash command menu when typing /", async (mode) => {
7888
const { lastFrame, stdin } = renderInMode(mode);
7989

80-
// Type just /
8190
stdin.write("/");
82-
await waitForNextRender();
8391

84-
const frame = lastFrame();
92+
let frame = "";
93+
await waitForCondition(() => {
94+
frame = lastFrame() ?? "";
95+
return frame.includes("/");
96+
});
8597

8698
// Should show the slash
8799
expect(frame).toContain("/");
@@ -111,9 +123,18 @@ describe("TUIChat - Slash Commands Tests", () => {
111123

112124
// Type a complete command name first
113125
stdin.write("/title");
114-
await waitForNextRender();
115126

116-
const frameAfterCommand = lastFrame();
127+
let frameAfterCommand = lastFrame();
128+
await waitForCondition(() => {
129+
frameAfterCommand = lastFrame();
130+
131+
return (
132+
frameAfterCommand?.includes(
133+
mode === "remote" ? "Remote Mode" : "/title",
134+
) ?? false
135+
);
136+
});
137+
117138
if (mode === "remote") {
118139
// In remote mode, /title might not be a valid command, so just check we're in remote mode
119140
expect(frameAfterCommand).toContain("Remote Mode");
@@ -124,9 +145,12 @@ describe("TUIChat - Slash Commands Tests", () => {
124145

125146
// Now add a space and arguments
126147
stdin.write(" My Session Title");
127-
await waitForNextRender();
128148

129-
const frameAfterArgs = lastFrame();
149+
let frameAfterArgs = lastFrame();
150+
await waitForCondition(() => {
151+
frameAfterArgs = lastFrame() ?? "";
152+
return frameAfterArgs.includes("My Session Title");
153+
});
130154

131155
// Check that the UI is still functional after adding arguments
132156
if (mode === "remote") {
@@ -145,19 +169,27 @@ describe("TUIChat - Slash Commands Tests", () => {
145169
async (mode) => {
146170
const { lastFrame, stdin } = renderInMode(mode);
147171

148-
// Type a complete command with arguments
149172
stdin.write("/title Test Session");
150-
await waitForNextRender();
151173

152-
const frameBeforeEnter = lastFrame();
174+
let frameBeforeEnter = lastFrame();
175+
await waitForCondition(() => {
176+
frameBeforeEnter = lastFrame() ?? "";
177+
return (
178+
frameBeforeEnter.includes("/title") &&
179+
frameBeforeEnter.includes("Test Session")
180+
);
181+
});
182+
153183
expect(frameBeforeEnter).toContain("/title");
154184
expect(frameBeforeEnter).toContain("Test Session");
155185

156-
// Press Enter - this should execute the command, not try to autocomplete
157186
stdin.write("\r");
158-
await waitForNextRender();
159187

160-
const frameAfterEnter = lastFrame();
188+
let frameAfterEnter = lastFrame();
189+
await waitForCondition(() => {
190+
frameAfterEnter = lastFrame() ?? "";
191+
return frameAfterEnter.length > 0;
192+
});
161193

162194
// Should not crash and should clear the input (or show command execution)
163195
expect(frameAfterEnter).toBeDefined();

0 commit comments

Comments
 (0)