I need to select a row in a table where I have a text, hence I would like to leverage the option of selecting a text and then eventually selecting the parent
Now the page looks like:
<tr class=" tableRow1" id="_pu5ufb" dr="1" _awtisprimaryrow="1">
<td width="1" class="tableBody w-tbl-cell" align="center"><span
class="selectColumnMarker">
<div class="w-chk-container">
<input bh="CHKINP" hasaction="false" class="w-chk-native"
id="_m7iynb" value="1" type="checkbox" elementid="_jw4lmb"
issender="false" awnomitcomponent="true" name="_jw4lmb"><label
bh="CHK" class="w-chk w-chk-dsize"></label>
</div>
</span>
</td>
<td align="left" class="tableBody w-tbl-cell">
<span>
<table role="presentation" class="mls" cellpadding="0"
cellspacing="0">
<tbody><tr>
<td class="" id="_tz87e" tabindex="0"><a id="_3iqrbb" href="#"
bh="HL" _sf="true">Analyst</a>
</td>
</tr>
</tbody></table>
</span>
</td><td class="tableBody w-tbl-cell">
</td>
<td class="tableBody w-tbl-cell">
</td>
</tr>
I need to find the text Analyst and then find the associated <tr> class and select the <tr> class.
Any help would be highly appreciable
First, whenever you have mixed content (text and markup) it is better to compare elements' string value than text nodes because inline markup might be splitting the compared text into different text nodes.
Second, you can use:
//tr[td='Analyst']/#class
Note: node-set comparison is an existencial comparison. It means that you are asking if there is some node (some td element in this case) with string value equal to 'Analyst'.
Of course, in HTML there are elements for which white space is not significant for rendering (it's not preserved) despite its presence in the source document. In that case you can use this simple XPath 1.0 expression:
//tr[td[normalize-space()='Analyst']]/#class
Do note: a node-set has a false boolean value if and only if it's empty; you can "nest" predicates (properly, a predicate can be any XPath expression).
I need to find the text Analyst and then find the associated tr class and select the tr class.
XPath 2.01
This XPath,
//tr[td/normalize-space() = "Analyst"]/#class
will select all #class attributes of tr elements containing a td with a space-normalized string value of "Analyst".
Do note, however, that in your sample HTML, such a tr has no #class.
1Thanks for correction, #DebanjanB
Fix your XML file to
<?xml version="1.0"?>
<!DOCTYPE stylesheet [
<!ENTITY nbsp " ">
]>
<root>
<tr class=" tableRow1" id="_pu5ufb" dr="1" _awtisprimaryrow="1">
<td width="1" class="tableBody w-tbl-cell" align="center">
<span class="selectColumnMarker">
<div class="w-chk-container">
<input bh="CHKINP" hasaction="false" class="w-chk-native" id="_m7iynb" value="1" type="checkbox" elementid="_jw4lmb" issender="false" awnomitcomponent="true" name="_jw4lmb"/>
<label bh="CHK" class="w-chk w-chk-dsize"/>
</div>
</span>
</td>
<td align="left" class="tableBody w-tbl-cell">
<span>
<table role="presentation" class="mls" cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td class="" id="_tz87e" tabindex="0">
<a id="_3iqrbb" href="#" bh="HL" _sf="true">Analyst</a>
</td>
</tr>
</tbody>
</table>
</span>
</td>
<td class="tableBody w-tbl-cell">
</td>
<td class="tableBody w-tbl-cell">
</td>
</tr>
</root>
Then, the expression you are looking for is
//tr[td/a/text()='Analyst']/#class
But because the tr element does not have a class attribute, the result is empty.
A bit unclear what exactly you meant by ...find the associated tr class and select the tr class... once you have found ...the text Analyst....
However, as the elements are dynamic element and to locate the element with text as Analyst you can use either of the following Java based Locator Strategies:
linkText
WebElement elem = new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOfElementLocated(By.linkText("Analyst")));
cssSelector:
WebElement elem = new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("td.tableBody table.mls a[bh='HL']")))
xpath:
WebElement elem = new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//td[contains(#class, 'tableBody')]//table[#class='mls']//a[text()='Analyst']")));
To extract the class attribute of the <tr> element with respect to the text as Analyst you can use the following Java based solution:
xpath:
String tr_class_attrib = new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("//td[contains(#class, 'tableBody')]//table[#class='mls']//a[text()='Analyst']//preceding::tr[1]"))).getAttribute("class");
Not able to find the element with input tag. Need to find the element in the input tag. eclipse could catch the element till nobr and not further.
input id="ServiceFromDate" class="inactvDtTmTxt" name="$PHCClaimSearch$pServiceFromDate" data-ctl="["DatePicker"]" data-formatting="yes" value="05/02/2017" data-value="5/2/2017" style="padding-right:17px;width:11.719em;" validationtype="date" data-change="[["refresh", ["thisSection","", "", "&=", "", ",",":event","","HCClaimSearch"]]]" data-display-value="05/02/2017" type="text"/>
//table[contains(#role,'presentation')][contains(#id,'pyActionArea')]//table[1]//table[contains(#role,'presentation')][contains(#section_index,'1')]//tbody//tr[2]//td[1]//following::nobr[1]//following::span[#id='$PHCClaimSearch$pServiceFromDateSpan']/input
driver.findElement(By.xpath("//input[#id='ServiceFromDate']")).sendKeys("04242015")
<table id="" role="presentation" section_index="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<tr>
<td class="dataLabelWrite" style="height:24px;width:143px;">
<td class="dataValueWrite" style="height:24px;width:190px;">
<nobr>
<ins id="pega-calendar" style="display: none;" data-calendar="{"img":"webwb/pzspacercal_12860256145.gif!!.gif","locale":[["0","1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19","20","21","22","23","24","25","26","27","28","29","30","31","32","33","34","35","36","37","38","39","40","41","42","43","44","45","46","47","48","49","50","51","52","53","54","55","56","57","58","59"],0,"M/d/yyyy","M/d/yyyy h:mm a","Today",["January","February","March","April","May","June","July","August","September","October","November","December"],["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],["AM","PM"],"Apply","Close"]}"/>
<script> var positionDatePickerIcn = function(control){ /* BUG-47098 - Following block filters out IE8(both quirks and standards modes) and IE9 (standards mode) */ var addMarginFlag = true; if(document.documentMode && navigator.userAgent.indexOf("Trident/4") > -1){ //IE8: skip for both standards and quirks mode addMarginFlag = false; } else if(document.documentMode && document.documentMode >= 9 && navigator.userAgent.indexOf("Trident/5") > -1){ //IE9: skip for standards mode addMarginFlag = false; } if (addMarginFlag) { var icnEle = control.lastChild; if(icnEle.tagName.toLowerCase() == 'img'){ icnEle.style.marginTop = '0px'; } } }; </script>
<span id="$PHCClaimSearch$pServiceFromDateSpan" role="group" aria-label="Service From Date : " data-calendar="{"d":[0,0],"l":0}" style="display:inline-block; width:inherit;" onmouseover="pega.c.DatePicker.dtTmHvr(event);">
<input id="ServiceFromDate" class="inactvDtTmTxt" name="$PHCClaimSearch$pServiceFromDate" data-ctl="["DatePicker"]" data-formatting="yes" value="05/02/2017" data-value="5/2/2017" style="padding-right:17px;width:11.719em;" validationtype="date" data-change="[["refresh", ["thisSection","", "", "&=", "", ",",":event","","HCClaimSearch"]]]" data-display-value="05/02/2017" type="text"/>
<img class="inactvIcon" src="webwb/pzspacer_11792674401.gif!!.gif" data-ctl="["DatePicker"]" style="cursor:pointer;"/>
</span>
</nobr>
</td>
<td class="dataLabelWrite" style="height:24px;width:125px;">
<td class="dataValueWrite" style="height:24px;width:190px;">
<td class="dataLabelWrite" style="height:24px;width:101px;">
</tr>
</tbody>
</table>
The problem is with the HTML, at least as you've pasted here.
there are a number of places inside that tag that have double-quoted text inside of double-quoted text. e.g. the input element has the following attribute:
data-ctl="["DatePicker"]"
Other attributes I found with this problem: data-calendar, data-change
Once I corrected all of the places that this is a problem with outer single quotes, I was able to find the input using your Xpath from the Chrome developer tools
data-ctl='["DatePicker"]'
As you mentioned, you could catch the element till <nobr> tag and not further that is because the <ins> tag is having style="display: none;", so will use JavascriptExecutor to change the attribute and then send the text as follows :
((JavascriptExecutor)driver).executeScript("document.getElementById('pega-calendar').style.display='block';");
driver.findElement(By.xpath("//input[#id='ServiceFromDate']")).sendKeys("04242015");
I am using jquery kendo grid in my project where i used row template to show three column in one row. Below is the code:
<table id="grid" style="width:100%">
<thead style="display:none">
<tr>
<th>
Details
</th>
</tr>
</thead>
<tbody>
<tr>
<td colspan="3"></td>
</tr>
<tr>
<td>
</td>
</tr>
</tbody>
</table>
<script id="rowTemplate" type="text/x-kendo-tmpl">
<div>
<span class="name" style="font-size:medium">#: FirstValue #</span>
<span class="name" style="font-size:medium">#: SecondValue #</span>
</div>
<tr>
<td style="width:30%">
#: GetName #
<span class="name" style="font-size:14px; color:green">#: Designation #</span>
<span class="name" style="font-family:Arial; font-size:small">#: Company #</span>
</td>
</tr>
</script>
in the above code i am just passing my model data it's working fine but when i added one div which have value firstName and LastName so it is also repeating with this data but i want to to show separately.How do i show it separately so that it should not repeat with grid.
there is one problem in your html template.
Please replace '#' with 'Javascript:void(0)'.
Error:- #: GetName #
Fix:- #: GetName #
Hope that's work for you.
http://jsfiddle.net/parthiv89/t0w3ht6m/1/
if you like then don't forget to like.
I got solution by own, Firstly i changed code in my schema like this:
schema: {
parse: function (data) {
var items = [];
for (var i = 0; i < data.data.length; i++) {
if (data.data[i].CorrectValue != null && data.data[i].SearchValue != null) {
$("#spnSR")[i].innerHTML = "<b>"+"Get results for this text: "+"</b>"+data.data[i].CorrectValue;
$("#spnSV")[i].innerHTML = "<b>" + "Searched for this text: " +"</b>" + data.data[i].SearchValue;
}
}
var product = {
data: data.data,
total: data.total
};
items.push(product);
return (items[0].data);
},
}
Then in html i used two span to show this value which is there in for loop.
and it's working fine for me.
Thanks everyone.
Here is the table that I am using to get the table row element that has specific element such as the href that has 'Harvest' in text and also checking if text 'running' exists in the same table row.
<table id="execTable" class="tableHistory jobtable translucent">
<colgroup>
<col class="execid">
<col class="titlecol">
</colgroup>
<tbody>
<tr>
<th>Id</th>
<th>Name</th>
</tr>
</tbody>
<tr id="8571">
<td>8571</td>
<td class="titlecol">
<div id="hitdiv-8571" class="arrow"></div>
Harvest
</td>
<td>09-03-2015 09:45:04</td>
<td>-</td>
<td>2m 6s</td>
<td>running</td>
<td>view/restart</td>
</tr>
<tr id="8571-child" class="childRow" style="display: none;"></tr>
<tr id="8566">
<td>8566</td>
<td class="titlecol">
<div id="hitdiv-8566" class="arrow"></div>
mk
</td>
<td>09-03-2015 03:30:00</td>
<td>09-03-2015 04:16:50</td>
<td>46m 50s</td>
<td>succeeded</td>
<td>view/restart</td>
</tr>
<tr id="8555-child" class="childRow" style="display: none;"></tr>
</table>
I am not able to get the TRs.
WebElement table = driver.findElement(By.id("execTable"));
List<WebElement> trows = table.findElements(By.tagName("tr"));
List<WebElement> all = driver.findElements(By.xpath(".//*[#id='execTable']/*"));
for (WebElement a : all) {
if(a.getTagName().equalsIgnoreCase("tr")) { ....}
}
I was able to get the above code working. Thank you!
code is used is:
WebElement desc=driver.findElementByXPath(".//*[#label='Description']");
desc.sendKeys("testing");
desc.sendKeys(Keys.ENTER);
List<WebElement> button=driver.findElementsByXPath("(//div[#id='sv'])[1]");
for (WebElement buttonname : button)
{
System.out.println("buttonname: "+buttonname.getAttribute("id"));
String but = buttonname.getAttribute("id");
driver.findElementById(but).click();
}
Below is the html code of that textarea and button .
<td>
<textarea id="1992800000" label="Description" ft="12" mand="false"class="ic" maxlength="120" cols="13" rows="2"/>
</td>
......
<table cellspacing="0" cellpadding="0">
<tbody>
<tr style="height: 40px; ">
<td class="pdl">
<div class="tbut" onclick="ir('Tas','tas','')" id="sv">Save</div>
</td>
Your XPath can only select one element, so there is no need to create a list and iterate through it.
Try something more like:
WebElement desc=driver.findElementByXPath("//*[#label='Description']");
desc.sendKeys("testing");
WebElement button=driver.findElementsByXPath("(//div[#id='sv'])[1]");
button.click();