This is the HTML code, for the box, please advice me on how to find the correct xpath for any element in this box.
The box contains list of elements and the element is transferred from left to right box or vice versa when clicked.
<div id="companyIndustry" class="form-group" style="margin:0">
<select id="my-select-industry" name="segmentdiv:companyIndustries" multiple="multiple" size="8">
<option value="1">Agriculture and Mining - Farming and Ranching</option>
<option value="2">Agriculture and Mining - Fishing, Hunting and Trapping</option>
</select>
</div>
Xpath can be:-
//select[#id='my-select-industry']/option[#value='2']
In this case you can use
Select dropdown = new Select(driver.findElement(By.id("my-select-industry")));
To select its option say 'Agriculture and Mining - Fishing, Hunting and Trapping' you can do
dropdown.selectByVisibleText("Agriculture and Mining - Fishing, Hunting and Trapping ");
or
dropdown.selectByIndex(2);
or
dropdown.selectByValue("2");
Hope it will help you :)
List<WebElement> options = driver.findElements(By.xpath("//option"));
You could also search for 'option' tags with relative xpath (searching downward from a 'known' [previously found] element), but that would require you to add a '.' dot instead of double slash before 'option'.
e.g.
WebElement selectElement = driver.findElement(By.id("my-select-industry"));
List<WebElement> options = selectElement.findElements(By.xpath("./option"));
There's a similar example of what you're trying to do here: http://forum.testproject.io/index.php?topic=19.0
Related
I am inspecting one button element from a web page using chrome driver and selenium. And the html code for the particular button is:
<div class="label text-left text-link link-blue text-
uppercase">Financial Statement Analysis <span class="count">(2)</span>
</div>
I have tried different element options like find element by name, xpath, link text etc. But none of them unable to locate the element.
What will be the element to locate the button. ?
try Xpath :
//span[contains(#class,'count') and text() = '(2)']
You can try with this css selector :
div.label.text-left.text-link.link-blue.text-.uppercase
To locate the element with text as Financial Statement Analysis (2) you can use the following solution:
Java Solution:
WebElement elem = driver.findElement(By.xpath("//div[#class='label text-left text-link link-blue text-uppercase'][contains(.,'Financial Statement Analysis')]"));
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")
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.
Not able to select a dynamic drop down PFB the html tag of the element.
Drop down dynamic ids:
page:frm:pageB:repeatUpper:0:repeat:1:ServiceSubtype
page:frm:pageB:repeatUpper:0:repeat:2:ServiceSubtype
HTML Code :
<td class="dataCell" style="border-top:1px solid #838282;">
<span id="page:frm:pageB:repeatUpper:0:repeat:1:DescPopup" class="DescServicePopupClone" style="display:none;"></span>
<span id="page:frm:pageB:repeatUpper:0:repeat:1:DescPopupHasResource" class="DescServicePopupHasResource" style="display:none;"></span>
<span id="page:frm:pageB:repeatUpper:0:repeat:1:DescPopupLOE" class="DescServicePopupLOE" style="display:none;"></span>
My code:
new Select(driver.findElement(By.xpath("//td[contains(#id, 'page:frm:pageB:repeatUpper:0:repeat:')]"))).selectByVisibleText("CAT-New Implementer");
Thread.sleep(18000);
getting the below error:
Caused by: org.openqa.selenium.NoSuchElementException: Unable to
locate element: {"method":"xpath","selector":"//td[contains(#id,
'page:frm:pageB:repeatUpper:0:repeat:')]"} For documentation on this
error, please visit:
http://seleniumhq.org/exceptions/no_such_element.html
UPDATE from OP - part of the "real" HTML:
<select id="page:frm:pageB:repeatUpper:0:repeat:2:ServiceSubtype" name="page:frm:pageB:repeatUpper:0:repeat:2:ServiceSubtype">
<option value="">--None--</option>
<option value="CAT-New Implementer">CAT-New Implementer</option>
<option value="CAT-Repeat Implementer">CAT-Repeat Implementer</option> </select> </span> </td>
Try this one:
new Select(driver.findElement(By.xpath("//select[starts-with(#id, 'page:frm:pageB:repeatUpper:0:repeat:')]"))).selectByVisibleText("CAT-New Implementer");
I also changed "contains" to "starts-with" because that better suits your example.
My suggestion to you is to not use XPath. Prefer ID, then maybe name, and then CSS Selectors. Those 3 locators should be 99% of your find methods. XPath is complex, fragile, and slow. Stick to the simple things until you get them mastered and then move on to XPath when you absolutely must.
This code should work
Select dropdown = new Select(driver.findElement(By.id("page:frm:pageB:repeatUpper:0:repeat:2:ServiceSubtype")));
dropdown.selectByVisibleText("CAT-New Implementer");
Since you have an ID on the SELECT, use that. Because it is a SELECT, casting the WebElement to a Select gets you extra options only available for SELECTs as far as choosing OPTIONs. For your example, you can use either .selectByVisibleText() or .selectByValue() since they are equivalent in the HTML you provided.
EDIT 1
Another option is to look for a partial ID, ID ends with ($) X, but I don't know if that is unique on your page.
Select dropdown = new Select(driver.findElement(By.cssSelector("span[id$=':ServiceSubtype']")));
Yet another option is to increment a counter and insert that into your ID string.
int i = 0;
Select dropdown2 = new Select(driver.findElement(By.id("page:frm:pageB:repeatUpper:0:repeat:" + i + ":ServiceSubtype")));
// i++; each time you add something
I've populated a multiselect using dojo and added the selected values using combo.set("value", selectedValuesArray);
Problem is that when trying to assert the selected values using selenium IDE, I can't figure out how dojo does to "select" the selected values, I would expect to be like
<option value="111" selected>name</option>
But as you can see in the image, there's no indication in the image, not in the disabled (view) or the enabled (edit) one
There's no CSS classes added either, so i don't know how to assert if the item is selected or not.
Any idea?
Here's the generated HTML
<select data-dojo-attach-event="onchange: _onChange" data-dojo-attach-point="containerNode,focusNode" name="combo_project_participants" multiple="true" class="dijitMultiSelect" tabindex="0" id="dijit_form_MultiSelect_3" widgetid="dijit_form_MultiSelect_3">
<option value="1367">name 0 AdminEdge</option>
<option value="1368">Test User name Test User lname</option>
</select>
EDIT: this didn't allowed me to upload the image...
http://imageshack.us/photo/my-images/850/cf6a.jpg
Add
data-dojo-type="dijit/form/MultiSelect"
in your select-Tag. That should fix it.
For further information look at http://dojotoolkit.org/reference-guide/1.8/dijit/form/MultiSelect.html
Regards