import { describe, expect, it } from "vitest"; import { defineToolcraft, fireEvent, renderControlsPanelWithSchema, screen, } from "../testing/controls-panel-test-utils"; describe("ControlsPanel range and manual slider editing", () => { it("passes schema disabled state into range slider controls", () => { const schema = defineToolcraft({ base: { identity: { id: "runtime-test", title: "Toolcraft App" }, canvas: { enabled: true }, panels: { controls: { sections: [ { id: "test-section-1", controls: { band: { applicability: { mode: "always" as const }, defaultValue: [20, 80], disabled: true, label: "Band", max: 100, min: 0, step: 1, target: "shader.band", type: "rangeSlider", }, }, title: "Output", }, ], title: "Generation Controls", }, }, }, modules: [], }); const { container } = renderControlsPanelWithSchema(schema); const field = screen.getByText("Band").closest('[data-slot="field"]'); const slider = container.querySelector('[data-slot="slider"]'); expect(field?.getAttribute("data-disabled")).toBe("true"); expect(slider).toBeTruthy(); expect(slider?.hasAttribute("data-disabled")).toBe(true); }); it("commits common range slider value label separators", () => { const schema = defineToolcraft({ base: { identity: { id: "runtime-test", title: "Toolcraft App" }, canvas: { enabled: true }, panels: { controls: { sections: [ { id: "test-section-2", controls: { range: { applicability: { mode: "always" as const }, defaultValue: [20, 80], label: "Range", max: 100, min: 0, step: 1, target: "shape.range", type: "rangeSlider", unit: "%", }, }, title: "Shape", }, ], title: "Controls", }, }, }, modules: [], }); renderControlsPanelWithSchema(schema); for (const [draftValue, expectedValue, expectedLabel] of [ ["0/1", '"shape.range":[0,1]', "0% – 1%"], ["3/5", '"shape.range":[3,5]', "3% – 5%"], ["1-6", '"shape.range":[1,6]', "1% – 6%"], ["2-3", '"shape.range":[2,3]', "2% – 3%"], ["4 - 5", '"shape.range":[4,5]', "4% – 5%"], ["30%-150%", '"shape.range":[30,100]', "30% – 100%"], ["30% - 90%", '"shape.range":[30,90]', "30% – 90%"], ["30 % - 90 %", '"shape.range":[30,90]', "30% – 90%"], ["6–7", '"shape.range":[6,7]', "6% – 7%"], ["7—8", '"shape.range":[7,8]', "7% – 8%"], ["8−9", '"shape.range":[8,9]', "8% – 9%"], ] as const) { fireEvent.click(screen.getByRole("button", { name: "Edit Range value" })); const editor = screen.getByRole("textbox", { name: "Range value" }); editor.textContent = draftValue; fireEvent.blur(editor); expect(screen.getByTestId("values-json").textContent).toContain( expectedValue, ); expect( screen.getByRole("button", { name: "Edit Range value" }).textContent, ).toBe(expectedLabel); } }); it("steps manually edited slider values with arrow keys", () => { const schema = defineToolcraft({ base: { identity: { id: "runtime-test", title: "Toolcraft App" }, canvas: { enabled: true }, panels: { controls: { sections: [ { id: "test-section-3", controls: { opacity: { applicability: { mode: "always" as const }, defaultValue: 10, label: "Opacity", max: 100, min: 0, step: 5, target: "shape.opacity", type: "slider", unit: "%", }, }, title: "Shape", }, ], title: "Controls", }, }, }, modules: [], }); renderControlsPanelWithSchema(schema); fireEvent.click(screen.getByRole("button", { name: "Edit Opacity value" })); const editor = screen.getByRole("textbox", { name: "Opacity value" }); fireEvent.keyDown(editor, { key: "ArrowUp" }); expect(screen.getByTestId("values-json").textContent).toContain( '"shape.opacity":15', ); expect(editor.textContent).toBe("15%"); fireEvent.keyDown(editor, { key: "ArrowDown" }); expect(screen.getByTestId("values-json").textContent).toContain( '"shape.opacity":10', ); expect(editor.textContent).toBe("10%"); fireEvent.blur(editor); expect( screen.getByRole("button", { name: "Edit Opacity value" }).textContent, ).toBe("10%"); }); });