"""Shared test helpers. The OCR guard used to live inline in two files, written two slightly different ways - and on a machine with no OCR engine one of them never fired at all. It is one function now, and `test_ocr_guard.py` proves it actually skips. """ import pytest def require_ocr() -> None: """Skip the calling test unless a real OCR engine is installed. Deliberately asks for the **ocr** detector, not the ``auto`` one: ``auto`` is available even with nothing installed, because it falls back to the numbered grid, so guarding on it silently *never* skips. """ from tiny_computer_agent.perception import detector_available available, detail = detector_available("ocr") if not available: pytest.skip(f"no OCR engine installed: {detail}") def require_atspi() -> None: """Skip the calling test unless the AT-SPI reader can actually be built. The same trap as `require_ocr`, one layer down. `make_detector("atspi")` is right to raise when PyGObject is missing - but a test that calls it on a machine without the typelib *fails* where it should skip, and the failure reads like a harness defect. Ask the backend that needs the typelib, never a name that resolves anyway. """ from tiny_computer_agent.accessibility import accessibility_available available, detail = accessibility_available("atspi") if not available: pytest.skip(f"no AT-SPI reader on this machine: {detail}")