From f429d6d51ea5dd3da4f1ec95ae0905574d148527 Mon Sep 17 00:00:00 2001 From: LawyZheng Date: Wed, 11 Sep 2024 11:53:47 +0800 Subject: [PATCH] fix spinbutton issue (#806) --- skyvern/webeye/actions/handler.py | 20 +++++++++++--------- skyvern/webeye/utils/dom.py | 16 ++++++++++++++++ 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/skyvern/webeye/actions/handler.py b/skyvern/webeye/actions/handler.py index a632a79f..5467cc7c 100644 --- a/skyvern/webeye/actions/handler.py +++ b/skyvern/webeye/actions/handler.py @@ -414,7 +414,7 @@ async def handle_input_text_action( incremental_element: list[dict] = [] # check if it's selectable - if skyvern_element.get_tag_name() == InteractiveElement.INPUT: + if skyvern_element.get_tag_name() == InteractiveElement.INPUT and not await skyvern_element.is_spinbtn_input(): await skyvern_element.scroll_into_view() select_action = SelectOptionAction( reasoning=action.reasoning, element_id=skyvern_element.get_id(), option=SelectOption(label=text) @@ -483,14 +483,16 @@ async def handle_input_text_action( # force to move focus back to the element await skyvern_element.get_locator().focus(timeout=timeout) - try: - await skyvern_element.input_clear() - except TimeoutError: - LOG.info("None input tag clear timeout", action=action) - return [ActionFailure(InvalidElementForTextInput(element_id=action.element_id, tag_name=tag_name))] - except Exception: - LOG.warning("Failed to clear the input field", action=action, exc_info=True) - return [ActionFailure(InvalidElementForTextInput(element_id=action.element_id, tag_name=tag_name))] + # `Locator.clear()` on a spin button could cause the cursor moving away, and never be back + if not await skyvern_element.is_spinbtn_input(): + try: + await skyvern_element.input_clear() + except TimeoutError: + LOG.info("None input tag clear timeout", action=action) + return [ActionFailure(InvalidElementForTextInput(element_id=action.element_id, tag_name=tag_name))] + except Exception: + LOG.warning("Failed to clear the input field", action=action, exc_info=True) + return [ActionFailure(InvalidElementForTextInput(element_id=action.element_id, tag_name=tag_name))] try: # TODO: not sure if this case will trigger auto-completion diff --git a/skyvern/webeye/utils/dom.py b/skyvern/webeye/utils/dom.py index d1e33827..c1fa3e76 100644 --- a/skyvern/webeye/utils/dom.py +++ b/skyvern/webeye/utils/dom.py @@ -197,6 +197,22 @@ class SkyvernElement: button_type = await self.get_attr("type") return button_type == "radio" + async def is_spinbtn_input(self) -> bool: + """ + confirm the element is: + 1. element + 2. role=spinbutton + + Usage of , https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/spinbutton_role + """ + if self.get_tag_name() != InteractiveElement.INPUT: + return False + + if await self.get_attr("role") == "spinbutton": + return True + + return False + def is_interactable(self) -> bool: return self.__static_element.get("interactable", False)