How to select an option in a combined input and li field with Selenium?

49 Views Asked by At

I came across a field that I don't know how to iterate through its options. I need to be able to choose each element one by one so that the page loads associated information, and then retrieve that information for each option. The structure is as follows.

<div class="col-xs-10 col-xs-offset-1 mar-ver">
  <select id="filter" multiple data-placeholder="Filtrar.." name="namefilter" style="display: none;">
    <option value="limitedtest">limit test</option>
    <option value="test_2">Test 2</option>
    <option value="test_3">Test 3</option>
    ...
  </select>
  <div class="chosen-container chosen-container-multi" title id="agendafilter_chosen" style="width: 99%;">
    <ul class="chosen-choices">
      <li class="search-field">
        <input class="chosen-search-input default" type="text" autocomplete="off" value="Filtrar" style="width: 147px;">
      </li>
    </ul>
    <div class="chosen-drop">
      <ul class="chosen-results">
        <li class="active-result" data-option-array-index="0">limit test</li>
        <li class="active-result" data-option-array-index="1">Test 2</li>
        <li class="active-result" data-option-array-index="2">Test 3</li>
      </ul>
    </div>
  </div>
</div>

I tried selecting one option from the select id="filter", but it throws “select disabled error”. I also attempted to pass the value to the input, but it only displays the list and erases the sent text.

option = "Test 3"
chosen_search_input = WebDriverWait(driver, 10).until(
        EC.presence_of_element_located((By.XPATH, "/html/body/div[1]/div[2]/div[4]/div/div/div/div/div[1]/div[2]/div[1]/div[1]/div/ul/li/input"))
    )
    chosen_search_input.send_keys(option)

Any other method you can suggest? Thanks for your time.

1

There are 1 best solutions below

1
sashkins On BEST ANSWER

You are dealing with the Chosen library.
This changes the classic Select handling via native Selenium functionality.

The following code works ok for me (tested on the select from here):



wait = WebDriverWait(driver, 10)

driver.get("https://harvesthq.github.io/chosen/")
dropdown_wrapper = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "div.chosen-container-single"))).click()

options = [option.text for option in driver.find_elements(By.CSS_SELECTOR, '.chosen-results li') if option.text]
for i, option in enumerate(options):
    if i != 0:
        wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "div.chosen-container-single"))).click()

    wait.until(EC.element_to_be_clickable((By.XPATH, f'//li[text()="{option}"]'))).click()
    wait.until(EC.invisibility_of_element_located((By.CLASS_NAME, 'chosen-loading')))

    # your retrieve logic goes here
    # your retrieve logic goes here
    # your retrieve logic goes here

    print("Handled: " + option)

So you collect all the options first, and then handle them one by one by opening the dropdown and selecting the required option.