Search code examples
pythonselenium-webdriverxpathshadow-root

Selenium: cannot use click() on shadow root WebElement


driver.get("https://colp.maps.arcgis.com/apps/dashboards/0334150e430449cf8ac917e347897d46")
driver.implicitly_wait(15)

cyber_button_outer = driver.find_element(By.XPATH, "//span[@title='Fraud or Cyber Crimes']/ancestor::div[contains(@class, 'category-selector-widget h-full')]").find_elements(By.CLASS_NAME, "group-btn")     

for button in cyber_button_outer:
    shadow_root = driver.execute_script("return arguments[0].shadowRoot", button)
    try:
        check_button = shadow_root.find_element(By.CSS_SELECTOR, "button")
        print(check_button.text)
        if check_button.text == "Cyber Crime":
            print("1")
            check_button.click()
            
    except:
        print("false")

I would like to click on the button that was hidden inside the shadow root in this website (https://colp.maps.arcgis.com/apps/dashboards/0334150e430449cf8ac917e347897d46). I think I successfully called out the web element but I just wasn't able to click on it with click().

Thanks for any help in advance :)

screenshot for the button

screenshot for the button


Solution

  • To interact with Shadow DOM elements using Selenium in Python, you can use JavaScript to access the shadow root and perform the desired actions.

    from selenium import webdriver
    from selenium.webdriver.common.by import By
    
    # Start a new browser session
    driver = webdriver.Chrome()
    
    # Navigate to the webpage
    driver.get("https://colp.maps.arcgis.com/apps/dashboards/0334150e430449cf8ac917e347897d46")
    driver.implicitly_wait(15)
    
    # Find the outer element of the shadow root
    cyber_button_outer = driver.find_element(By.XPATH, "//span[@title='Fraud or Cyber Crimes']/ancestor::div[contains(@class, 'category-selector-widget h-full')]").find_element(By.CLASS_NAME, "group-btn")
    
    # Access the shadow root using JavaScript
    shadow_root = driver.execute_script("return arguments[0].shadowRoot", cyber_button_outer)
    
    try:
        # Find the desired button within the shadow root
        check_button = shadow_root.find_element(By.CSS_SELECTOR, "button")
        print(check_button.text)
        if check_button.text == "Cyber Crime":
            print("1")
            # Perform the click action using JavaScript
            driver.execute_script("arguments[0].click()", check_button)
    except:
        print("false")
    
    # Close the browser
    driver.quit()
    

    Interacting with Shadow DOM elements can be tricky, and it depends on the specific page structure. If possible, consider asking the developers to make elements accessible in the regular DOM to simplify automation.