Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fallback to use js click #1274

Merged
merged 1 commit into from
Nov 27, 2024
Merged
Show file tree
Hide file tree
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
22 changes: 19 additions & 3 deletions skyvern/webeye/actions/handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -1262,18 +1262,34 @@ async def fc_func(fc: FileChooser) -> None:
)
return action_results

blocking_element = await skyvern_element.find_blocking_element(
blocking_element, blocked = await skyvern_element.find_blocking_element(
dom=DomUtil(scraped_page=scraped_page, page=page)
)
if blocking_element is None:
if not blocked:
LOG.info(
"Chain click: exit since the element is not blocking by any element",
task_id=task.task_id,
action=action,
element=str(skyvern_element),
locator=locator,
)
return action_results

LOG.info(
"Chain click: exit since the element is not blocking by any skyvern element",
"Chain click: element is blocked by an non-interactable element, going to use javascript click instead of playwright click",
task_id=task.task_id,
action=action,
element=str(skyvern_element),
locator=locator,
)
return action_results
try:
await skyvern_element.click_in_javascript()
action_results.append(ActionSuccess())
return action_results
except Exception as e:
action_results.append(ActionFailure(FailToClick(action.element_id, anchor="self_js", msg=str(e))))
return action_results

try:
LOG.debug(
Expand Down
4 changes: 2 additions & 2 deletions skyvern/webeye/scraper/domUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -427,10 +427,10 @@ function getBlockElementUniqueID(element) {
);

if (!hitElement) {
return "";
return ["", false];
}

return hitElement.getAttribute("unique_id") ?? "";
return [hitElement.getAttribute("unique_id") ?? "", true];
}

function isHidden(element) {
Expand Down
12 changes: 8 additions & 4 deletions skyvern/webeye/utils/dom.py
Original file line number Diff line number Diff line change
Expand Up @@ -320,12 +320,12 @@ async def get_element_handler(
assert handler is not None
return handler

async def find_blocking_element(self, dom: DomUtil) -> SkyvernElement | None:
async def find_blocking_element(self, dom: DomUtil) -> tuple[SkyvernElement | None, bool]:
skyvern_frame = await SkyvernFrame.create_instance(self.get_frame())
blocking_element_id = await skyvern_frame.get_blocking_element_id(await self.get_element_handler())
blocking_element_id, blocked = await skyvern_frame.get_blocking_element_id(await self.get_element_handler())
if not blocking_element_id:
return None
return await dom.get_skyvern_element_by_id(blocking_element_id)
return None, blocked
return await dom.get_skyvern_element_by_id(blocking_element_id), blocked

async def find_element_in_label_children(
self, dom: DomUtil, element_type: InteractiveElement
Expand Down Expand Up @@ -576,6 +576,10 @@ async def move_mouse_to(

return dest_x, dest_y

async def click_in_javascript(self) -> None:
skyvern_frame = await SkyvernFrame.create_instance(self.get_frame())
await skyvern_frame.click_element_in_javascript(await self.get_element_handler())

async def coordinate_click(
self, page: Page, timeout: float = SettingsManager.get_settings().BROWSER_ACTION_TIMEOUT_MS
) -> None:
Expand Down
6 changes: 5 additions & 1 deletion skyvern/webeye/utils/page.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ async def get_disabled_from_style(self, element: ElementHandle) -> bool:
js_script = "(element) => checkDisabledFromStyle(element)"
return await self.evaluate(frame=self.frame, expression=js_script, arg=element)

async def get_blocking_element_id(self, element: ElementHandle) -> str:
async def get_blocking_element_id(self, element: ElementHandle) -> tuple[str, bool]:
js_script = "(element) => getBlockElementUniqueID(element)"
return await self.evaluate(frame=self.frame, expression=js_script, arg=element)

Expand Down Expand Up @@ -239,3 +239,7 @@ async def is_sibling(self, el1: ElementHandle, el2: ElementHandle) -> bool:
async def has_ASP_client_control(self) -> bool:
js_script = "() => hasASPClientControl()"
return await self.evaluate(frame=self.frame, expression=js_script)

async def click_element_in_javascript(self, element: ElementHandle) -> None:
js_script = "(element) => element.click()"
return await self.evaluate(frame=self.frame, expression=js_script, arg=element)