How to find and click on a hidden button with selenium?

10,477

I tried with two different approaches

driver = webdriver.Firefox()
print driver
driver.implicitly_wait(20)
driver.get("https://www.swisscom.ch/de/privatkunden/mobile/devices.html")

Directly finding elements with class_name = 'primary-button'

hrefs = driver.find_elements_by_class_name('primary-button')
print hrefs
print(len(hrefs))

Result:

[<selenium.webdriver.remote.webelement.WebElement object at 0xe390d0>, <selenium.webdriver.remote.webelement.WebElement object at 0xe39290>, <selenium.webdriver.remote.webelement.WebElement object at 0xe39250>, <selenium.webdriver.remote.webelement.WebElement object at 0xe391d0>, <selenium.webdriver.remote.webelement.WebElement object at 0xe394d0>, <selenium.webdriver.remote.webelement.WebElement object at 0xe4ed10>, <selenium.webdriver.remote.webelement.WebElement object at 0xe4ecd0>, <selenium.webdriver.remote.webelement.WebElement object at 0xe4ec50>, <selenium.webdriver.remote.webelement.WebElement object at 0xe4ec10>, <selenium.webdriver.remote.webelement.WebElement object at 0xe4ec90>]
10

On div element find all buttons using xpath

element = driver.find_element_by_xpath("//div[@id='gridProduct10247118']")
hrefs = element.find_elements_by_xpath("//a[@class='primary-button']")
print hrefs
print len(hrefs)

Result:

[<selenium.webdriver.remote.webelement.WebElement object at 0xe4ee10>, <selenium.webdriver.remote.webelement.WebElement object at 0xe4ee50>, <selenium.webdriver.remote.webelement.WebElement object at 0xe4ee90>, <selenium.webdriver.remote.webelement.WebElement object at 0xe4eed0>, <selenium.webdriver.remote.webelement.WebElement object at 0xe4ef10>, <selenium.webdriver.remote.webelement.WebElement object at 0xe4ef50>, <selenium.webdriver.remote.webelement.WebElement object at 0xe4ef90>, <selenium.webdriver.remote.webelement.WebElement object at 0xe4efd0>, <selenium.webdriver.remote.webelement.WebElement object at 0xe58050>]
9

And your approach:

element = driver.find_element_by_xpath("//div[@id='gridProduct10247118']")
hrefs = element.find_elements_by_class_name('primary-button')
print hrefs
print len(hrefs)

Result:

[]
0

On the other hand finding elements by xpath can be relative to other elements . From the docs:

You can use XPath to either locate the element in absolute terms (not advised), or relative to an element that does have an id or name attribute.

So the second approach gives you list of required elements

Update:

The real problem is that the target element is not visible until you hover on the parent div.

from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions

from selenium.webdriver.common.action_chains import ActionChains

driver = webdriver.Firefox()
driver.get("https://www.swisscom.ch/de/privatkunden/mobile/devices.html")

div_element = WebDriverWait(driver, 60).until(expected_conditions.presence_of_element_located((By.ID, 'gridProduct10247118')))
hover = ActionChains(driver).move_to_element(div_element)
hover.perform()

button = WebDriverWait(driver, 30).until(expected_conditions.presence_of_element_located((By.XPATH, "//div[@id='gridProduct10247118']//a[@class='primary-button']")))
hover = ActionChains(driver).move_to_element(button)
hover.perform()

button.click()
Share:
10,477
Alex
Author by

Alex

Updated on June 13, 2022

Comments

  • Alex
    Alex 3 months

    I am trying to use a selenium python script to try to click on a button which is only visible when the mouse hovers over a certain region of the webpage. The code I use so far is as follows:

    driver = webdriver.Firefox()
    driver.implicitly_wait(20)
    driver.get("https://www.swisscom.ch/de/privatkunden/mobile/devices.html")
    element = driver.find_element_by_xpath("//div[@id='gridProduct10247118']")
    hrefs = element.find_elements_by_class_name('primary-button')
    print(len(hrefs))
    

    which seems to work, but returns 0 entries in hrefs. But in the inspector of firefox I clearly can see this element within the element of the given id:

    enter image description here

    What am I doing wrong? How to find that button element and be able to click it?

    P.S. I am not able to use the record ability of selenium (see here) because the button becomes only visible when the mouse is hovered above a certain element, as shown here:

    enter image description here

    Addendum:

    Given the 'help' I change a line in the script to:

    hrefs = element.hover().find_elements_by_class_name('primary-button').click()
    

    which gives an error:

    AttributeError: 'WebElement' object has no attribute 'hover'
    

    Addendum on the help by Andersson: I change part of the code as follows:

    element = driver.find_element_by_xpath("//div[@id='gridProduct10247118']")
    hover = ActionChains(driver).move_to_element(element)
    hover.perform()
    hrefs = hover.find_elements_by_xpath("//a[@class='primary-button']")
    

    but got an error

    AttributeError: 'ActionChains' object has no attribute 'find_elements_by_xpath'
    

    If I use the following line of code instead:

    hrefs = element.find_elements_by_xpath("//a[@class='primary-button']")
    

    I get 9 elements, although I expecte only one single "Bestellen"-button element (see images in the question).