From e6e564d4610814194aa21529d3d033fd102d8033 Mon Sep 17 00:00:00 2001 From: Ayman Bagabas Date: Wed, 5 Aug 2026 18:26:14 -0400 Subject: [PATCH] test(js): read the cursor next to the state it is compared against `echo roundtrip drives a real session` compared `getCursor()` against a `state.cursor` captured five calls earlier. The shell draws its next prompt after the command finishes, which moves the cursor, so a prompt landing between the two reads made them differ by its width: macOS CI saw `{x: 0}` against `{x: 2}`. Reading them next to each other narrows that window about sixfold, from the five intervening round trips to one. It narrows rather than closes it. The reason a window exists at all is that `wait command` falls back to "the prompt came back and the screen is idle" when a session has no shell integration, and an idle screen is indistinguishable from a prompt that has not started. `waitIdle` is no help for the same reason: measured against a shell with a deliberately slow prompt, it returned with the cursor still at column 0, because the screen was quiet precisely because the prompt had not begun. That root cause is tracked in #98. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Ayman Bagabas --- bindings/js/test/integration.test.mjs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/bindings/js/test/integration.test.mjs b/bindings/js/test/integration.test.mjs index 8b9de15..7c538a5 100644 --- a/bindings/js/test/integration.test.mjs +++ b/bindings/js/test/integration.test.mjs @@ -30,14 +30,22 @@ test("echo roundtrip drives a real session", async () => { await su.waitCommand(); await su.expectText("hello-sdk", { strict: false }); await su.expectExitCode(0); + const state = await su.state(); + // Read next to the snapshot it is compared against. The shell draws its + // next prompt after the command finishes, which moves the cursor, and + // these two calls read it separately: with other calls in between, the + // prompt lands between them and they disagree by its width. + // + // `waitIdle` is not the barrier it looks like here, since the screen is + // quiet *because* the prompt has not started, so idle arrives first. + assert.deepEqual(await su.getCursor(), state.cursor); assert.ok(state.cols > 0); assert.match(await su.text(), /hello-sdk/); assert.match(await su.getCommand(), /echo hello-sdk/); assert.match(await su.getOutput(), /hello-sdk/); assert.equal(await su.getExitCode(), 0); assert.equal(typeof (await su.getCwd()), "string"); - assert.deepEqual(await su.getCursor(), state.cursor); assert.deepEqual(await su.getSize(), { cols: state.cols, rows: state.rows }); await su.resize(92, 26);