import { describe, expect, it } from "vitest"; import { defineToolcraft, fireEvent, renderControlsPanel, renderControlsPanelWithSchema, screen } from "../testing/controls-panel-test-utils"; describe("ControlsPanel runtime setup controls", () => { it("commits canvas size controls to runtime state on blur or Enter", () => { renderControlsPanel(); const canvasSizeGroup = screen.getByText("Canvas width").closest( '[data-control-layout="inline"][data-control-layout-columns="2"]', ); expect(canvasSizeGroup).toBeTruthy(); expect(canvasSizeGroup?.textContent).toContain("Canvas width"); expect(canvasSizeGroup?.textContent).toContain("Canvas height"); const widthInput = screen.getByDisplayValue("320") as HTMLInputElement; fireEvent.change(widthInput, { target: { value: "640" } }); expect(screen.getByTestId("canvas-size").textContent).toBe("320,180"); expect(widthInput.value).toBe("640"); fireEvent.blur(widthInput); expect(screen.getByTestId("canvas-size").textContent).toBe("640,180"); const heightInput = screen.getByDisplayValue("180") as HTMLInputElement; fireEvent.change(heightInput, { target: { value: "360" } }); expect(screen.getByTestId("canvas-size").textContent).toBe("640,180"); fireEvent.keyDown(heightInput, { code: "Enter", key: "Enter" }); expect(screen.getByTestId("canvas-size").textContent).toBe("640,360"); fireEvent.click(screen.getByRole("button", { name: "Reset controls" })); expect(screen.getByTestId("canvas-size").textContent).toBe("320,180"); }); it("renders editable-output aspect ratio controls with the current canvas preset", () => { const schema = defineToolcraft({ canvas: { enabled: true, size: { height: 1080, unit: "px", width: 1440 }, sizing: { mode: "editable-output" }, }, panels: { controls: { sections: [], title: "Controls", }, }, }); const { container } = renderControlsPanelWithSchema(schema); expect(screen.getByTestId("canvas-size").textContent).toBe("1440,1080"); const aspectRatioControl = container.querySelector( '[data-slot="canvas-aspect-ratio-control"]', ); expect(screen.getByText("Aspect ratio")).toBeTruthy(); expect(aspectRatioControl?.textContent).toContain("4:3"); const values = JSON.parse(screen.getByTestId("values-json").textContent ?? "{}"); expect(values["canvas.aspectRatio"]).toEqual({ height: 3, mode: "preset", value: "4:3", width: 4, }); expect(values["canvas.size.width"]).toBe(1440); expect(values["canvas.size.height"]).toBe(1080); }); it("switches editable-output aspect ratio to custom after manual size edits", () => { const schema = defineToolcraft({ canvas: { enabled: true, size: { height: 1080, unit: "px", width: 1920 }, sizing: { mode: "editable-output" }, }, panels: { controls: { sections: [], title: "Controls", }, }, }); renderControlsPanelWithSchema(schema); const widthInput = screen.getByDisplayValue("1920") as HTMLInputElement; fireEvent.change(widthInput, { target: { value: "1600" } }); fireEvent.blur(widthInput); expect(screen.getByTestId("canvas-size").textContent).toBe("1600,1080"); expect(screen.getAllByText("Custom").length).toBeGreaterThan(0); expect(screen.queryByDisplayValue("40")).toBeNull(); expect(screen.queryByDisplayValue("27")).toBeNull(); expect(JSON.parse(screen.getByTestId("values-json").textContent ?? "{}")).toMatchObject({ "canvas.aspectRatio": { height: 27, mode: "custom", value: "40:27", width: 40, }, "canvas.size.height": 1080, "canvas.size.width": 1600, }); }); it("renders raster render scale as the last technical setup control", () => { const schema = defineToolcraft({ canvas: { enabled: true, renderScale: true, size: { height: 1080, unit: "px", width: 1920 }, sizing: { mode: "editable-output" }, }, panels: { controls: { sections: [], title: "Controls", }, }, }); renderControlsPanelWithSchema(schema); const values = JSON.parse(screen.getByTestId("values-json").textContent ?? "{}"); expect(screen.getByText("Resolution scale")).toBeTruthy(); expect(screen.getByText("2")).toBeTruthy(); expect(values["canvas.renderScale"]).toBe(2); }); it("renders timeline extended mode as runtime panel state instead of product values", () => { const schema = defineToolcraft({ canvas: { enabled: true, renderScale: true, size: { height: 1080, unit: "px", width: 1920 }, sizing: { mode: "editable-output" }, }, panels: { controls: { sections: [], title: "Controls", }, timeline: { mode: "playback" }, }, }); renderControlsPanelWithSchema(schema, undefined, { timeline: { currentTimeSeconds: 2, expanded: true, isPlaying: true }, }); const timelineField = screen.getByText("Timeline").closest('[role="group"]'); const setupSection = timelineField?.closest("section"); const timelineSwitch = timelineField?.querySelector('[role="switch"]'); expect((setupSection?.textContent ?? "").indexOf("Resolution scale")).toBeLessThan( (setupSection?.textContent ?? "").indexOf("Timeline"), ); expect(screen.queryByRole("button", { name: "Timeline help" })).toBeNull(); expect( screen.queryByRole("button", { name: "Infinity canvas help" }), ).toBeNull(); expect(timelineSwitch?.getAttribute("aria-checked")).toBe("false"); expect(screen.getByTestId("timeline-panel-extended").textContent).toBe("undefined"); expect(screen.getByTestId("timeline-panel-hidden").textContent).toBe("undefined"); expect(screen.getByTestId("timeline-expanded").textContent).toBe("true"); fireEvent.click(timelineSwitch as HTMLElement); expect(timelineSwitch?.getAttribute("aria-checked")).toBe("true"); expect(screen.getByTestId("timeline-panel-extended").textContent).toBe("true"); expect(screen.getByTestId("timeline-panel-hidden").textContent).toBe("undefined"); expect(screen.getByTestId("timeline-expanded").textContent).toBe("true"); expect(JSON.parse(screen.getByTestId("values-json").textContent ?? "{}")).not.toHaveProperty( "panels.timeline.extended", ); fireEvent.click(screen.getByRole("button", { name: "Reset controls" })); expect(timelineSwitch?.getAttribute("aria-checked")).toBe("true"); expect(screen.getByTestId("timeline-panel-extended").textContent).toBe("true"); }); });