1

I am trying to click a button on a website in Python using Selenium. The html for the button I want looks like this:

<a onclick="exportGridExcel()"><span class="accordion-download"><i class="fa fa-file-excel-o" title="Download Excel" aria-hidden="true"></i></span></a>

A more expanded version of the html is:

<div class="lang-switch-wrapper lang-switch-inverse-wrapper">
                            <div class="lang-switch">
                                <ul>
    <li class="dropdown">                        
        <a href="#" class="dropdown-toggle lang-lable" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
            <span class=" hidden-xs">English</span>
            <span class="hidden-lg hidden-md hidden-sm">EN</span>
            <img src="/etc/designs/wbrrdesign/clientlibs-wbrredsign/img/angle-down-gray.svg" alt="dropdown"></a>
        <ul class="dropdown-menu dropdown-item">
            <li><a href="https://espanol.enterprisesurveys.org/es/enterprisesurveys">Español</a></li>
        </ul>
    </li>
</ul>

                            </div>
                        </div>

Then some other stuff before going to the button group and button I want:

<div class="button-group">   
        <button onclick="onModifyQuery()" type="button" class="btn">Modify Query</button>
        <a onclick="exportGridExcel()"><span class="accordion-download"><i class="fa fa-file-excel-o" title="Download Excel" aria-hidden="true"></i></span></a>
        <a title="Undo to column removal" onclick="restoreColumn()" class="toggle-btn primary-light-blue-btn"><i class="fa fa-circle-o-notch" aria-hidden="true"></i></a>
    </div>

Part of my confusion is inexperience with this html with multiple classes and "i class".

EDIT:

If I try something like:

WebDriverWait(driver,300).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "a[onclick='exportGridExcel()']"))).click()

Then I get the error:

ElementClickInterceptedException: element click intercepted: Element <a onclick="exportGridExcel()">...</a> is not clickable at point (772, 11). Other element would receive the click: <div class="lang-switch-wrapper lang-switch-inverse-wrapper">...</div>
Bob
  • 127
  • 2
  • 7
  • 1
    `i` is a text tag, so just consider it like any other tag. with the limited HTML, its hard to tell what's going on. try to observe this `aria-hidden="true"` is this get changed or set to `false` when you hover on the element or hover near `a` tag. for me even `'//i[@title="Download Excel"]'` identified the element. so need more detail to recreate it. – simpleApp Jan 30 '23 at 03:23
  • Thanks very much, thats still quite helpful! With some updated code in the edit (also works for your suggestion with "i[@title...") the issue of identifying the element seems solved. But now I have another error: "ElementClickInterceptedException: Other element would receive the click:
    ...
    ". I have edited the post to provide more html if it helps.
    – Bob Jan 30 '23 at 03:54
  • Does this [SO thread](https://stackoverflow.com/questions/48665001/can-not-click-on-a-element-elementclickinterceptedexception-in-splinter-selen) help? As no URL provided, guessing based on the exception. – Heelara Jan 30 '23 at 05:07
  • @Heelara thanks, I'll try it. Fyi, the Url is https://www.enterprisesurveys.org/en/custom-query. But the page after selecting some boxes and clicking Create Report the button I want is the download excel one next to the button Modify Query. – Bob Jan 30 '23 at 05:19
  • Did you try, JavascriptExecutor - 'click()' function. element = WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "a[onclick='exportGridExcel()']"))). driver.execute_script("arguments[0].click();", element). Make sure your locator is correct. – AbiSaran Jan 30 '23 at 07:14
  • @Bob Can you explain a bit why `
    ` obstructs the click on ``? I mean in which situation/condition?
    – undetected Selenium Jan 30 '23 at 07:53

2 Answers2

2

The problem is that your page is automatically scrolled up and the excel download button is probably hidden by the top banner that contains the language selector. When Selenium tries to click on the excel download button, it finds the language selector instead.

I would suggest you to scroll the page up till the whole data table is visible

You can use something like this. Press HOME key to go to top of the page

from selenium.webdriver.common.keys import Keys
...
...
element = WebDriverWait(driver,300).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "a[onclick='exportGridExcel()']")))
element.send_keys(Keys.CONTROL + Keys.HOME)
element.click()
Manish
  • 484
  • 3
  • 12
0

Ideally clicking on the element <a onclick="exportGridExcel()"> as per your code trials inducing WebDriverWait for the elementToBeClickable() should have worked.

However, there seems to be a decendant <span>. So you can use either of the following locator strategies:

  • Using CSS_SELECTOR:

    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "a[onclick^='exportGridExcel'] > span.accordion-download"))).click()
    
  • Using XPATH:

    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//a[starts-with(@onclick, 'exportGridExcel')]/span[@class='accordion-download']"))).click()
    
  • Note: You have to add the following imports :

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

In another approach you can also use JavascriptExecutor as follows:

  • Using CSS_SELECTOR:

    element  = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "a[onclick^='exportGridExcel'] > span.accordion-download")))
    driver.execute_script("arguments[0].click();", element) 
    
  • Using XPATH:

    element  = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//a[starts-with(@onclick, 'exportGridExcel')]/span[@class='accordion-download']")))
    driver.execute_script("arguments[0].click();", element)
    
undetected Selenium
  • 183,867
  • 41
  • 278
  • 352
  • 1
    Thank you. The first solution did not work but the javascript executor works. – Bob Jan 30 '23 at 19:05