import { act, cleanup, fireEvent, render, screen } from "@testing-library/react";
import { afterEach, beforeAll, describe, expect, it, vi } from "vitest";
import {
createToolcraftAppTestSchema,
installToolcraftAppTestWindow,
PanelWorkspaceProbe,
} from "./toolcraft-app-test-utils";
import { ToolcraftApp } from "./toolcraft-app";
beforeAll(() => {
installToolcraftAppTestWindow();
});
afterEach(() => {
vi.useRealTimers();
cleanup();
window.localStorage.clear();
});
describe("ToolcraftApp panel workspace", () => {
it("exposes persistence lifecycle status on the runtime shell", () => {
vi.useFakeTimers();
const { container } = render(
,
);
const app = container.querySelector('[data-slot="toolcraft-runtime-app"]');
expect(app?.getAttribute("data-toolcraft-persistence-status")).toBe(
"pending",
);
act(() => {
vi.advanceTimersByTime(120);
});
expect(app?.getAttribute("data-toolcraft-persistence-status")).toBe(
"success",
);
});
it("binds panel and stable section collapse to committed workspace state", () => {
const schema = createToolcraftAppTestSchema();
const basicSectionId = schema.panels.controls?.sections.find(
(section) => section.title === "Basic",
)?.id;
if (!basicSectionId) {
throw new Error("Expected the Basic controls section to have a stable id.");
}
render(
} schema={schema} />,
);
const sectionHeader = screen
.getByText("Basic")
.closest('[data-slot="control-section-header"]');
if (!sectionHeader) {
throw new Error("Expected the Basic controls section header.");
}
fireEvent.click(sectionHeader);
fireEvent.click(screen.getByRole("button", { name: "Collapse controls" }));
const panels = JSON.parse(
screen.getByTestId("panel-workspace-state").textContent ?? "{}",
);
expect(panels.controls).toMatchObject({
collapsed: true,
collapsedSections: { [basicSectionId]: true },
});
expect(screen.getByTestId("panel-workspace-history").textContent).toBe("0");
});
it("restores a moved panel and commits its reset through the real shell", () => {
const schema = createToolcraftAppTestSchema();
if (schema.persistence.storage !== "localStorage") {
throw new Error("Expected default local persistence");
}
window.localStorage.setItem(
schema.persistence.key,
JSON.stringify({
state: {
panels: {
controls: {
offset: { x: 72, y: -24 },
snapEdge: "left",
},
},
},
version: schema.persistence.version,
}),
);
render(
} schema={schema} />,
);
expect(
JSON.parse(
screen.getByTestId("panel-workspace-state").textContent ?? "{}",
).controls,
).toMatchObject({
offset: { x: 72, y: -24 },
snapEdge: "left",
});
const dragHandle = screen
.getByText("Controls")
.closest('[data-panel-drag-handle=""]');
if (!dragHandle) {
throw new Error("Expected the Controls panel drag handle.");
}
fireEvent.doubleClick(dragHandle);
const resetControls = JSON.parse(
screen.getByTestId("panel-workspace-state").textContent ?? "{}",
).controls;
expect(resetControls).toMatchObject({ offset: { x: 0, y: 0 } });
expect(resetControls).not.toHaveProperty("snapEdge");
expect(screen.getByTestId("panel-workspace-history").textContent).toBe("0");
});
});