From 559cac35a31c520b4067f11a1d55268b21023ed8 Mon Sep 17 00:00:00 2001 From: abrichr Date: Tue, 28 Jul 2026 02:09:51 -0400 Subject: [PATCH] fix: refuse launcher capture before readiness --- openadapt/cli.py | 5 ++++- tests/test_cli_smoke.py | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/openadapt/cli.py b/openadapt/cli.py index 74ccb761d..19b55aab3 100644 --- a/openadapt/cli.py +++ b/openadapt/cli.py @@ -442,7 +442,10 @@ def capture_start(name: str, video: bool, audio: bool): capture_video=video, capture_audio=audio, ) as recorder: - recorder.wait_for_ready() + if not recorder.wait_for_ready(): + raise click.ClickException( + "Capture did not become ready. No successful capture was saved." + ) click.echo("Recording...") try: while recorder.is_recording: diff --git a/tests/test_cli_smoke.py b/tests/test_cli_smoke.py index 445ed7adf..0fe61b49e 100644 --- a/tests/test_cli_smoke.py +++ b/tests/test_cli_smoke.py @@ -255,6 +255,44 @@ def test_top_level_help_leads_with_flow(): assert flow_idx < capture_idx, "flow should be listed before capture" +def test_capture_start_refuses_when_recorder_never_becomes_ready(monkeypatch): + """The compatibility command must not label failed startup as saved.""" + from types import SimpleNamespace + + state = {} + + class NeverReadyRecorder: + def __init__(self, *args, **kwargs): + pass + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc, traceback): + state["exited"] = True + return False + + def wait_for_ready(self): + return False + + monkeypatch.setitem( + sys.modules, + "openadapt_capture", + SimpleNamespace(Recorder=NeverReadyRecorder), + ) + + result = CliRunner().invoke( + cli_main, + ["capture", "start", "--name", "failed-capture", "--no-video"], + ) + + assert result.exit_code != 0 + assert state == {"exited": True} + assert "did not become ready" in result.output + assert "Recording..." not in result.output + assert "Capture saved" not in result.output + + def test_flow_help_lists_verbs(): """`openadapt flow --help` lists every mounted verb (no flow install needed — click renders help before importing openadapt-flow)."""