// @vitest-environment happy-dom import { act } from "react"; import { afterEach, describe, expect, it, vi } from "vitest"; import { createRoot } from "react-dom/client"; import { AudioFxGroup } from "./propertyPanelAudioFxGroup.js"; import type { DomEditSelection } from "./domEditingTypes"; import { EFFECT_COPY } from "@hyperframes/core/audio-fx-copy"; import { liveTime, usePlayerStore } from "../../player"; /** * What a knob is CALLED in the panel, looked up rather than spelled out. * * The rack speaks the plain-language layer now, so a row is addressed by the * parameter it belongs to and the copy decides the words. Hard-coding them here * would make every copy edit a test edit, and these tests are about which row * carries the automate button — not about how it reads. */ function plainLabel(effectId: string, key: string): string { const label = EFFECT_COPY[effectId]?.params[key]?.label; if (!label) throw new Error(`no copy for ${effectId}.${key}`); return label; } (globalThis as unknown as { IS_REACT_ACT_ENVIRONMENT: boolean }).IS_REACT_ACT_ENVIRONMENT = true; const CHAIN = JSON.stringify({ version: 1, nodes: [{ type: "lowpass", id: "n1", params: { frequency: 900, q: 1.2, poles: "2" } }], }); // Each mount appends its tracks to the document; without clearing, a later // "only one audio track" case would still find the previous test's sibling. afterEach(() => { document.body.innerHTML = ""; }); /** * A selected `