Search code examples
pythonseleniumxpathwebdriverwaitfindelement

Unable to locate and click on li element within ul list


I'm trying to click on an li element in a ul dropdown list. I want to select "Last Month" but get this error: Message: no such element: Unable to locate element

Here's my code:

def click_on(xpath):
    timeout = time.time() + 30
    while True:
        try:
            driver.find_element(By.XPATH, xpath).click()
            break
        except Exception:
            if time.time() > timeout:
                msgbox('Process timed out after 30 seconds.', 'Error')
                exit()

click_on('//*[@id="popover_otrppv916b"]/div/div[2]/div[1]/div/div/div/div/ul/li[9]/div/span')

Here's the html:

html

I've also tried clicking on just the <div> tag, and just the <li> tag (instead of the <span> tag) and I get the same error.


Solution

  • The id attribute values like popover_otrppv916b are dynamically generated and is bound to change sooner/later. They may change next time you access the application afresh or even while next application startup. So can't be used in locators.


    Solution

    To click on the clickable element with text as Last month you need to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following locator strategies:

    • Using XPATH and normalizespace():

      WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//ul[@class='group-list']//li//span[normalizespace()='Last month']"))).click()
      
    • Using XPATH and contains():

      WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//ul[@class='group-list']//li//span[contains(., 'Last month')]"))).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