From adfa211bbf23084426071e0d0ed743c1fa4489da Mon Sep 17 00:00:00 2001 From: can1357 Date: Tue, 18 Aug 2026 11:24:23 +0300 Subject: [PATCH] chore: bump version to 17.3.7 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Retry: deflaked tui IME preedit border test (#5563) — VirtualTerminal.waitForRender's fixed 40ms sleep raced TUI's throttled render timer on starved CI runners, reading the pre-input frame; waitForRender now takes an optional settle predicate polled up to 2s and the test keys on the rendered content. --- packages/tui/test/editor.test.ts | 2 +- packages/tui/test/virtual-terminal.ts | 13 +++++++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/packages/tui/test/editor.test.ts b/packages/tui/test/editor.test.ts index 1af316879..f884fb314 100644 --- a/packages/tui/test/editor.test.ts +++ b/packages/tui/test/editor.test.ts @@ -1025,7 +1025,7 @@ describe("Editor component", () => { await terminal.waitForRender(); for (const char of "ast") editor.handleInput(char); tui.requestRender(); - await terminal.waitForRender(); + await terminal.waitForRender(() => terminal.getViewport()[1]?.includes("ast") === true); const beforePreedit = terminal.getViewport().map(row => row.trimEnd()); expect(beforePreedit.slice(0, 3)).toEqual(["+------------------+", "| ast", "+------------------+"]); diff --git a/packages/tui/test/virtual-terminal.ts b/packages/tui/test/virtual-terminal.ts index 3821ba0c8..8a7908bd6 100644 --- a/packages/tui/test/virtual-terminal.ts +++ b/packages/tui/test/virtual-terminal.ts @@ -280,12 +280,21 @@ export class VirtualTerminal implements Terminal { // --- Test-only helpers --------------------------------------------------- - /** Wait for TUI's throttled render pipeline to settle (matches the ~33ms frame budget). */ - async waitForRender(): Promise { + /** + * Wait for TUI's throttled render pipeline to settle (matches the ~33ms + * frame budget). Fixed sleeps race starved CI timers, so callers asserting + * on a specific frame pass `until`; polling continues (10ms slices, ~2s + * cap) until the predicate observes the expected viewport. + */ + async waitForRender(until?: () => boolean): Promise { const nextTick = Promise.withResolvers(); process.nextTick(nextTick.resolve); await nextTick.promise; await Bun.sleep(40); + if (until) { + const deadline = Date.now() + 2_000; + while (!until() && Date.now() < deadline) await Bun.sleep(10); + } await this.flush(); }