import { setupTest, startEngine, startClientInTmux, openCmdFifo, writeFifoCommand, wait, tmuxSendKeys, tmuxCapturePane, ensureGenTone, execSync, waitForStatusContaining, teardownTest } from './test_utils'; import * as path from "path"; import * as fs from "fs"; import * as globals from "./test_globals"; export async function testTUIRecordAndLoop(): Promise { console.log("\nTest: TUI RECORD AND LOOP (T key)"); setupTest(); const engine = await startEngine(); await startClientInTmux(); openCmdFifo(); ensureGenTone(); await wait(500); // press 't' to start recording on default cell (col 0, row 0) tmuxSendKeys("looper", "0", "t"); await wait(1000); // 1) Check status FIFO shows RECORD const statusRec = await waitForStatusContaining("RECORD", 5000); if (!statusRec.includes("RECORD")) { console.log(" FAIL: Status FIFO did not show RECORD after pressing t"); engine.kill(); teardownTest(); throw new Error("RECORD state not achieved via TUI"); } console.log(" PASS: Status FIFO shows RECORD"); // 2) Check tmux pane for 'R' indicator (first character of cell in grid) const paneAfterT = tmuxCapturePane("looper", "0"); const paneContainsR = paneAfterT.includes("R"); if (!paneContainsR) { console.log(" FAIL: TUI grid does not show 'R' indicator after pressing t"); console.log(" Pane excerpt (maybe): " + paneAfterT.slice(0, 1000)); engine.kill(); teardownTest(); throw new Error("Grid indicator not updated"); } console.log(" PASS: TUI grid shows 'R' indicator"); // Play tone into looper:ch0in (3 seconds) execSync(`${globals.GEN_TONE_BIN} 3.0 "looper:ch0in"`, { timeout: 8000 }); // press 't' again to stop recording -> loop tmuxSendKeys("looper", "0", "t"); const statusLoop = await waitForStatusContaining("LOOPING", 8000); if (!statusLoop.includes("LOOPING")) { console.log(" WARN: Did not see LOOPING in status, continuing"); } else { console.log(" PASS: Status FIFO shows LOOPING after second t"); } // Check pane for 'L' indicator const paneAfterLoop = tmuxCapturePane("looper", "0"); const paneContainsL = paneAfterLoop.includes("L"); if (!paneContainsL) { console.log(" FAIL: TUI grid does not show 'L' indicator after loop"); engine.kill(); teardownTest(); throw new Error("Grid indicator not updated for LOOPING"); } console.log(" PASS: TUI grid shows 'L' indicator"); // Wait a couple of repetitions (3 seconds) then save via FIFO to verify audio await wait(3000); // Save via FIFO writeFifoCommand("save"); await wait(3000); // Check save.wav exists and has audio const savePath = path.join(globals.PROJECT_DIR, "save.wav"); let saveOk = false; if (fs.existsSync(savePath)) { const stat = fs.statSync(savePath); if (stat.size > 44) { saveOk = true; console.log(` PASS: save.wav created (${stat.size} bytes) – loop has audio`); } } if (!saveOk) { console.log(" FAIL: save.wav not created or too small – loop not producing audio"); engine.kill(); teardownTest(); throw new Error("Loop playback not producing audio"); } engine.kill(); teardownTest(); }