import pytest from unittest.mock import patch, MagicMock from cursor_flasher.detector import ( CursorDetector, PollResult, parse_ui_signals, UISignals, ) class TestParseUISignals: def test_no_elements_means_no_signals(self): signals = parse_ui_signals([]) assert signals.agent_working is False assert signals.approval_needed is False def test_stop_text_means_agent_working(self): elements = [{"role": "AXStaticText", "value": "Stop"}] signals = parse_ui_signals(elements) assert signals.agent_working is True def test_cancel_generating_means_agent_working(self): elements = [{"role": "AXStaticText", "value": "Cancel generating"}] signals = parse_ui_signals(elements) assert signals.agent_working is True def test_accept_text_means_approval_needed(self): elements = [{"role": "AXStaticText", "value": "Accept"}] signals = parse_ui_signals(elements) assert signals.approval_needed is True def test_reject_text_means_approval_needed(self): elements = [{"role": "AXStaticText", "value": "Reject"}] signals = parse_ui_signals(elements) assert signals.approval_needed is True def test_run_this_time_means_approval_needed(self): elements = [{"role": "AXStaticText", "value": "Run this time only (⏎)"}] signals = parse_ui_signals(elements) assert signals.approval_needed is True def test_both_signals(self): elements = [ {"role": "AXStaticText", "value": "Stop"}, {"role": "AXStaticText", "value": "Accept"}, ] signals = parse_ui_signals(elements) assert signals.agent_working is True assert signals.approval_needed is True def test_irrelevant_text_ignored(self): elements = [{"role": "AXStaticText", "value": "Settings"}] signals = parse_ui_signals(elements) assert signals.agent_working is False assert signals.approval_needed is False def test_button_role_also_detected(self): elements = [{"role": "AXButton", "title": "Accept"}] signals = parse_ui_signals(elements) assert signals.approval_needed is True def test_partial_match_on_run_command(self): elements = [{"role": "AXStaticText", "value": "Run command"}] signals = parse_ui_signals(elements) assert signals.approval_needed is True class TestCursorDetector: def test_returns_none_when_cursor_not_running(self): detector = CursorDetector() with patch.object(detector, "_find_cursor_pid", return_value=None): result = detector.poll() assert result is None class TestPollResult: def test_default_has_empty_active_windows(self): result = PollResult(signals=UISignals()) assert result.active_windows == [] assert result.signals.agent_working is False assert result.signals.approval_needed is False