Henry Gunawan
Henry Gunawan

Reputation: 25

selenium python dynamic dropdown menu

I want to fill form from a website automatically, everything goes well until I need to choose an option from dynamic dropdown menu.

<div id="field_type_group" class="field trigger-option group0" style="">
  <div class="label"><label>Input Type</label></div>
  <div class="input">
    <select>
      <option data-item-id="100" value="text_field_validation_type">Text input</option>
      <option data-item-id="200" value="dropdown_field_type">Dropdown list</option>
      <option data-item-id="300" value="location_field_type">Location based input</option>
    </select>
  </div>
</div>

<div id="text_field_validation_type" class="field trigger-option group100" style="display: none;">
  <div class="label"><label>Input validation</label></div>
  <div class="input">
    <select>
      <option data-item-id="0" data-displayfield="text_raw" value="none">No validation required</option>
      <option data-item-id="500" value="text_field_type">Validation required</option>
    </select>
  </div>
</div>

<div id="dropdown_field_type" class="field trigger-option group200" style="">
  <div class="label"><label>Data source for dropdown list</label></div>
  <div class="input">
    <select>
      <option data-item-id="6" data-displayfield="dropdown_static" value="none">Populate with list items specified here</option>
      <option data-item-id="7" data-displayfield="dropdown_dynamic" value="none">Retrieve list items from my service</option>
    </select>
  </div>
</div>

The dropdown menu are like this and I can successfully choose it for the first menu after trying many ways using this code.

wait.until(ec.visibility_of_element_located((By.XPATH, "//select[option[@value='text_field_validation_type']]"))).click()
browser.find_element_by_xpath(".//option[text()[contains(.,'Dropdown list')]]").click()

But the problems appear when I need to select the sub menu.

I have tried many ways (also try using Select and ActionChains) and nothing works.

My code using Select:

select_element = browser.find_element_by_xpath("//select[option[@value='text_field_validation_type']]")
select = Select(select_element)
select.select_by_index(1)

select_element = browser.find_element_by_xpath("//select[option[@data-item-id='6']]")
select = Select(select_element)
select.select_by_index(1)

My other code:

wait.until(ec.visibility_of_element_located((By.XPATH, "//select[option[@data-item-id ='6']]"))).click()
browser.find_element_by_xpath(".//option[@data-displayfield='dropdown_dynamic']").click()

I try many ways with changing the xpath value but nothing works and my environment doesnt support ActionChains.

EDIT:

I found out that I need to click the dropdown first, then I can use the select function, but it still only work on first menu. This is the code.

wait.until(ec.visibility_of_element_located((By.XPATH, "//select[option[@value='text_field_validation_type']]"))).click()
sleep(2)
select_element = browser.find_element_by_xpath("//select[option[@value='dropdown_field_type']]")
select = Select(select_element)
#select.select_by_index(1)
select.select_by_visible_text('Dropdown list')

I also notice that on the dynamic dropdown submenu, they use another div with style="display:none;" when it's not the dropdown submenu of my selected menu, is it affected my problem? I add HTML menu a little.

Can someone help me? Thank you very much.

Upvotes: 0

Views: 1377

Answers (3)

Henry Gunawan
Henry Gunawan

Reputation: 25

After trying many things, the solution is to upgrade the web browser and using the latest geckodriver, then using the Select function. My bad. Thank you very much for the help.

Upvotes: 0

Naveen
Naveen

Reputation: 788

Can you try using xpath like this ?

dd1 = "//*[text() = 'Input Type']//following::select[1]"
dd2 = "//*[contains(text() , 'Data source')]//following::select[1]"

Select first dropdown by text or value.

select = Select(driver.find_element_by_xpath(dd1))

# select by visible text
select.select_by_visible_text('Dropdown list')
# OR select by value 
select.select_by_value('dropdown_field_type')

and then Select second dropdown

select = Select(driver.find_element_by_xpath(dd2))
# select by visible text
select.select_by_visible_text('Populate with list items specified here')

Make sure to add the exact text with the correct case.

Upvotes: 1

Sers
Sers

Reputation: 12255

Try code below with Selenium Select, xpath based on label and wait for element to be clickable:

sub_menu = wait.until(EC.element_to_be_clickable((By.XPATH, "//div[@id='dropdown_field_type' and .//label[.='Data source for dropdown list']]//select")))
select = Select(sub_menu)
select.select_by_index(0)
# or
select.select_by_visible_text("Populate with list items specified here")

Upvotes: 1

Related Questions