tiny-computer-agent / tests /test_act.py
hkblockchaintechnology's picture
Publish tests/ from marimo
8b9b8c8 verified
Raw History Blame Contribute Delete
2.52 kB
import pytest
from tiny_computer_agent import (
Action, DryRunExecutor, Element, InputUnavailable, Observation,
PyAutoGuiExecutor, resolve_point,
)
FRAME = Observation(elements=(Element("Save", x=320, y=120, width=80, height=24),))
def test_resolve_point_uses_pixels_when_given():
assert resolve_point(Action("click", x=1, y=2), FRAME) == (1, 2)
def test_resolve_point_uses_the_element_index_for_labels():
assert resolve_point(Action("click", label="Save"), FRAME) == (360, 132)
def test_resolve_point_is_none_for_unmatched_labels_and_other_verbs():
assert resolve_point(Action("click", label="Quit"), FRAME) is None
assert resolve_point(Action("type", text="hi"), FRAME) is None
def test_dry_run_records_instead_of_acting():
executor = DryRunExecutor()
result = executor.execute(Action("click", label="Save"), FRAME)
assert result.ok
assert "(dry-run)" in result.note
assert "(360, 132)" in result.note
assert len(executor.performed) == 1
def test_dry_run_fails_where_live_input_would_refuse():
"""A dry run must never give false confidence about a doomed click."""
dry = DryRunExecutor().execute(Action("click", label="Quit"), FRAME)
live = PyAutoGuiExecutor().execute(Action("click", label="Quit"), FRAME)
assert dry.ok is False and live.ok is False
assert "absent from the element index" in dry.note
def test_live_executor_refuses_to_guess_pixels():
"""The dangerous path: a label with no element behind it must never click."""
result = PyAutoGuiExecutor().execute(Action("click", label="Quit"), FRAME)
assert result.ok is False
assert "refusing to guess pixels" in result.note
def test_live_executor_treats_done_as_a_no_op():
result = PyAutoGuiExecutor().execute(Action("done", reason="finished"))
assert result.ok and "goal reported met" in result.note
def test_live_executor_needs_pyautogui_installed():
"""Real input on a machine that cannot run pyautogui fails loudly, not silently.
pyautogui installed is not the same as pyautogui usable: with no display it
raises KeyError('DISPLAY') on import, so this must catch Exception rather than
ImportError or the failure escapes as a traceback instead of InputUnavailable.
"""
try:
import pyautogui # noqa: F401
except Exception:
with pytest.raises(InputUnavailable, match="pyautogui"):
PyAutoGuiExecutor().execute(Action("type", text="hello"))
else:
pytest.skip("pyautogui is usable here")