Search code examples
pythonseleniumhidden

Click Hidden Link Using Selenium in Python


I am using Selenium in Python to try to click a link within a drop down menu that appears when the mouse hovers over that drop down menu. Here is the drop down menu info:

<div id="DownloadMenu">
    <ul id="DownloadMenu_control" class="topmenu" widgetid="DownloadMenu_control">
    <li class="horizontal-list-item-2 leftFloatedItem" id="DownloadMenu_control@BatchPrintSaveMenu_1" widgetid="DownloadMenu_control@BatchPrintSaveMenu_1" style="">
    <a class="horizontal-list-item-2 leftFloatedItem" href="javascript:void(0)">Download</a>
    <ul id="common_navigation_MenuControl_6" class="submenu" style="display: none; left: 0px; visibility: hidden;" widgetid="common_navigation_MenuControl_6">
    <li class="subitems" id="DownloadMenu_control@DownloadSelectedDocumentsMenuItem" widgetid="DownloadMenu_control@DownloadSelectedDocumentsMenuItem">
    <a href="javascript:com.reuters.rts.event(event, 'openMultiDocInfoViewerBatchViewEikon', 'itemsCollectionId', 'AllDocumentListView_items', 'researchTableManagerId', 'AllDocumentListView', 'summary', escape(encodeURIComponent(dijit.byId('advancedSearchManager').getFilterSubmittedSummary())), 'fileSizeLimitForMerging', '25','forBatchPrint','true', 'action','Save');">Documents</a>
    </li>
    </ul>
    </li>
    </ul>
</div>

I am trying to click on the "Documents" link in the "a href" tag. When I hover over the menu, the code changes as follows:

<div id="DownloadMenu">
    <ul id="DownloadMenu_control" class="topmenu" widgetid="DownloadMenu_control">
    <li class="topitemOn" id="DownloadMenu_control@BatchPrintSaveMenu_1" widgetid="DownloadMenu_control@BatchPrintSaveMenu_1" style="">
    <a class="horizontal-list-item-2 leftFloatedItem" href="javascript:void(0)">Download</a>
    <ul id="common_navigation_MenuControl_6" class="submenu" style="display: none; left: 0px;" widgetid="common_navigation_MenuControl_6">
    <li class="subitems" id="DownloadMenu_control@DownloadSelectedDocumentsMenuItem" widgetid="DownloadMenu_control@DownloadSelectedDocumentsMenuItem">
    <a href="javascript:com.reuters.rts.event(event, 'openMultiDocInfoViewerBatchViewEikon', 'itemsCollectionId', 'AllDocumentListView_items', 'researchTableManagerId', 'AllDocumentListView', 'summary', escape(encodeURIComponent(dijit.byId('advancedSearchManager').getFilterSubmittedSummary())), 'fileSizeLimitForMerging', '25','forBatchPrint','true', 'action','Save');">Documents</a>
    </li>
    </ul>
    </li>
    </ul>
</div>

You can see that the visibility:hidden part goes away in the second ul tag.

I have found the elements on the page using the following code:

download_menu = driver.find_element_by_id("DownloadMenu")
download_button = download_menu.find_elements_by_tag_name('a')[1]

If I try to click the download button using:

download_button.click()

I get an error that the element is not visible:

ElementNotVisibleException: Message: element not visible

So I tried,

ActionChains(driver).move_to_element(download_menu).move_to_element(download_button).click(download_button).perform()

When I do this, nothing happens. So, I tried executing the script to make the menu visible and then clicking and that didn't work either:

visibility_tag = download_menu.find_elements_by_tag_name('ul')[1]
driver.execute_script("arguments[0].style.display = 'block'; arguments[0].style.left = '0px'; arguments[0].style.visibility = ''", visibility_tag)

When I run the execute_script function, the menu DOES become visible on my browser. It just still can't be clicked. I'm going crazy here. Any ideas? I'm using the Chrome extension of Selenium in Python.


Solution

  • You should try using ExplicitWaits to wait until Documents link visible and enable to click as below :-

    from selenium import webdriver
    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.action_chains import ActionChains
    
    wait = WebDriverWait(driver, 10)
    
    download_menu = driver.find_element_by_id("DownloadMenu")
    
    action = ActionChains(driver)
    #hover on download_menu first
    action.move_to_element(download_menu).perform()
    
    #now find Documents link and click
    documents = wait.until(EC.element_to_be_clickable((By.LINK_TEXT, "Documents")))
    documents.click()