3

I have a dropdown menu and I need to check its entries. If there is no entry , I can add new entries, if there is only one entry I remove it and add new entries and when I have many entries (>=2) I cannot proceed to adding entries. I can check it via person_rem_btn. If I have only one button doc_person_table:0:person_rem_btn I can proceed If I have a second button doc_person_table:1:person_rem_btn I cannot proceed.

I get this exception:

selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":"//*[@id='frmMain:doc_person_table:1:person_rem_btn']/span[1]"}

However, that's the point, this element may not be available, I just check its existence. I would appreciate any help. Here is my code:

if driver.find_element_by_xpath("//*[@id='frmMain:doc_person_table:1:person_rem_btn']/span[1]") == True:
   print ("there are already many entries")
   driver.close()
elif (driver.find_element_by_xpath("//*[@id='frmMain:doc_person_table:1:person_rem_btn']/span[1]") == False and driver.find_element_by_xpath("//*[@id='frmMain:doc_person_table:0:person_rem_btn']/span[1]") == True):
   print ("there is only one entry, it will be removed to proceed")
   WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//*[@id='frmMain:doc_person_table:0:person_rem_btn']/ span[1]"))).click()
else:
    print ("there is no entry, you can proceed")

2 Answers 2

1

find_element_by_xpath doesn't return True or False, it returns WebElement or throws NoSuchElementException. You can use find_elements_by_xpath to get a list and check if this list contains any elements. Start with waiting for an unrelated element that can indicate the page is loaded

WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.XPATH, "//*[@id^='frmMain:doc_person_table")))
# assuming this element will always appear when the page is loaded

elements = driver.find_elements_by_xpath("//*[@id='frmMain:doc_person_table:1:person_rem_btn']/span[1]")
if elements: # more verbose if len(elements) > 0
    print ("there are already many entries")
    driver.close()
else:
    elements = driver.find_elements_by_xpath("//*[@id='frmMain:doc_person_table:0:person_rem_btn']/span[1]")
    if elements:
        print ("there is only one entry, it will be removed to proceed")
        elements[0].click()
    else:
        print ("there is no entry, you can proceed")
Sign up to request clarification or add additional context in comments.

10 Comments

@jitlp It should be find_elements_by_xpath, see updated answer.
@jitlp You can add a WebDriverWait for unrelated element that you know will always be there and indicate the page was loaded. See updated answer.
@jitlp this element was just an example, you can choose any other element. It's just meant to give an indication the page is loaded. I'm not familiar with the site so I posted based on the locators from the question.
@jitlp are you referring to the elements located in elements = driver.find_elements_by_xpath("//*[@id='frmMain:doc_person_table:0:person_rem_btn']/span[1]") and elements[0].click()? or something else not related to this?
@jitlp It sounds like a new question, it will be hard answering in the comments without seeing more detailed code and html, but you should remember that moving to another page or refreshing the page (click() sometimes can cause the page to refresh) invalidates all the previously located elements and you need to relocate them.
|
0

There are several approaches you can adapt and one of the approach would be to create a List of the dropdown entries inducing WebDriverWait for the visibility_of_all_elements_located() and probe the list size:

  • Using CSS_SELECTOR:

    list = WebDriverWait(driver, 20).until(EC.visibility_of_all_elements_located((By.CSS_SELECTOR, "[id*='doc_person_table'][id$='person_rem_btn']>span")))
    if not list:
        print ("there is no entry, you can proceed")
        # other steps
    elif len(list) == 1
        print ("there is only one entry, it will be removed to proceed")
        # other steps
    else:
        print ("there are already many entries")
        break
    
  • Using XPATH:

    list = WebDriverWait(driver, 20).until(EC.visibility_of_all_elements_located((By.XPATH, "//*[contains(@id, 'doc_person_table') and contains(@id, 'person_rem_btn')]/span")))
    if not list:
        print ("there is no entry, you can proceed")
        # other steps
    elif len(list) == 1
        print ("there is only one entry, it will be removed to proceed")
        # other steps
    else:
        print ("there are already many entries")
        break
    

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.