diff --git a/src/renderer/src/components/terminal-pane/pty-connection.test.ts b/src/renderer/src/components/terminal-pane/pty-connection.test.ts index 5cb40457f98..5868b7d8334 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection.test.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection.test.ts @@ -947,53 +947,92 @@ describe('connectPanePty', () => { } }) - it('writes visible split-pane PTY bytes immediately even when the tab is not active', async () => { + it('writes visible split-pane PTY bytes on the foreground flush even when the tab is not active', async () => { + const pendingTimeouts: (() => void)[] = [] + const originalSetTimeout = globalThis.setTimeout + globalThis.setTimeout = vi.fn((fn: () => void) => { + pendingTimeouts.push(fn) + return 999 as unknown as ReturnType + }) as unknown as typeof setTimeout + const { connectPanePty } = await import('./pty-connection') - const transport = createMockTransport() - const capturedDataCallback: { current: ((data: string) => void) | null } = { current: null } - transport.connect.mockImplementation(async ({ callbacks }: { callbacks: ConnectCallbacks }) => { - capturedDataCallback.current = callbacks.onData ?? null - return 'pty-id' - }) - transportFactoryQueue.push(transport) - const pane = createPane(1) - const manager = createManager(1) - const deps = createDeps({ - isActiveRef: { current: false }, - isVisibleRef: { current: true } - }) + try { + const transport = createMockTransport() + const capturedDataCallback: { current: ((data: string) => void) | null } = { current: null } + transport.connect.mockImplementation( + async ({ callbacks }: { callbacks: ConnectCallbacks }) => { + capturedDataCallback.current = callbacks.onData ?? null + return 'pty-id' + } + ) + transportFactoryQueue.push(transport) - connectPanePty(pane as never, manager as never, deps as never) - await flushAsyncTicks(6) + const pane = createPane(1) + const manager = createManager(1) + const deps = createDeps({ + isActiveRef: { current: false }, + isVisibleRef: { current: true } + }) - expect(capturedDataCallback.current).not.toBeNull() - capturedDataCallback.current?.('visible split output\r\n') + connectPanePty(pane as never, manager as never, deps as never) + await flushAsyncTicks(6) - expect(pane.terminal.write).toHaveBeenCalledWith('visible split output\r\n') + expect(capturedDataCallback.current).not.toBeNull() + capturedDataCallback.current?.('visible split output\r\n') + expect(pane.terminal.write).not.toHaveBeenCalledWith('visible split output\r\n') + + for (const fn of pendingTimeouts) { + fn() + } + + expect(pane.terminal.write).toHaveBeenCalledWith('visible split output\r\n') + } finally { + globalThis.setTimeout = originalSetTimeout + } }) it('marks panes that receive Arabic output for DOM rendering', async () => { + const pendingTimeouts: (() => void)[] = [] + const originalSetTimeout = globalThis.setTimeout + globalThis.setTimeout = vi.fn((fn: () => void) => { + pendingTimeouts.push(fn) + return 999 as unknown as ReturnType + }) as unknown as typeof setTimeout + const { connectPanePty } = await import('./pty-connection') - const transport = createMockTransport() - const capturedDataCallback: { current: ((data: string) => void) | null } = { current: null } - transport.connect.mockImplementation(async ({ callbacks }: { callbacks: ConnectCallbacks }) => { - capturedDataCallback.current = callbacks.onData ?? null - return 'pty-id' - }) - transportFactoryQueue.push(transport) - const pane = createPane(1) - const manager = createManager(1) - const deps = createDeps() + try { + const transport = createMockTransport() + const capturedDataCallback: { current: ((data: string) => void) | null } = { current: null } + transport.connect.mockImplementation( + async ({ callbacks }: { callbacks: ConnectCallbacks }) => { + capturedDataCallback.current = callbacks.onData ?? null + return 'pty-id' + } + ) + transportFactoryQueue.push(transport) - connectPanePty(pane as never, manager as never, deps as never) - await flushAsyncTicks(6) + const pane = createPane(1) + const manager = createManager(1) + const deps = createDeps() - capturedDataCallback.current?.('Arabic: السلام عليكم\r\n') + connectPanePty(pane as never, manager as never, deps as never) + await flushAsyncTicks(6) - expect(manager.markPaneHasComplexScriptOutput).toHaveBeenCalledWith(1) - expect(pane.terminal.write).toHaveBeenCalledWith('Arabic: السلام عليكم\r\n') + capturedDataCallback.current?.('Arabic: السلام عليكم\r\n') + + expect(manager.markPaneHasComplexScriptOutput).toHaveBeenCalledWith(1) + expect(pane.terminal.write).not.toHaveBeenCalledWith('Arabic: السلام عليكم\r\n') + + for (const fn of pendingTimeouts) { + fn() + } + + expect(pane.terminal.write).toHaveBeenCalledWith('Arabic: السلام عليكم\r\n') + } finally { + globalThis.setTimeout = originalSetTimeout + } }) it('reattaches via daemon sessionId when an in-session PTY is live', async () => {