mirror of
https://github.com/Termix-SSH/Termix.git
synced 2026-10-28 14:15:24 +00:00
feat: reconnect all disconnected terminal tabs (#1523)
This commit is contained in:
1 parent
5860921cbe
commit
e161ad22e0
12 files changed
+265
-17
No files matched your search
@@ -0,0 +1,72 @@
|
||||
// @vitest-environment node
|
||||
import fs from "node:fs";
|
||||
import vm from "node:vm";
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
|
||||
const source = fs.readFileSync(
|
||||
new URL("../../../src/frontend/terminal/Terminal.tsx", import.meta.url),
|
||||
"utf8",
|
||||
);
|
||||
const reconnect = source.slice(
|
||||
source.indexOf(" function reconnectTerminal()"),
|
||||
source.indexOf(" useImperativeHandle("),
|
||||
);
|
||||
const methods = source.slice(
|
||||
source.indexOf(" reconnect: reconnectTerminal,"),
|
||||
source.indexOf(" isConnected: () => isConnected,"),
|
||||
);
|
||||
|
||||
function createHandle(overrides: Record<string, unknown> = {}) {
|
||||
const context = {
|
||||
terminal: { cols: 80, rows: 24, clear: vi.fn() },
|
||||
isConnected: false,
|
||||
isUnmountingRef: { current: false },
|
||||
shouldNotReconnectRef: { current: true },
|
||||
isReconnectingRef: { current: false },
|
||||
isConnectingRef: { current: false },
|
||||
reconnectTimeoutRef: { current: null },
|
||||
reconnectAttempts: { current: 8 },
|
||||
wasDisconnectedBySSH: { current: true },
|
||||
wasConnectedRef: { current: false },
|
||||
updateConnectionError: vi.fn(),
|
||||
setShowDisconnectedOverlay: vi.fn(),
|
||||
connectToHost: vi.fn(() => {
|
||||
context.isConnectingRef.current = true;
|
||||
}),
|
||||
...overrides,
|
||||
};
|
||||
const handle = vm.runInNewContext(
|
||||
reconnect + `\n({${methods}})`,
|
||||
context,
|
||||
) as { reconnectIfDisconnected: () => boolean; reconnect: () => void };
|
||||
return { handle, context };
|
||||
}
|
||||
|
||||
describe("terminal bulk reconnect handle", () => {
|
||||
it("uses the manual reconnect flow after a dropped SSH session and rejects duplicate requests", () => {
|
||||
const { handle, context } = createHandle();
|
||||
expect(handle.reconnectIfDisconnected()).toBe(true);
|
||||
expect(context.connectToHost).toHaveBeenCalledWith(80, 24);
|
||||
expect(context.shouldNotReconnectRef.current).toBe(false);
|
||||
expect(context.reconnectAttempts.current).toBe(0);
|
||||
expect(context.wasDisconnectedBySSH.current).toBe(false);
|
||||
expect(handle.reconnectIfDisconnected()).toBe(false);
|
||||
expect(context.connectToHost).toHaveBeenCalledOnce();
|
||||
});
|
||||
it.each([
|
||||
{ isConnected: true },
|
||||
{ isConnectingRef: { current: true } },
|
||||
{ isReconnectingRef: { current: true } },
|
||||
{ reconnectTimeoutRef: { current: 1 } },
|
||||
{ isUnmountingRef: { current: true } },
|
||||
{ terminal: null },
|
||||
])(
|
||||
"does not interrupt a connected, busy or unavailable terminal: %j",
|
||||
(overrides) => {
|
||||
const { handle, context } = createHandle(overrides);
|
||||
expect(handle.reconnectIfDisconnected()).toBe(false);
|
||||
expect(context.connectToHost).not.toHaveBeenCalled();
|
||||
expect(context.shouldNotReconnectRef.current).toBe(true);
|
||||
},
|
||||
);
|
||||
});
|
||||
Reference in new issue
Block a user