From 6571604fa5a8187a8ce3adeac0cc2c8eea5d0d50 Mon Sep 17 00:00:00 2001 From: Kerem Yilmaz Date: Fri, 13 Sep 2024 17:57:36 -0700 Subject: [PATCH] support revival selection (#829) --- skyvern/webeye/actions/handler.py | 1 + skyvern/webeye/scraper/domUtils.js | 37 ++++++++++++++++++++++++++++-- 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/skyvern/webeye/actions/handler.py b/skyvern/webeye/actions/handler.py index 1b5c2c24..7eafeada 100644 --- a/skyvern/webeye/actions/handler.py +++ b/skyvern/webeye/actions/handler.py @@ -451,6 +451,7 @@ async def handle_input_text_action( element_id=skyvern_element.get_id(), action=action, ) + await incremental_scraped.stop_listen_dom_increment() else: try: # TODO: we don't select by value for the auto completion detect case diff --git a/skyvern/webeye/scraper/domUtils.js b/skyvern/webeye/scraper/domUtils.js index 7f37940d..9a70bffb 100644 --- a/skyvern/webeye/scraper/domUtils.js +++ b/skyvern/webeye/scraper/domUtils.js @@ -219,9 +219,11 @@ function isElementVisible(element) { ) return element.parentElement && isElementVisible(element.parentElement); + const className = element.className.toString(); if ( - element.className.toString().includes("select2-offscreen") || - element.className.toString().includes("select2-hidden") + className.includes("select2-offscreen") || + className.includes("select2-hidden") || + className.includes("ui-select-offscreen") ) { return false; } @@ -545,6 +547,36 @@ const isReactSelectDropdown = (element) => { ); }; +function hasNgAttribute(element) { + for (let attr of element.attributes) { + if (attr.name.startsWith("ng-")) { + return true; + } + } + return false; +} + +const isAngularDropdown = (element) => { + if (!hasNgAttribute(element)) { + return false; + } + + const tagName = element.tagName.toLowerCase(); + // TODO: some angular might use to trigger dropdown menu + // if (tagName === "span") { + // ... + // } + + if (tagName === "input") { + const ariaLabel = element.hasAttribute("aria-label") + ? element.getAttribute("aria-label").toLowerCase() + : ""; + return ariaLabel.includes("select") || ariaLabel.includes("choose"); + } + + return false; +}; + const checkParentClass = (className) => { const targetParentClasses = ["field", "entry"]; for (let i = 0; i < targetParentClasses.length; i++) { @@ -953,6 +985,7 @@ function buildElementObject(frame, element, interactable, purgeable = false) { isSelectable: elementTagNameLower === "select" || isDropdownButton(element) || + isAngularDropdown(element) || isSelect2Dropdown(element) || isSelect2MultiChoice(element), };