""" Advanced browser features: scroll, hover, wait, etc. """ import time import logging from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.keys import Keys from selenium.webdriver.common.action_chains import ActionChains from browser.driver import get_driver, cleanup_driver logger = logging.getLogger(__name__) def wait_for_element(url: str, selector: str, timeout: int = 10, use_persistent: bool = False) -> str: """Wait for element to appear on page""" driver = None try: driver = get_driver(url, use_persistent) wait = WebDriverWait(driver, timeout) elem = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, selector))) text = elem.text[:100] + "..." if len(elem.text) > 100 else elem.text return f"Element found: {selector}\nText preview: {text}" except Exception as e: logger.error(f"Error in wait_for_element: {e}") return f"Error: Element not found within {timeout} seconds" finally: cleanup_driver(driver, use_persistent) def scroll_page(url: str, direction: str = "bottom", pixels: int = 0, use_persistent: bool = False) -> str: """Scroll page in specified direction""" driver = None try: driver = get_driver(url, use_persistent) if direction == "bottom": driver.execute_script("window.scrollTo(0, document.body.scrollHeight);") elif direction == "top": driver.execute_script("window.scrollTo(0, 0);") elif direction == "down": driver.execute_script(f"window.scrollBy(0, {pixels or 500});") elif direction == "up": driver.execute_script(f"window.scrollBy(0, -{pixels or 500});") time.sleep(1) # Get current scroll position scroll_pos = driver.execute_script("return window.pageYOffset;") return f"Scrolled {direction}. Current position: {scroll_pos}px from top" except Exception as e: logger.error(f"Error in scroll_page: {e}") return f"Error: {e}" finally: cleanup_driver(driver, use_persistent) def hover_element(url: str, selector: str, use_persistent: bool = False) -> str: """Hover over an element""" driver = None try: driver = get_driver(url, use_persistent) wait = WebDriverWait(driver, 10) elem = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, selector))) actions = ActionChains(driver) actions.move_to_element(elem).perform() time.sleep(1) return f"Hovered over element: {selector}" except Exception as e: logger.error(f"Error in hover_element: {e}") return f"Error: {e}" finally: cleanup_driver(driver, use_persistent) def press_key(url: str, key: str, selector: str = "body", use_persistent: bool = False) -> str: """Press a keyboard key on element""" driver = None try: driver = get_driver(url, use_persistent) wait = WebDriverWait(driver, 10) elem = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, selector))) # Map common key names to Selenium keys key_map = { "enter": Keys.ENTER, "tab": Keys.TAB, "escape": Keys.ESCAPE, "backspace": Keys.BACKSPACE, "delete": Keys.DELETE, "space": Keys.SPACE, "up": Keys.ARROW_UP, "down": Keys.ARROW_DOWN, "left": Keys.ARROW_LEFT, "right": Keys.ARROW_RIGHT, "home": Keys.HOME, "end": Keys.END, "pageup": Keys.PAGE_UP, "pagedown": Keys.PAGE_DOWN, } selenium_key = key_map.get(key.lower(), key) elem.send_keys(selenium_key) return f"Pressed key '{key}' on {selector}" except Exception as e: logger.error(f"Error in press_key: {e}") return f"Error: {e}" finally: cleanup_driver(driver, use_persistent)