test(workspace): add split terminal view tests with corrected expectations
Added comprehensive tests for the split-terminal-view feature: - Default 1-pane layout (no multi-pane UI) - Switching to 2-pane and 4-pane layouts - Persisting layout and lane selections to localStorage - Fallback behavior when persisted lane IDs no longer exist Fixed test expectation: when a persisted lane ID no longer exists and falls back to unselected (null), both panes render as empty (pane-empty), not just one. Updated Run snapshot to reflect the new layout toggle buttons.
This commit is contained in:
@@ -7,7 +7,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
|
import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
|
||||||
import { render, act, screen, waitFor } from "@testing-library/react";
|
import { render, act, screen, waitFor, fireEvent } from "@testing-library/react";
|
||||||
import { MemoryRouter } from "react-router-dom";
|
import { MemoryRouter } from "react-router-dom";
|
||||||
import userEvent from "@testing-library/user-event";
|
import userEvent from "@testing-library/user-event";
|
||||||
|
|
||||||
@@ -633,3 +633,63 @@ describe("Workspace — proof gallery", () => {
|
|||||||
expect(gallery).toBeNull();
|
expect(gallery).toBeNull();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("split terminal view", () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
localStorage.clear();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("defaults to a single pane with no layout toggle pressed state implying 2 or 4", async () => {
|
||||||
|
await renderWorkspace();
|
||||||
|
expect(screen.getAllByTestId("console-body")).toHaveLength(1);
|
||||||
|
expect(screen.queryAllByTestId("pane-lane-select")).toHaveLength(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("switching to 2-pane layout renders two independent panes with lane pickers", async () => {
|
||||||
|
await renderWorkspace();
|
||||||
|
fireEvent.click(screen.getByRole("button", { name: /2.*pane/i }));
|
||||||
|
await settle();
|
||||||
|
expect(screen.getAllByTestId(/console-body|pane-empty/)).toHaveLength(2);
|
||||||
|
expect(screen.getAllByTestId("pane-lane-select")).toHaveLength(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("switching to 4-pane layout renders four panes", async () => {
|
||||||
|
await renderWorkspace();
|
||||||
|
fireEvent.click(screen.getByRole("button", { name: /4.*pane/i }));
|
||||||
|
await settle();
|
||||||
|
expect(screen.getAllByTestId(/console-body|pane-empty/)).toHaveLength(4);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("persists the layout and pane selections to localStorage across remounts", async () => {
|
||||||
|
const { unmount } = await renderWorkspace();
|
||||||
|
fireEvent.click(screen.getByRole("button", { name: /2.*pane/i }));
|
||||||
|
await settle();
|
||||||
|
const select = screen.getAllByTestId("pane-lane-select")[1];
|
||||||
|
fireEvent.change(select, { target: { value: String(lanesToReturn[1]!.id) } });
|
||||||
|
await settle();
|
||||||
|
unmount();
|
||||||
|
|
||||||
|
localStorage.clear();
|
||||||
|
localStorage.setItem(
|
||||||
|
"ccam.workspace.splitView",
|
||||||
|
JSON.stringify({ layout: 2, paneLaneIds: [null, lanesToReturn[1]!.id] })
|
||||||
|
);
|
||||||
|
|
||||||
|
await renderWorkspace();
|
||||||
|
expect(screen.getAllByTestId("pane-lane-select")).toHaveLength(2);
|
||||||
|
expect((screen.getAllByTestId("pane-lane-select")[1] as HTMLSelectElement).value).toBe(
|
||||||
|
String(lanesToReturn[1]!.id)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("falls back to unselected when a persisted lane id no longer exists", async () => {
|
||||||
|
localStorage.setItem(
|
||||||
|
"ccam.workspace.splitView",
|
||||||
|
JSON.stringify({ layout: 2, paneLaneIds: [9999, null] })
|
||||||
|
);
|
||||||
|
await renderWorkspace();
|
||||||
|
// Lane 9999 doesn't exist, so it falls back to null (unselected).
|
||||||
|
// The second pane is already null. Both render as pane-empty.
|
||||||
|
expect(screen.getAllByTestId("pane-empty")).toHaveLength(2);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|||||||
@@ -5778,6 +5778,31 @@ exports[`screen snapshots > Run 1`] = `
|
|||||||
<div
|
<div
|
||||||
class="flex min-h-0 flex-col gap-2"
|
class="flex min-h-0 flex-col gap-2"
|
||||||
>
|
>
|
||||||
|
<div
|
||||||
|
class="flex items-center gap-1.5"
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
aria-pressed="true"
|
||||||
|
class="rounded border px-2 py-1 text-xs border-accent bg-accent/15 text-accent"
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
1 pane
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
aria-pressed="false"
|
||||||
|
class="rounded border px-2 py-1 text-xs border-border text-fg-secondary hover:border-border-light"
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
2 pane
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
aria-pressed="false"
|
||||||
|
class="rounded border px-2 py-1 text-xs border-border text-fg-secondary hover:border-border-light"
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
4 pane
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
<div
|
<div
|
||||||
class="flex min-h-0 flex-1 flex-col gap-5"
|
class="flex min-h-0 flex-1 flex-col gap-5"
|
||||||
data-testid="console-body"
|
data-testid="console-body"
|
||||||
|
|||||||
Reference in New Issue
Block a user