Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 27 additions & 8 deletions src/frontend_visualqa/actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,26 @@ def _is_coordinate_pair(coordinates: Any) -> bool:
return False


def _ref_result_coordinates(ref_result: dict[str, Any]) -> tuple[int, int] | None:
"""Rounded viewport coordinates from a ``GET_ELEMENT_BY_REF_SCRIPT`` result.

Returns ``None`` when the ref lookup did not succeed or the coordinates it
reported are missing/malformed, so callers can fall through to their own
fallback (raw coordinates, an error, or skipping an overlay preview).
Shared by :meth:`ActionExecutor._resolve_coordinates` and the
``set_element_value`` paste-preview path in
:meth:`ActionExecutor._execute_expanded_tool`, which previously each
hand-rolled the identical success-check / pair-validation / round-to-int
sequence over the same script's result payload.
"""
if not ref_result.get("success"):
return None
coordinates = ref_result.get("coordinates")
if not _is_coordinate_pair(coordinates):
return None
return round(float(coordinates[0])), round(float(coordinates[1]))


def render_action_trace(
action_name: str,
arguments: dict[str, Any],
Expand Down Expand Up @@ -658,12 +678,12 @@ async def _execute_expanded_tool(
if self._overlay is not None and ref:
try:
ref_info = await evaluate_tool_script(page, GET_ELEMENT_BY_REF_SCRIPT, ref)
coords = ref_info.get("coordinates") if ref_info.get("success") else None
if _is_coordinate_pair(coords):
coords = _ref_result_coordinates(ref_info)
if coords is not None:
await self._best_effort_overlay_preview_action(
action_type="set_element_value",
x=round(float(coords[0])),
y=round(float(coords[1])),
x=coords[0],
y=coords[1],
)
except Exception:
logger.debug("paste-effect preview failed for ref %s", ref, exc_info=True)
Expand Down Expand Up @@ -725,10 +745,9 @@ async def _resolve_coordinates(
result = await evaluate_tool_script(page, GET_ELEMENT_BY_REF_SCRIPT, ref)
except Exception as exc: # pragma: no cover - defensive around browser evaluate failures
result = {"success": False, "message": str(exc)}
if result.get("success"):
resolved_coordinates = result.get("coordinates")
if _is_coordinate_pair(resolved_coordinates):
return round(float(resolved_coordinates[0])), round(float(resolved_coordinates[1]))
resolved_coordinates = _ref_result_coordinates(result)
if resolved_coordinates is not None:
return resolved_coordinates
if not has_coordinates:
message = result.get("message", "Unknown error")
raise BrowserActionError(f"{action_name} ref resolution failed for {ref}: {message}")
Expand Down