I'm using selenium2 webdriver with firefox.
Usually, when there is a combobox for e.g. months I set a distinct month by send_keys(monthname).
I have a special listbox this time, where I can't simply send_keys() to it (not with webdriver nor manually). I'm not a web developer, so I have no idea what the actual difference is. This is the HTML Code of that combobox:
<div class="selectArea marke" style="width: 75px; ">
<span class="left"></span>
<span class="center">Month</span>
<span class="selectButton"></span>
<div class="disabled" style="display: none; "></div>
</div>
<select name="sregisterdmc" id="sregisterdmc" class="marke outtaHere" style="width:75px" multiple="">
<option value="">Month</option>
<option value="01">01</option>
...more options...
</select>
I have no idea how I could set an option here. I found out that I can get all the option values with .find_elements_by_tag_name(), but not how I actually set such one now. Thanks in advance!
Do a click on the option element you want selected.
Related
I'm trying to select an item from a list with selenium / python and am having issues with getting the elements to load and be interactable. I think the problem is the website doesn't load the html for that section until the drop down is clicked but I'm not sure how to go about resolving that. This is what the html looks like if I click view source:
<label data-lang="4003">Impact</label>
<select id="impact">
<option value="" selected data-lang="48">Select</option>
</select>
If I look at it with the chrome inspect tools I see this:
<label data-lang="4003">Impact</label>
<div class="select-wrapper cascading-dropdown-loading initialized">
<span class="caret">▼</span>
<input type="text" class="select-dropdown" readonly="true" data-activates="select-options-e89d2a9c-3be1-67a1-6f4b-32c36b38f6eb" value="Select">
<ul id="select-options-e89d2a9c-3be1-67a1-6f4b-32c36b38f6eb" class="dropdown-content select-dropdown ">
<li class="">
<span>Select</span>
</li>
<li class="">
<span>High</span>
</li>
<li class="">
<span>Medium</span>
</li>
<li class="">
<span>Low</span>
</li>
<li class="">
<span>None</span>
</li>
</ul>
<select id="impact" class="initialized" data-select-id="e89d2a9c-3be1-67a1-6f4b-32c36b38f6eb">
<option value selected data-lang="48">Select</option>
<option value="HIGH">High</option>
<option value="MEDIUM">Medium</option>
<option value="LOW">Low</option>
<option value="NONE">None</option>
</select>
</div>
The data-select-id also seems to be randomly generated, as it changes each time I refresh the page.
So far, I've been able to get a list of the options available using the following code:
select = driver.find_element_by_id("impact")
options = [x for x in select.find_elements_by_tag_name("option")]
for element in options:
print(element.get_attribute("value"))
Attempting to manipulate the list with something like element.click() doesn't seem to work and only gives me the error "Error: Message: element not interactable: Element is not currently visible and may not be manipulated"
I have also tried using Select with code like this with no success. I've used all three select by options, select_by_value, select_by_visible_test and select_by_index with no success.
select = Select(driver.find_element_by_id('impact'))
select = select_by_value("HIGH")
I have also tried exploring select.options which returns a list of objects that look like:
<selenium.webdriver.remote.webelement.WebElement (session="513ab2b2bfc1c3c738af19e69230a763", element="d00bf83d-3772-4357-b6da-1702a12ffda3")>
but I'm not sure how to manipulate these to do anything more with them. The session and element ids also change between runs.
Any help pointing me in the right direction would be greatly appreciated!
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.
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")
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.
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.
I want to click a three way toggle using selenium with python.The html element Ids are dynamic. So I have tried with an XPath where class contains a specific text! But I seeing 'element not found'/'element not visible' whole day!
I've tried with below line of code but no help.
browser.find_element_by_xpath("//*[contains(#class,'switch switch-three toggle ios') and contains(text(),'Available')]").click()
Here is the HTML code of the page and I want to click on - 'Available'
<label class="switch switch-three toggle ios" id="radio8526" onclick="" style="float: left; width: 300px; height:15px; margin-right: 20px;margin-left: 20px;">
<input id="available8526" value="available" onclick="setVersioningIdFun('8526');document.getElementById('toggleStateButton').click();;" name="onoffswitch8526" type="radio">
<label for="available8526" onclick="">Available</label>
<input id="unavailable8526" value="unavailable" onclick="setVersioningIdFun('8526');document.getElementById('toggleStateButton').click();;" name="onoffswitch8526" type="radio">
<label for="unavailable8526" onclick="">Unavailable</label>
<input id="archived8526" value="archived" onclick="setVersioningIdFun('8526');document.getElementById('toggleStateButton').click();;" name="onoffswitch8526" type="radio" checked="">
<label for="archived8526" onclick="">Finalised</label>
<a class="slide-button"></a>
</label>
From w3c documentation You can use this to solve your problem
browser.find_element_by_css_selector('input[id^="available"]').click()
You can just use the value attribute, e.g.
input[value='available']
You might need to add a wait for clickable to make sure the page has loaded. See this link for more info and some examples.
UPDATED
In my Django settings, when I set DEBUG to false, Selenium is able to interact with the elements. It still does not work when DEBUG is set to true
So I am trying to select one option in a dropdown menu, but when I try to directly access the <select> tag I get the error ElementNotVisibleException: Message: element not interactable.
In the console whenever I click on the dropdown in only refers to an input tag that dynamically changes based on what I click on. Ultimately, I want the test to click on the dropdown and then select 'Tango' as shown in the link below.
My Selenium code is:
from selenium.webdriver import Chrome
from selenium.webdriver.support.ui import Select
from selenium import webdriver
driver = webdriver.Chrome()
driver.get("localhost:8000/")
select = Select(driver.find_element_by_xpath('//*[#id="select-dance"]').click())
select.select_by_value('1')
And HTML:
<form onsubmit="return false;">
<div class="row border-light bg-white rounded-left rounded-right no-gutters">
<div class="col-12 col-lg px-3">
<div class="select-wrapper mdb-select">
<span class="caret"></span>
<input type="text" class="select-dropdown" readonly="true" data-activates="select-options-20f378f1-9560-4598-b8e8-
3ffe496cd688" value="Choose your dance event">
<ul id="select-options-20f378f1-9560-4598-b8e8-3ffe496cd688" class="dropdown-content select-dropdown" style="width: 658px; position:absolute;top: 0px; left: 0px;opacity: 1; display: none;">
<li class="">
<span class="filtrable">Choose your dance event</span></li>
<li class="">
<span class="filtrable">Tango</span></li>
<li class="active selected">
<span class="filtrable">Swing</span>
</li>
<li class="">
<span class="filtrable">Latin/Salsa</span>
</li>
<li class="">
<span class="filtrable">Ballroom</span>
</li>
<li class="">
<span class="filtrable">Bachata</span>
</li>
</ul>
<select class="mdb-select initialized" id="select-dance">
<option value="0">Choose your dance event</option>
<option value="1">Tango</option>
<option value="2">Swing</option>
<option value="3">Latin/Salsa</option>
<option value="4">Ballroom</option>
<option value="5">Bachata</option>
</select>
</div>
</div>
</div>
</div>
</form>
I do not know how to deal with the input tag interfering with the select (it only shows up in the elements console in Chrome).
Thank you!
You can handle by,
driver = webdriver.Chrome()
driver.get("localhost:8000/")
time.sleep(10)
select = Select(driver.find_element_by_id('select-dance'))
select.select_by_value('1')
You can try this,
driver = webdriver.Chrome()
driver.get("localhost:8000/")
time.sleep(10)
driver.find_element_by_id('select-dance').click()
when you click then new list of s will get populated under , then call select tag
select = Select(driver.find_element_by_id('select-dance'))
select.select_by_value('1')
or
select = Select(driver.find_element_by_xpath('//*[#id="select-dance"]'))
select.select_by_value('1')
Your page uses custom Select Component which is not the default html select box. In your case, they have used MDBootstrap Select Component which cannot be interacted using selenium Select class.
Please read this answer for your another question which related to the same issue.
I am trying to get the XPath for a drop down field which I can use in my Webdriver, Python code.
There are two drop down fields in the html. I need to identify the drop down which has the options, Person Name, Organisation Name, Address etc.
I would like to select Address value from the drop down.
I have tried the following XPath:
//select[#class="gwt-ListBox marginbelow"]
It identifies both the drop down fields.
<div class="clear">
<span class="gwt-InlineLabel marginbelow myinlineblock" style="width: 8em;">Type</span>
<select class="gwt-ListBox marginbelow" style="display: inline;">
<option value="Person name">Person name</option>
<option value="Organisation name">Organisation name</option>
<option value="Address">Address</option>
<option value="Date">Date</option>
<option value="Email">Email</option>
<option value="Phone">Phone</option>
<option value="Integer">Integer</option>
<option value="Numeric">Numeric</option>
<option value="String">String</option>
<option value="User-defined">User-defined</option>
</select>
</div>
<div class="clear">
<div class="clear">
<div class="clear">
<div style="display: none;" aria-hidden="true">
<div class="clear">
<span class="gwt-InlineLabel marginbelow myinlineblock" style="width: 8em;">TestDB</span>
<select class="gwt-ListBox marginbelow" style="display: inline;">
<option value="paf_uk15051">paf_uk15051</option>
</select>
</div>
</div>
I will then use the XPath like this, e.g.
from selenium.webdriver.support import By
from selenium.webdriver.support.ui import select
data_objects_element_Type.Select(self.driver.find.element(By.XPATH, '//select[#class="gwt-ListBox marginbelow"]'))
data_objects_element_Type.select_by_visible_text(("Address"))
Thanks for suggestions.
Riaz
If you can, I suggest editing the HTML, to contain ID's, so that you can specifically identify your two select boxes separately. If you cannot, here is a solution. I have made a jsfiddle site with your html-code, so that you can execute the script and see for yourself. The only thing you need to change, is the path, and choice of webdriver:
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions
from selenium.webdriver.common.by import By
driver = WebDriver("path_to_webdriver")
driver.get("http://jsfiddle.net/ksftLk9j/")
wait = WebDriverWait(driver, 20, 2)
wait.until(expected_conditions.frame_to_be_available_and_switch_to_it((By.NAME, 'result')))
element = driver.find_element_by_xpath('//select[#class="gwt-ListBox marginbelow"]/option[#value="Address"]')
element.click()
the WebDriverWait, and switch_to_frame-statements are specific for this jsfiddle-case. The two bottom lines are not. You do not say anything about what you want to do with the element, but I'm gonna go out on a limb, and assume that you want to select it. Presto.
You can try by checking the contains function.
Like this:
//option[contains(text(),'Address')]
Try this to find the element and perform click on it directly. This allows you to bypass the use of Select class
//select/option[#value='Address']
you can try it this way :
//select[#class="gwt-ListBox marginbelow"]/option[#value = 'Address']/text()
Try this:
//select[contains(#class, 'ListBox')]/option[#value = 'Address']
So you code will be:
from selenium.webdriver.support import By
from selenium.webdriver.support.ui import select
data_objects_element_Type.Select(self.driver.find.element(By.XPATH, '//select[contains(#class, 'ListBox')]'))
data_objects_element_Type.select_by_visible_text(("Address"))
^ I don't know python, but you need method smth. like selectByValue