from unittest.mock import patch, MagicMock from merlin.actions.executor import ActionExecutor @patch("merlin.actions.executor.subprocess") def test_left_click_calls_xdotool(mock_sub): ex = ActionExecutor(backend="xdotool") ex.execute("left_click") mock_sub.run.assert_called_once_with(["xdotool", "click", "1"], capture_output=True) @patch("merlin.actions.executor.subprocess") def test_right_click_calls_xdotool(mock_sub): ex = ActionExecutor(backend="xdotool") ex.execute("right_click") mock_sub.run.assert_called_once_with(["xdotool", "click", "3"], capture_output=True) @patch("merlin.actions.executor.subprocess") def test_double_click_calls_xdotool(mock_sub): ex = ActionExecutor(backend="xdotool") ex.execute("double_click") mock_sub.run.assert_called_once_with( ["xdotool", "click", "--repeat", "2", "1"], capture_output=True ) @patch("merlin.actions.executor.subprocess") def test_key_enter(mock_sub): ex = ActionExecutor(backend="xdotool") ex.execute("key_enter") mock_sub.run.assert_called_once_with( ["xdotool", "key", "Return"], capture_output=True ) @patch("merlin.actions.executor.subprocess") def test_unknown_action_does_not_raise(mock_sub): ex = ActionExecutor(backend="xdotool") ex.execute("nonexistent_action") mock_sub.run.assert_not_called() @patch("merlin.actions.executor.pyautogui") def test_pyautogui_fallback_left_click(mock_pag): ex = ActionExecutor(backend="pyautogui") ex.execute("left_click") mock_pag.click.assert_called_once()