chore: archive tools/ui_inspector snapshot before migration removal.
Keep the last in-template copy on main so history can restore it; product continues in jiangchang-ui-recorder. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
50
tools/ui_inspector/locators/validator.py
Normal file
50
tools/ui_inspector/locators/validator.py
Normal file
@@ -0,0 +1,50 @@
|
||||
"""Locator uniqueness validation against snapshot / live tree rows."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any, Optional
|
||||
|
||||
from models.locator import LocatorCandidate
|
||||
|
||||
from .base import count_matches
|
||||
|
||||
|
||||
def validate_locator_against_rows(
|
||||
candidate: LocatorCandidate,
|
||||
rows: list[dict[str, Any]],
|
||||
*,
|
||||
level: str = "snapshot_only",
|
||||
expected_count: int = 1,
|
||||
) -> LocatorCandidate:
|
||||
"""
|
||||
Validate structured locator properties against a row list.
|
||||
|
||||
Levels supported in this phase: snapshot_only | live_tree
|
||||
"""
|
||||
actual = count_matches(
|
||||
rows,
|
||||
properties=candidate.properties,
|
||||
scope=candidate.scope,
|
||||
)
|
||||
candidate.mark_counts(actual, expected=expected_count)
|
||||
candidate.validation = level
|
||||
if not candidate.unique:
|
||||
candidate.reasons = list(candidate.reasons or [])
|
||||
if "ambiguous_match_count" not in candidate.reasons:
|
||||
candidate.reasons.append("ambiguous_match_count")
|
||||
candidate.production_eligible = False
|
||||
if candidate.uses_coordinates:
|
||||
candidate.production_eligible = False
|
||||
if "coordinates_never_primary" not in (candidate.reasons or []):
|
||||
candidate.reasons = list(candidate.reasons or []) + ["coordinates_never_primary"]
|
||||
return candidate
|
||||
|
||||
|
||||
def choose_production_primary(
|
||||
candidates: list[LocatorCandidate],
|
||||
) -> Optional[LocatorCandidate]:
|
||||
"""Return first production-eligible unique non-coordinate locator, else None."""
|
||||
for c in candidates:
|
||||
if c.production_eligible and c.unique and not c.uses_coordinates:
|
||||
return c
|
||||
return None
|
||||
Reference in New Issue
Block a user