user3595231
user3595231

Reputation: 767

How to click the icon in selenium python

I am trying to do logout on a web page by selenium and python, and currently no luck. In order to do a logout, I need to click the link at the upper right corner of the web page, and it will have a small drop-down window open, and then I can click the "logout" icon inside this drop-down window. Here is the picture of this drop down window. enter image description here

And the inspect code for this logout icon in the dropdown window.

enter image description here

Now in my python code, I was able to have the drop-down window open, but if I was to click the logout icon, I keep getting exception of "selenium.common.exceptions.ElementNotVisibleException".

Here is my code:

try:
    # to click the link so that the drop-down window opens 
    action = ActionChains(self.driver)
    dropdownwindow= self.driver.find_element_by_xpath("//span[@class='ssobanner_logged']/img")
    action.move_to_element(dropdownwindow).perform()
    dropdownwindow.click()

    # try to click the logout icon in the drop-down so that user may logout 
    logoutLink = self.driver.find_element_by_xpath(
        "//*[@id='ctl00_HeaderAfterLogin1_DL_Portals1']/tbody/tr/td[4]/a/img")
    action.move_to_element(logoutLink).perform()
    logoutLink.click()
    return True
except Exception as e:
    self.logger.info(e)
    raise
return False

And I have got such exceptions during the run time.

selenium.common.exceptions.NoSuchElementException: 
Message: no such element: Unable to locate element: 
 {"method":"xpath","selector":"//*[@id='ctl00_HeaderAfterLogin1_DL_Portals1']/tbody/tr/td[4]/a/img"}

Does anyone know a better way to handle that, other than the xpath I was using ?

Upvotes: 0

Views: 2995

Answers (2)

undetected Selenium
undetected Selenium

Reputation: 193098

Once the drop-down window opens up to click on the icon with text as Logout you need to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following Locator Strategies:

  • Using CSS_SELECTOR:

    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "span.portals-separator +table td>a[title='Log out'][data-mkey='Logout']>img"))).click()
    
  • Using XPATH:

    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//span[text()='Support and Settings']//following-sibling::table[1]//td/a[@title='Log out' and @data-mkey='Logout']/img"))).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
    

Upvotes: 1

Brydenr
Brydenr

Reputation: 798

The problem is most likely that the dropdown menu has not fully been expanded/rendered after it is clicked. While a time.sleep(1) command could be a potential fix, a more appropriate fix is a dynamic wait using WebDriverWait:

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

by = By.XPATH  # This could also be By.CSS_SELECTOR, By.Name, etc.
hook = "//*[@id='ctl00_HeaderAfterLogin1_DL_Portals1']/tbody/tr/td[4]/a/img"
max_time_to_wait = 10  # Maximum time to wait for the element to be present
WebDriverWait(driver, max_time_to_wait).until(expected_conditions.element_to_be_clickable((by, hook)))

expected_conditions can also wait using visibility_of_element_located or presence_of_element_located

Upvotes: 1

Related Questions