Preserve terminal output across log sessions
This commit is contained in:
@@ -111,7 +111,7 @@ describe("ServerManagementTerminalDrawer", () => {
|
|||||||
expect(apiMocks.dispatchSourceRCONCommand).not.toHaveBeenCalled();
|
expect(apiMocks.dispatchSourceRCONCommand).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("clears generation A on a new session and rejects late generation A events", async () => {
|
it("keeps visible output on a new session and rejects late generation A events", async () => {
|
||||||
await renderDrawer();
|
await renderDrawer();
|
||||||
await emitSession("session-a");
|
await emitSession("session-a");
|
||||||
await emitStream(logStream("stdout-a", "session-a", "process.stdout"));
|
await emitStream(logStream("stdout-a", "session-a", "process.stdout"));
|
||||||
@@ -122,14 +122,14 @@ describe("ServerManagementTerminalDrawer", () => {
|
|||||||
await emitStream(logStream("stdout-b", "session-b", "process.stdout"));
|
await emitStream(logStream("stdout-b", "session-b", "process.stdout"));
|
||||||
await emitLog("stdout-b", "session-b", "process.stdout", logEntry(1, "generation B output"));
|
await emitLog("stdout-b", "session-b", "process.stdout", logEntry(1, "generation B output"));
|
||||||
|
|
||||||
expect(container?.textContent).not.toContain("generation A output");
|
expect(container?.textContent).toContain("generation A output");
|
||||||
expect(container?.textContent).not.toContain("late generation A output");
|
expect(container?.textContent).not.toContain("late generation A output");
|
||||||
expect(container?.textContent).toContain("generation B output");
|
expect(container?.textContent).toContain("generation B output");
|
||||||
expect(container?.textContent).toContain("Run 已切换到新的受管进程输出会话");
|
expect(container?.textContent).toContain("Run 已切换到新的受管进程输出会话");
|
||||||
expect(apiMocks.openServerLogEvents).toHaveBeenCalledTimes(1);
|
expect(apiMocks.openServerLogEvents).toHaveBeenCalledTimes(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("clears a stopped session and restores the running session on the same SSE connection", async () => {
|
it("keeps visible output through a stopped boundary and restores the running session on the same SSE connection", async () => {
|
||||||
await renderDrawer();
|
await renderDrawer();
|
||||||
await emitSession("session-a");
|
await emitSession("session-a");
|
||||||
await emitStream(logStream("stdout-a", "session-a", "process.stdout"));
|
await emitStream(logStream("stdout-a", "session-a", "process.stdout"));
|
||||||
@@ -137,14 +137,14 @@ describe("ServerManagementTerminalDrawer", () => {
|
|||||||
|
|
||||||
await emitSession();
|
await emitSession();
|
||||||
await emitLog("stdout-a", "session-a", "process.stdout", logEntry(2, "late output after stop"));
|
await emitLog("stdout-a", "session-a", "process.stdout", logEntry(2, "late output after stop"));
|
||||||
expect(container?.textContent).not.toContain("running output before stop");
|
expect(container?.textContent).toContain("running output before stop");
|
||||||
expect(container?.textContent).not.toContain("late output after stop");
|
expect(container?.textContent).not.toContain("late output after stop");
|
||||||
expect(container?.textContent).toContain("当前没有可跟随的受管进程输出");
|
expect(container?.textContent).toContain("当前没有可跟随的受管进程输出");
|
||||||
|
|
||||||
await emitSession("session-b");
|
await emitSession("session-b");
|
||||||
await emitStream(logStream("stdout-b", "session-b", "process.stdout"));
|
await emitStream(logStream("stdout-b", "session-b", "process.stdout"));
|
||||||
await emitLog("stdout-b", "session-b", "process.stdout", logEntry(1, "running output after recovery"));
|
await emitLog("stdout-b", "session-b", "process.stdout", logEntry(1, "running output after recovery"));
|
||||||
expect(container?.textContent).not.toContain("running output before stop");
|
expect(container?.textContent).toContain("running output before stop");
|
||||||
expect(container?.textContent).toContain("running output after recovery");
|
expect(container?.textContent).toContain("running output after recovery");
|
||||||
expect(apiMocks.openServerLogEvents).toHaveBeenCalledTimes(1);
|
expect(apiMocks.openServerLogEvents).toHaveBeenCalledTimes(1);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -169,9 +169,10 @@ export function ServerManagementTerminalDrawer({ open, serverId, serverName, plu
|
|||||||
setLiveSessionId(nextSessionId);
|
setLiveSessionId(nextSessionId);
|
||||||
if (previousSessionId === nextSessionId) return;
|
if (previousSessionId === nextSessionId) return;
|
||||||
setStreams({ status: "ready", data: [] });
|
setStreams({ status: "ready", data: [] });
|
||||||
setLines(nextSessionId
|
setLines((current) => mergeTerminalLines(current, [nextSessionId
|
||||||
? [terminalSystemLine("info", previousSessionId === undefined ? "已跟随当前受管进程输出会话。" : "Run 已切换到新的受管进程输出会话。", "SYSTEM", `session-${nextSessionId}`, serverTimeRef.current)]
|
? terminalSystemLine("info", previousSessionId === undefined ? "已跟随当前受管进程输出会话。" : "Run 已切换到新的受管进程输出会话。", "SYSTEM", `session-${nextSessionId}`, serverTimeRef.current)
|
||||||
: [terminalSystemLine("warn", "当前没有可跟随的受管进程输出;旧日志可从历史查看。", "SYSTEM", "session-empty", serverTimeRef.current)]);
|
: terminalSystemLine("warn", "当前没有可跟随的受管进程输出;旧日志可从历史查看。", "SYSTEM", "session-empty", serverTimeRef.current)
|
||||||
|
]));
|
||||||
lockTerminalFollow();
|
lockTerminalFollow();
|
||||||
});
|
});
|
||||||
events.addEventListener("stream", (event) => {
|
events.addEventListener("stream", (event) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user