This commit is contained in:
@@ -284,9 +284,40 @@ describe("sanitizeLayout - session panel handling", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("tryRestoreLayout - phantom session panel filtering", () => {
|
||||
describe("tryRestoreLayout - env restore", () => {
|
||||
beforeEach(() => {
|
||||
vi.restoreAllMocks();
|
||||
document.body.replaceChildren();
|
||||
});
|
||||
|
||||
it("reconciles a stale saved grid width with the live container before applying fixups", () => {
|
||||
const layout = buildLayout({ centerSize: 650, rightSize: 900 });
|
||||
layout.grid.width = 1900;
|
||||
vi.spyOn(localStorage, "getEnvLayout").mockReturnValue(layout);
|
||||
vi.spyOn(localStorage, "getEnvMaximizeState").mockReturnValue(null);
|
||||
|
||||
const container = document.createElement("div");
|
||||
const dockview = document.createElement("div");
|
||||
dockview.className = "dv-dockview";
|
||||
container.appendChild(dockview);
|
||||
document.body.appendChild(container);
|
||||
Object.defineProperties(container, {
|
||||
clientWidth: { value: 1260 },
|
||||
clientHeight: { value: 700 },
|
||||
});
|
||||
|
||||
const api = makeFakeRestoreApi();
|
||||
Object.defineProperties(api, {
|
||||
width: { value: 1900, writable: true },
|
||||
height: { value: 600, writable: true },
|
||||
});
|
||||
|
||||
expect(tryRestoreLayout(api, "env-stale-width", VALID_COMPONENTS)).toBe(true);
|
||||
expect(api.fromJSON).toHaveBeenCalledOnce();
|
||||
expect(api.layout).toHaveBeenCalledWith(1260, 700);
|
||||
expect((api.fromJSON as ReturnType<typeof vi.fn>).mock.invocationCallOrder[0]).toBeLessThan(
|
||||
(api.layout as ReturnType<typeof vi.fn>).mock.invocationCallOrder[0],
|
||||
);
|
||||
});
|
||||
|
||||
it("restores the (stripped) layout when every session in the saved env-layout is a phantom", () => {
|
||||
|
||||
@@ -185,6 +185,8 @@ function applyFixupsWithMaximize(
|
||||
if (savedMax) {
|
||||
applySavedMaximize(api, savedMax, savedRightWidth);
|
||||
} else {
|
||||
const { width, height } = measureDockviewContainer(api);
|
||||
api.layout(width, height);
|
||||
// Anchor the right column to its per-env saved width (see
|
||||
// `captureRightTarget`) so a page reload restores the task's remembered
|
||||
// width instead of resetting it to the default.
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { test, expect } from "../../fixtures/test-base";
|
||||
import { computeRightMaxPx } from "../../../lib/state/layout-manager/caps";
|
||||
import { TERMINAL_DEFAULT_ID } from "../../../lib/state/layout-manager/constants";
|
||||
import {
|
||||
WIDE_VIEWPORT,
|
||||
openWideTask,
|
||||
@@ -48,6 +49,73 @@ test.describe("Right pane resize — container-proportional cap", () => {
|
||||
expectApproxWidth(after, before, 12);
|
||||
});
|
||||
|
||||
test("initial restore reconciles a stale saved grid width without a manual resize", async ({
|
||||
testPage,
|
||||
apiClient,
|
||||
seedData,
|
||||
}) => {
|
||||
await testPage.setViewportSize({ width: 2200, height: 900 });
|
||||
const task = await apiClient.createTaskWithAgent(
|
||||
seedData.workspaceId,
|
||||
"Right stale grid restore",
|
||||
seedData.agentProfileId,
|
||||
{
|
||||
description: "/e2e:simple-message",
|
||||
workflow_id: seedData.workflowId,
|
||||
workflow_step_id: seedData.startStepId,
|
||||
repository_ids: [seedData.repositoryId],
|
||||
},
|
||||
);
|
||||
if (!task.session_id) throw new Error("created task did not return a session_id");
|
||||
await testPage.goto(`/t/${task.id}`);
|
||||
const session = new SessionPage(testPage);
|
||||
await session.waitForLoad();
|
||||
await session.waitForDockviewReady();
|
||||
expect(await resizeColumnViaSplitview(testPage, "right", 900)).toBeGreaterThan(800);
|
||||
|
||||
const staleLayout = await testPage.evaluate((sessionId) => {
|
||||
type StoreWindow = Window & {
|
||||
__KANDEV_E2E_STORE__?: {
|
||||
getState: () => { environmentIdBySessionId: Record<string, string> };
|
||||
};
|
||||
};
|
||||
const store = (window as StoreWindow).__KANDEV_E2E_STORE__;
|
||||
const envId = store?.getState().environmentIdBySessionId[sessionId];
|
||||
if (!envId) throw new Error("environment id not hydrated");
|
||||
const key = `kandev.dockview.env-layout-v3.${envId}`;
|
||||
const raw = window.sessionStorage.getItem(key);
|
||||
if (!raw) throw new Error("env layout was not persisted");
|
||||
const layout = JSON.parse(raw);
|
||||
const columns = layout.grid?.root?.data;
|
||||
if (!Array.isArray(columns) || columns.length < 2) {
|
||||
throw new Error("saved layout does not contain center and right columns");
|
||||
}
|
||||
layout.grid.width = 1900;
|
||||
columns[0].size = 1000;
|
||||
columns[columns.length - 1].size = 900;
|
||||
return { key, json: JSON.stringify(layout) };
|
||||
}, task.session_id);
|
||||
|
||||
await testPage.addInitScript(({ key, json }) => {
|
||||
window.sessionStorage.setItem(key, json);
|
||||
}, staleLayout);
|
||||
await testPage.setViewportSize({ width: 1540, height: 900 });
|
||||
await testPage.reload();
|
||||
await session.waitForLoad();
|
||||
await session.waitForDockviewReady();
|
||||
|
||||
const dockviewBox = await testPage.locator(".dv-dockview").boundingBox();
|
||||
expect(dockviewBox).not.toBeNull();
|
||||
const rightWidth = await getDockviewGroupWidth(testPage, "files");
|
||||
const terminalWidth = await getDockviewGroupWidth(testPage, TERMINAL_DEFAULT_ID);
|
||||
const centerWidth = await getDockviewGroupWidth(testPage, `session:${task.session_id}`);
|
||||
const cap = computeRightMaxPx(dockviewBox?.width ?? 0);
|
||||
expect(rightWidth).toBeLessThanOrEqual(cap + 10);
|
||||
expectApproxWidth(terminalWidth, rightWidth, 10);
|
||||
// Allow 2px of rendering tolerance around the 480px center comfort reserve.
|
||||
expect(centerWidth).toBeGreaterThanOrEqual(478);
|
||||
});
|
||||
|
||||
test("viewport shrink re-clamps an over-cap pinned width", async ({
|
||||
testPage,
|
||||
apiClient,
|
||||
|
||||
Reference in New Issue
Block a user