124 lines
3.2 KiB
Python
124 lines
3.2 KiB
Python
from __future__ import annotations
|
|
|
|
import sys
|
|
from pathlib import Path
|
|
from unittest.mock import MagicMock
|
|
|
|
ROOT = Path(__file__).parent.parent.parent
|
|
sys.path.insert(0, str(ROOT))
|
|
|
|
from agent_v0.agent_v1.core.grounding import GroundingEngine # noqa: E402
|
|
|
|
|
|
def test_template_strategy_passes_fallback_coords_to_anchor_drift_guard():
|
|
executor = MagicMock()
|
|
executor._template_match_anchor = MagicMock(
|
|
return_value={
|
|
"resolved": True,
|
|
"x_pct": 0.7,
|
|
"y_pct": 0.35,
|
|
"score": 0.95,
|
|
}
|
|
)
|
|
|
|
engine = GroundingEngine(executor)
|
|
target_spec = {"anchor_image_base64": "abc123"}
|
|
|
|
result = engine._try_strategy(
|
|
"template",
|
|
server_url="",
|
|
screenshot_b64="shot",
|
|
target_spec=target_spec,
|
|
fallback_x=0.708594,
|
|
fallback_y=0.35,
|
|
screen_width=2560,
|
|
screen_height=1600,
|
|
)
|
|
|
|
assert result.found is True
|
|
executor._template_match_anchor.assert_called_once_with(
|
|
"shot",
|
|
"abc123",
|
|
2560,
|
|
1600,
|
|
fallback_x_pct=0.708594,
|
|
fallback_y_pct=0.35,
|
|
)
|
|
|
|
|
|
def test_server_explicit_reject_skips_local_text_fallback():
|
|
executor = MagicMock()
|
|
executor._server_resolve_target = MagicMock(
|
|
return_value={
|
|
"resolved": False,
|
|
"method": "rejected_close_tab_zone_hybrid_text_direct",
|
|
"reason": "close_tab_out_of_recorded_zone",
|
|
"score": 0.8,
|
|
}
|
|
)
|
|
executor._hybrid_vlm_resolve = MagicMock(
|
|
return_value={
|
|
"resolved": True,
|
|
"x_pct": 0.1,
|
|
"y_pct": 0.13,
|
|
"method": "hybrid_text_direct",
|
|
"score": 0.9,
|
|
}
|
|
)
|
|
|
|
engine = GroundingEngine(executor)
|
|
engine._capture_window_or_screen = MagicMock(return_value="shot")
|
|
|
|
result = engine.locate(
|
|
"http://server",
|
|
{
|
|
"by_text": "test",
|
|
"context_hints": {"interaction": "close_tab"},
|
|
"screen_scope": "full_screen",
|
|
},
|
|
fallback_x=0.7,
|
|
fallback_y=0.04,
|
|
screen_width=2560,
|
|
screen_height=1600,
|
|
)
|
|
|
|
assert result.found is False
|
|
executor._hybrid_vlm_resolve.assert_not_called()
|
|
|
|
|
|
def test_server_plain_not_found_allows_local_text_fallback():
|
|
executor = MagicMock()
|
|
executor._server_resolve_target = MagicMock(
|
|
return_value={
|
|
"resolved": False,
|
|
"method": "server_no_match",
|
|
"reason": "not_found",
|
|
"score": 0.0,
|
|
}
|
|
)
|
|
executor._hybrid_vlm_resolve = MagicMock(
|
|
return_value={
|
|
"resolved": True,
|
|
"x_pct": 0.45,
|
|
"y_pct": 0.5,
|
|
"method": "hybrid_text_direct",
|
|
"score": 0.9,
|
|
}
|
|
)
|
|
|
|
engine = GroundingEngine(executor)
|
|
engine._capture_window_or_screen = MagicMock(return_value="shot")
|
|
|
|
result = engine.locate(
|
|
"http://server",
|
|
{"by_text": "Enregistrer", "screen_scope": "full_screen"},
|
|
fallback_x=0.5,
|
|
fallback_y=0.5,
|
|
screen_width=1920,
|
|
screen_height=1080,
|
|
)
|
|
|
|
assert result.found is True
|
|
assert result.method == "hybrid_text_direct"
|
|
executor._hybrid_vlm_resolve.assert_called_once()
|