| from __future__ import annotations | |
| from typing import Any | |
| from leo_ui7m.schema import UIAction | |
| class PlaywrightExecutor: | |
| """Execute LEO-UI7M UIAction objects on a Playwright sync Page.""" | |
| def __init__(self, page) -> None: | |
| self.page = page | |
| self.history: list[dict[str, Any]] = [] | |
| self.completed_ids: set[str] = set() | |
| def apply(self, action: UIAction, values: dict[str, str] | None = None) -> dict[str, Any]: | |
| values = values or {} | |
| data = action.to_dict() | |
| act = data["action"] | |
| eid = data.get("target_element_id") | |
| if act == "done": | |
| event = {"type": "done", "action": "done", "target_element_id": None} | |
| self.history.append(event) | |
| return {"ok": True, "event": event} | |
| if act == "wait": | |
| self.page.wait_for_timeout(100) | |
| event = {"type": "wait", "action": "wait", "target_element_id": None} | |
| self.history.append(event) | |
| return {"ok": True, "event": event} | |
| if not eid: | |
| return {"ok": False, "error": "missing_target_element_id", "action": data} | |
| loc = self.page.locator(f"#{eid}") | |
| if loc.count() < 1: | |
| return {"ok": False, "error": "target_not_found", "target_element_id": eid, "action": data} | |
| try: | |
| if act == "type": | |
| text = data.get("text") or values.get(eid, "") | |
| loc.fill(text) | |
| event = {"type": "type", "action": "type", "target_element_id": eid, "text": text} | |
| elif act == "select": | |
| value = data.get("value") or values.get(eid, "") | |
| loc.select_option(label=value) | |
| event = {"type": "select", "action": "select", "target_element_id": eid, "value": value} | |
| elif act == "click": | |
| if loc.get_attribute("type") == "checkbox": | |
| loc.check() | |
| else: | |
| loc.click() | |
| event = {"type": "click", "action": "click", "target_element_id": eid} | |
| else: | |
| return {"ok": False, "error": "unsupported_action", "action": data} | |
| except Exception as e: | |
| return {"ok": False, "error": type(e).__name__, "message": str(e), "action": data} | |
| self.completed_ids.add(eid) | |
| self.history.append(event) | |
| return {"ok": True, "event": event} | |