I'm testing an application and in the application there is a table containing checkboxes (3 rows, x columns). Below is the html for part of this table (1row). I'm trying to click on the text of one of these items to either select or deselect a checkbox based on the text. So for example, I want to click on the text 'Text next to checkbox for nr 8' in order to select that textbox. However, I don't want to go there via a hard xpath using code like /table/tbody/tr[2]/td[2]/div/span)[2] but based on the text. I'm trying code like the ones below but they don't seem to work:
driver.findElement(By.xpath("(//*[#class='settingsPanelTD' and text()='Text next to checkbox for nr 8']")).click();
driver.findElement(By.xpath("(//*[#class='settingswidgetTitle' and text()='Text next to checkbox for nr 8']")).click();
driver.findElement(By.xpath("(//*[#class='settingswidgets' and text()='Text next to checkbox for nr 8']")).click();
I would like to create a string for the final xpath so you only have to change the text you'd like to click to change the test, something like:
String text = "Text next to checkbox for nr 8"; /** variable text based on what you want to click */
String locator = "//*[#class='settingswidgets' and text()='";
String xpathitem = locator + text + "']";
driver.findElement(By.xpath(xpathitem)).click();
This is the HTML:
<td class="settingsPanelTD" width="33%">
<div class="settingwidgetsTitle">
<input id="widgetsettings8" class="settingwidgets" type="checkbox" alt="2">
<span>Text next to checkbox for nr 8</span>
<a class="AddWidget" href="#"></a>
</div>
</td>
<td class="settingsPanelTD" width="33%">
<div class="settingwidgetsTitle">
<input id="widgetsettings9" class="settingwidgets" type="checkbox" alt="2">
<span>Text next to checkbox for nr 9</span>
<a class="AddWidget" href="#"></a>
</div>
</td>
<td class="settingsPanelTD" width="33%">
<div class="settingwidgetsTitle">
<input id="widgetsettings9" class="settingwidgets" type="checkbox" alt="2">
<span>Text next to checkbox for nr 10</span>
<a class="AddWidget" href="#"></a>
</div>
</td>
I'm using eclipse, Selenium and Java.
The XPaths you are using are incorrect. The third XPath you are using is closest to the correct solution:
//*[#class='settingswidgets' and text()='Text next to checkbox for nr 8']
In plain English, your XPath means - look for any element in the document with a class="settingswidgets" and text equal to Text next to checkbox for nr 8. Unfortunately, no such element exists.
One potential XPath you could use is:
//span[text()="Text next to checkbox for nr 8"]
This searches for any span element with the appropriate text.
You could then use:
String text = "Text next to checkbox for nr 8";
String locator = "//span[text()='";
String xpathitem = locator + text + "']";
driver.findElement(By.xpath(xpathitem)).click();
This should generate the desired click.
I don't have enough reputation to add comment
but in case you are unable to select option by clicking Span tag you need to click on input tag
ArrayList<WebElement> al=new ArrayList<WebElement>();
driver.findElements(By.className("settingwidgetsTitle"));
for(int i=0;i<al.size();i++){
if(driver.findElement(By.xpath(".//div[#class='settingwidgetsTitle']/span")).getText().equals("Option to Select")){
driver.findElement(By.xpath(".//div[#class='settingwidgetsTitle']["+i+"]
/input").click());
break;
}}
Related
I am testing the output of a search and I want to be sure that I will get the text and that it would be bold.
For example I want the name to include "ar". As an output I will get:
But I want to be sure that I will have "ar" in name, but will ignore it in position, department, etc.
The source of the fragment is:
<td style="width: 80%;">
<ul style="font-size: 20px;width: 50%;">
<li><b>Cecil Bonaparte</b></li>
<li style="font-size: 12px;">Software Engineer</li>
<li style="font-size: 12px;">Development</li>
<li style="font-size: 12px;">HQ - CA</li>
<li style="font-size: 12px;">
cecil#osohrm.com </li>
</ul>
</td>
Is there an option to check if an element has the text and this text is bold?
My current code is:
$("[class=odd]").shouldHave(text("char"));
My playground could be found at https://opensource-demo.orangehrmlive.com/index.php/auth/login , Directory tab
My solution for this is below. It is a little difficult to check the styling applied to text but we are fortunate here as the innerHtml() method will expose the inline styling. I should point out that using innerHtml() is not recommended, but I currently do not know a decent alternative.
#Test
public void whatever() {
// Open site and enter credentials
open("https://opensource-demo.orangehrmlive.com/");
$("#txtUsername").val("Admin");
$("#txtPassword").val("admin123");
$("#btnLogin").click();
$("#menu_directory_viewDirectory").click();
var searchTerm = "ar";
$("#searchDirectory_emp_name_empName").val(searchTerm);
// This click is required to cause the dropdown to lose focus
$("#search_form").click();
$("#searchBtn").click();
// Get the first entry from each row in the results table
ElementsCollection resultTable = $$("#resultTable tr li:first-child");
for (SelenideElement searchResult : resultTable) {
// Confirm each result has the expected search term
searchResult.shouldHave(Condition.text(searchTerm));
// Confirm each result has bold applied to the text
assertThat(searchResult.innerHtml().substring(0, 3)).isEqualTo("<b>");
}
}
How my web application works:
My web application loads a div with radio button input elements after conditions in the form above are changed. The form above will allow the manager to select a date and time. The div below will load with all the employees available at that date and time. I give this div the id "EmployeeListBox". Everytime conditions change in the form above the EmployeeListBox gets radio buttons injected using jquery's append method.
Okay so that's the idea of how my web application works. What I am trying to do is click the first radio button in the div EmployeeListBox after the form gets changed, using selenium web driver for Firefox in java. This is the line that I need to fix:
`driver.findElement(By.xpath("//[#id="EmployeeCell"]/span[2]/input")).click();`
When I run this xpath I recive this error:
Exception processing script - Element not found in the cache - perhaps the page has changed since it was looked up.
I guess the xpaths I have tried do not work because the elements are dynamically loaded.
Here is the JS code that loads the EmployeeListBox.
AvialableStaff = JSON.parse( data );
var MSG = "";
$('#EmployeeListBox').empty();
/*for each employee in AvialableStaff load the #CreateShiftLifeOfEmployees Select option*/
var eico = 0;
for ( var Staff in AvialableStaff )
{
var ID = AvialableStaff[Staff]["employeeID"];
var name = AvialableStaff[Staff]["Firstname"]+" "+ AvialableStaff[Staff]["Lastname"];
MSG += "<div id = \"EmployeeCell\">";
MSG += "<span class = \"MakeLeft\" id = \"EI"+eico+"\" > "+name+" </span>";
MSG += "<span class = \"MakeRight\"><input type = \"radio\" name=\"ChooseStaff\" value = \""+ID+"\" class = \"CSTAFFradioButtons\" /> </span>";
MSG += "</div>";
eico++;
}
$('#EmployeeListBox').append( MSG );
Here is my EmployeeListBox without the employee cells:
<p>Select an available employee</p>
<div id = "CSEmployeeList" >
<div id = "StaffAvaileP"> <h3> Staff Available</h3> </div>
<div id = "EmployeeListBox">
<!-- Radio Buttons go here -->
</div>
</div>
This is what the employee box looks like after the form has been changed and employee radio buttons have been inserted:
<div id="EmployeeListBox">
<div id="EmployeeCell">
<span class="MakeLeft" id="EI0"> Person One </span>
<span class="MakeRight">
<input type="radio" name="ChooseStaff" value="9" class="CSTAFFradioButtons">
</span>
</div>
<div id="EmployeeCell">
<span class="MakeLeft" id="EI1"> Person Two </span>
<span class="MakeRight">
<input type="radio" name="ChooseStaff" value="10" class="CSTAFFradioButtons">
</span>
</div>
<div id="EmployeeCell">
<span class="MakeLeft" id="EI2"> Person Three </span>
<span class="MakeRight">
<input type="radio" name="ChooseStaff" value="11" class="CSTAFFradioButtons">
</span>
</div>
</div><!--End of EmployeeListBox -->
Here is my java method which runs the test:
/** Method testCreateShifts
* purpose: Loads shifts with realistic shift data like the
* real life Saturday schedule.
*/
public static void testCreateShifts()
{
driver.get(theurl);
String createshiftPage = "https://***/index.php?/CreateAShift";
driver.get(createshiftPage);
new Select(driver.findElement(By.id("Day"))).selectByVisibleText("11");
new Select(driver.findElement(By.id("StartTime"))).selectByVisibleText("8:30am");
new Select(driver.findElement(By.id("EndTime"))).selectByVisibleText("2:00pm");
driver.findElement(By.id("Instructor")).click();
/*TODO: Currently trying to click on first employee in employee list box*/
driver.findElement(By.xpath("//*[#id=\"EmployeeCell\"]/span[2]/input")).click();
driver.findElement(By.id("CreateShiftSubmit")).click();
}/*End of Method testCreateShifts*/
So using selenium in java how do I click first radio button that is in the list after the EmployeeListBox gets reloaded by jquery?
I found out what was wrong. I needed to give my webapplication time to load.
I told my java test to wait 1 second with this line.
try {Thread.sleep(2000);}catch (InterruptedException ex) { }
I have a dynamically created list of car types, generated on a page.
I want to be able to locate the element by text string , and click on the checkbox next to it (double clicking on the text will produce the same result)
I am currently using :
//select car makes
Actions action = new Actions(driver);
action.moveToElement(driver.findElement(By.xpath("//div[#id='MakesList']/label[2]/i"))).doubleClick().build().perform();
But this is very flaky.. doesn't always select the option i want.
So i am trying to get string "ALFA ROMEO":
action.moveToElement(driver.findElement(By.xpath("//label[contains(.,' ALFA ROMEO ')]"))).doubleClick().build().perform();
But i doesn't select the option.
Here is the html :
<label class="c-option c-option-search--right u-px u-py-sm u-bb u-m-0 ng-binding ng-scope" ng-repeat="item in label.buckets" ng-class="{ 'u-bg-faded u-text-muted u-disabled' : sc.doc_count[label.id + item.key] == 0 }"><input type="checkbox" name="capMakeName" value="alfaromeo" checklist-value="item" ng-model="checked" class="ng-scope ng-pristine ng-untouched ng-valid" checklist-model="sc.searchCriteria.selected.makes">
<i class="c-option__checkbox"></i> ALFA ROMEO <span class="u-text-muted u-text-80 ng-binding">(9)</span>
</label>
Any pointers appreciated.
In your html there are:
<input type="checkbox" name="capMakeName" value="alfaromeo"
If your final goal is to click the checkbox, you could use these infos in order to do that:
driver.findElement(By.xpath("//input[#name='capMakeName' and #value='alfaromeo']")).click();
You could first check if elements are visible (or perhaps wait for them to load),
driver.findElements( By.xpath("//input[#name='capMakeName' and #value='alfaromeo']" ).size() != 0
You could try getting all the checkboxes as a list, then clicking on the one with the text you want
public void clickCheckBoxWithText(String text){
List<WebElement> checkboxes= driver.findElements(By.cssSelector("input[type='checkbox']"));
for(WebElement checkbox:checkboxes){
if(checkbox.getText().equals(text)) {
checkbox.click();
break;
}
}
}
I have a table whose data changes according to what is added and deleted. In the table there are multiple columns Name, Qty, type, Status. All i have is the Name Text with me , i need to find the status field of that row which has that Name.
Problem is the html tags of have same class names and i tried grabbing the parent and sibling everything failed. Please find the html structure of the table below:
<table>
<thead> </thead>
<tbody>
<tr>
<td class = "c1">
<a class = txtclass> text1 </a>
</td>
<td class = "c1"> Qty </td>
<td class = "c2"> type </td>
<td class = "c3">
<div id = "1" class = "status1"> /div>
</td>
</tr>
<tr>
<td class = "c1">
<a> text2 </a>
</td>
<td class = "c1"> Qty </td>
<td class = "c2"> type </td>
<td class = "c3">
<div id = "2" class = "status2"> /div>
</td>
</tr>
</tbody>
</table>
So all i have with me is text2 and i need to get the with the status of that row.
How do i proceed. I tried
List<WebElement> ele = driver.findElements(By.xpath("//*[#class = 'txtClass'][contains(text(),'text')]"));
for(WebElement el1:ele)
{
WebElement parent = el1.findElement(By.xpath(".."));
WebElement child1= parent.findElement(By.xpath("//td[4]/div"));
System.out.println(child1.getAttribute("class"));
}
this gives me the class name of the status of the first row in the table always.
Same i tried with
WebElement child = el1.findElement(By.xpath("//following-sibling::td[4]/div[1]"));
i got the same thing class name of the first row in the table. I figured since the class name of the are same for all child elements it will always grab the first row elements, and not the one from the row.
Please help i am stuck here for long, let me know if you need any other details.
You are trying using -
el1.findElements(By.xpath("//following-sibling::td[4]/div[1]"));
It is matching all the element present with format td[4]/div[1] in your page and retrieving first match.
You have to use following xpath to grab status present under div based on you text.
driver.findElement(By.xpath(".//tr/td[contains(.,'text1')]/following-sibling::td[3]/div")).getAttribute("class");
If your requirement to extract all status try following code-
List<WebElement> allElements = driver.findElements(By.xpath(".//tr/td[contains(.,'text2')]/following-sibling::td[3]/div"));
for(WebElement element:allElements)
{
String status = element.getAttribute("class");
System.out.println(status);
}
I think this approach suitable for you:
Get all div elements containt attribute status :
List<WebElement> listChildStatus = driver.findElements(By.xpath(".//tr[.//a[contains(.,'text')]]//div"));
Get specific div elements containt attribute status :
WebElement childStatus = driver.findElement(By.xpath(".//tr[.//a[contains(.,'{TEXT}')]]//div"));
{TEXT} = the text value that you have
You need to locate the element with the text, go one level up, and then get the sibling with the status
WebElement statusElement = driver.findElement(By.xpath(".//td[a[contains(text(),'text2')]]/following-sibling::td[3]/div"));
String status = statusElement.getAttribute("class"); // will be status2
If you don't want to relay on index you can use last() to find the last sibling
WebElement statusElement = driver.findElement(By.xpath(".//td[a[contains(text(),'text2')]]/following-sibling::td[last()]/div"));
<div class="Class-feedbacks">
<div class="grading class2">
<div itemtype="http://xx.edu/grading" itemscope="" itemprop="studentgrading">
<div class="rating">
<img class="passportphoto" width="1500" height="20" src="http://greg.png" >
<meta content="4.0" itemprop="gradingvalue">
</div>
</div>
<meta content="2012-09-08" itemprop="gradePublished">
<span class="date smaller">9/8/2012</span>
</div>
<p class="review_comment feedback" itemprop="description">Greg is one the smart person in his batch</p>
</div>
I want to print:
date: 2012-09-08
Feedback : Greg is one the smart person in his batch
I was able to use this as suggested at - Jsoup getting a hyperlink from li
The doc.select(div div divn li ui ...) and get the class feedback.
How should I use the select command to get the values of the above values?
To get the value of an attribute, use the attr method. E.g.
Elements elements = doc.select("meta");
for(Element e: elements)
System.out.println(e.attr("content"));
In one single select ...have you tried the comma Combinator "," ?
http://jsoup.org/apidocs/org/jsoup/select/Selector.html
Elements elmts = doc.select("div.Class-feedbacks meta, p")
Element elmtDate = elmts.get(0);
System.out.println("date: " + elmtDate.attr("content"));
Element elmtParag = elmts.get(1);
System.out.println("Feedback: " + elmtParag.text());
You should get back 2 elements in your list the date and the feedback after the select.
This is an old question and I might be late, but if anyone else wants to know how to do this easily, the below code will be helpful.
Document doc = Jsoup.parse(html);
// We select the meta tag whose itemprop property has value 'gradePublished'
String date = doc.select("meta[itemprop=gradePublished]").attr("content");
System.out.println("date: "+date);
// Now we select the text inside the p tag with itemprop value 'description'
String feedback = doc.select("p[itemprop=description]").text();
System.out.println("Feedback: "+feedback);