I'm trying to select a value in a select element. I'm using Selenium RC (Java) to run the test cases. I understand that the code for selecting a value is given by:
selenium.select("locator", "value=REQUIRED VALUE")
I'm unable to select the desired value with the above code. I think it might be something to do with optgroup in the select source code. I do not get any exceptions, the command executes fine but looking at the page the required value is not selected.
Also, I cant use ids (instead of value) because there arent any. Here is the source code of the selector:
<select>
<optgroup label="Group1">
<option value="13">some value1</option>
<option value="25">some value2</option>
</optgroup>
<optgroup label="Group2">
<option value="18">REQUIRED VALUE</option>
<option value="34">some value3</option>
...
...
</optgroup>
</select>
Is there any way to select the required value using Selenium?
It would be great if we could avoid the option values (such as "18", "34" etc) because these numbers change later as the values change. For example, "REQUIRED VALUE" has a value -18 but if I were to delete this item and add it again its value would be different. Basically this drop-down box is dynamic.
The value for the required option in your example is actually '18'. Try the following:
selenium.select("locator", "label=REQUIRED VALUE")
Related
I have the following dynamic xpath:
/html/body[#class='modal-open']/div[#class='container']/form[#id='form_application']/div[#id='interviewContent']/div[#class='modal-dialog']/div[#class='modal-content']/div[#class='modal-body']/div[#id='form_application:interviewContent']/div[#id='form_application:questionDropdown']/select[#id='form_application:j_idt473']
How can I make this unique for Selenium Web Driver? I was going to do a Starts-with method but this is pertaining to a drop down box where the values selected changes with each log in.
Page Source:
<br /><select id="form_application:j_idt473" name="form_application:j_idt473" class="form-control" size="1" style="width:250px;display:inline" onchange="mojarra.ab(this,event,'change','#this','form_application:questionDropdown form_application:dropdown_interview')"> <option value=""></option>
<option value="02">Alaska</option>
<option value="01">Alabama</option>
<option value="05">Arkansas</option>
<option value="60">American Samoa</option>
<option value="04" selected="selected">Arizona</option>
<option value="06">California</option>
""""
You can use css attribute selectors to match partial strings. I would get rid of that super complex xpath and use a contains selector instead to match a substring. Something like this should do the trick...
select[onchange*="form_application:questionDropdown form_application:dropdown_interview"]
As you mentioned in your Question that the xpath is dynamic and the HTML clearly shows the element as a <select> tag so we have to construct our xpath accordingly. I think you were quite right when you spoke about using Starts-with method as looking at the id and name attributes it seems to me though the attributes are dynamic but the string form_application: will be a constant. So we can use the following xpath :
Java
Select city = new Select(driver.findElement(By.xpath("//select[#class='form-control' and starts-with(#id,'form_application:')]")));
city.selectByIndex(2);
Python
select = Select(driver.find_element_by_xpath("//select[#class='form-control' and starts-with(#id,'form_application:')]"))
select.select_by_visible_text("Alabama")
I am having difficulty creating an xpath. I can write an xpath and map it directly to the id and it works fine. The problem arises when I need to select a different product. Most of the id is static and does not change, but the rest of it does change. I've tried writing an xpath with the contains clause and it still does not work.
Here is what I have tried:
//*[contains(#id, 'j_id0:j_id1:j_id6:section2:j_id34:j_id35:j_id67:j_id68:0:j_id138:j_id139:1:j_id219')]
//*[#id='j_id0:j_id1:j_id6:section2:j_id34:j_id35:j_id67:j_id68:']/option[5]
Here is the code I'm writing the xpath from:
<select id="j_id0:j_id1:j_id6:section2:j_id34:j_id35:j_id67:j_id68:0:j_id138:j_id139:0:j_id222" name="j_id0:j_id1:j_id6:section2:j_id34:j_id35:j_id67:j_id68:0:j_id138:j_id139:0:j_id222" class="user-success">
<option value="">--None--</option>
<option value="Budget">Budget</option>
<option value="Drop/New">Drop/New</option>
<option value="Management Change">Management Change</option>
<option value="Never Fulfilled">Never Fulfilled</option>
<option value="Product Swap">Product Swap</option><option value="Renewal">Renewal</option><option value="Stacked">Stacked</option></select>
Try using following:
//div[#class='user-success']/option[5]
This way you don't have to worry about changing xpath.
I just upgraded some functional testing code to use a newer version of Selenium and the required geckodriver, and now code that previously was selecting an option in an HTML select control is no longer working. I can reproduce the problem with a trivial page:
Here's the relevant code:
1. my_select = Select(driver.find_element_by_id("foo_select"))
2. my_select.select_by_value("3")
and the relevant HTML
<form>
<select id="foo_select" name="foo_select">
<option selected="selected" value="1">Ford</option>
<option value="2">Hyundai</option>
<option value="3">Jeep</option>
<option value="4">Kia</option>
<option value="5">Nissan</option>
<option value="6">Toyota</option>
</select>
</form>
I can check the value of my_select after 1 above and it does indeed refer to the select named "foo_select". But line 2 doesn't seem to be selecting the option with value "3" (it's not selecting anything. I've also tried the other "select_by.." variations). Indeed, if I look at my_select.first_selected_option (after 2) it still refers to the first option, "Ford".
The problem goes away when using Firefox 49. I was using 48.
When I execute my script using IEDriver without compatibility view, my test script is running without any problem.
But, If I execute the same script after adding domain in compatibility view, then some elements are not found and I'm getting exceptions.
e.g.
I want to get text of selected item from this DOM:
<select id="selectNumber" name="selectNumber" style="width:180px;">
<option selected="selected" value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
</select>
and I'm using XPath .//*[#id='selectNumber']/option[#selected='selected']
to get text but it does not work.
I just checked that in IE DOM selected="selected" is not displayed for selected option until I change Document version manually.
You can use the Select class that works with every browser. Here's some code
Select sel = new Select(driver.findElement(By.id("selectNumber")));
WebElement selectOption = sel.getFirstSelectedOption();
String text = selectOption.getText();
I think you should consider to change from using XPath to use cssSelector. It's much safer to find the elements, not depending on the whole "path". There's a big chance it would not break when using cssSelector running with IEDriver (as you stated in your question).
You can achieve the same goal with both, but when you use XPath, your DOM is much more sensible to changes, and you have bigger chances to see tests broken after page changes.
For your case, you could use it in two ways:
XPath (as you must have it)
driver.findElement(By.xpath(".//*[#id='selectNumber']/option[#selected='selected']"))
Selector
driver.findElement(By.cssSelector("#selectNumber[selected]"))
When you have more complex "paths" you can combine more things like CSS classes in cssSelectors. For example (when you don't have ID):
<select class"nice-dropdown" name="selectNumber" style="width:180px;">
<option selected="selected" value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
</select>
driver.findElement(By.cssSelector("select.nice-dropdown")) (return the select element)
driver.findElement(By.cssSelector("select.nice-dropdown option[value='3']")) (return the option with value=3)
With selectors you have shorter "paths". They work in the same way as selectors are used in CSS.
As reference:
Selectors = w3schools
Selectors = W3C
Hope this information is somehow helpful.
Been trying to fix this for a while now. I have loads of Dojo Filtering Select elements in my form. I need them to have a blank option which should be selected by default. Here is an example (of a normal <select> structure) that I want to emulate:
<select>
<option value="">-</option>
<option value="foo">Bar</option>
</select>
At present when I load up my filtering selects that have the options set as above, there is no element selected. This in turn disables form submission. This is totally unusable for my end users as they would have no idea why the form is not working. The selects are not even required fields.
The problem lies in the way the FilteringSelect stores it's data. It keeps them in a data store that requires an identifier and a label. You can't quite emulate the functionality of a plain select because of this.
You can 'get around' this by putting a fake item in your options with a value of 'XXXX' (or another fake value).
<select>
<option value="XXXX">-</option>
<option value="foo">Bar</option>
</select>
One downside of this kludge is that you need to change your validation functions to look for this fake value (instead of an empty value).
I set up a test on jsbin.com where you can see it in action.