I am currently trying to drill down on a user in a table full of users using Selenium webdriver, I have worked out how to iterate through the table but I'm having trouble actually selecting the person I want.
Here is the HTML (modified with X's due to it not being my data)
<table id="XXXXXXXXX_list" cellspacing="0" cellpadding="0" style=" border:0px black solid;WIDTH:100%;">
<tbody>
<tr cellspacing="0" style="height: 16px;">
<tr>
<tr onclick="widgetListView_onClick('XXXX_list',1,this,event)">
<tr onclick="widgetListView_onClick('XXXX_list',2,this,event)">
<tr onclick="widgetListView_onClick('XXXX_list',3,this,event)">
<tr onclick="widgetListView_onClick('XXXX_list',4,this,event)">
<tr onclick="widgetListView_onClick('XXXX_list',5,this,event)">
<tr onclick="widgetListView_onClick('XXXX_list',6,this,event)">
<tr onclick="widgetListView_onClick('XXXX_list',7,this,event)">
<td class="listView_default_dataStyle" nowrap="" style="font-size:12px ;
font-family: sans-serif ;color: black ;background: #FFFFFF "
ondblclick="XXXXListView_onDblClick('XXXXX_list',17, event)">NAME</td>
<td class="listView_default_dataStyle" nowrap="" style="font-size:12px ;font-family: sans-serif;
color: black ;background: #FFFFFF " ondblclick="XXXXX_onDblClick('XXXX_list',17, event)"> </td>
</tr>
Here is the code I am writing to try and find the user going by NAME in the table.
WebElement table = driver.findElement(By.id("table_list"));
// Now get all the TR elements from the table
List<WebElement> allRows = table.findElements(By.tagName("tr"));
// And iterate over them, getting the cells
for (WebElement row : allRows) {
List<WebElement> cells = row.findElements(By.tagName("td"));
for (WebElement cell : cells) {
List<WebElement> Names = cell.findElements(By.xpath("//td[text()='NAME']"));
System.out.println(Names);
This just prints thousands of [] (the table is huge in the real application).
Essentially what I need is to stop when I find the correct name and create a web element out of that table row. Which I can then click and drill down on.
Sorry if any of this is a bit vague,
Well if each name in the table is unique, you don't need to complicate things so much. Just search for element with text matching your 'Name' then select the row accordingly. Look at the code below:
WebElement name = driver.findElement(By.xpath("//table[#id='XXXXXXXXX_list']//td[contains(text(),'NAME')]"));//Select td with text NAME in table with id XXXXXXXXX_list
WebElement rowWithName = name.findElement(By.xpath("./.."));//Select the parent node, i.e., tr, of the td with text NAME
/*
* Look into that row for other element or perform any action on the row.
*/
If the names are not unique, i.e., same name exists twice at similar node, 1st instance will be picked each time. In that case we will have to try things differently, i.e., we will have to index the xpath for correct instance of matching name. Do ask if you have any further doubts :)
This will help you out.
try{
ArrayList<WebElement> cells = (ArrayList<WebElement>) driver.findElements(By.tagName("td"));
log4j.info("Value = "+input_type+" is stored in array from Webpage for "+keyword+" ");
for(WebElement type : cells)
{
if(type.getAttribute("name").equals("your correct name here")) {
type.sendKeys("ABC");
}
}
return true;
}catch(Throwable e){
return false;
}
You need to use Array list like this and you can compare your Name in which you wanna fill value Or wanna do any operation like getText(), click() etc.
Enjoy!
Related
I want to click on the Checkbox element which is present in the dynamic web table which has 3 static columns (CheckBox, Description, Link) and dynamic rows.
I'm able to get the exact text of the description of the check box but I'm unable to click on the check box.
Here's the script I tried to achieve my expectation but didn't work. Might be a wrong approach.
WebElement dataTable = driver.findElement(By.id("table_id"));
List<WebElement> TDs = dataTable.findElements(By.tagName("td"));
for(WebElement td : TDs)
{
if (!td.getText().trim().equals("text that i want to click on its checkbox"))
continue;
WebElement particularTd = td.findElement(By.xpath("//*[#type='checkbox']//preceding::input"));
particularTd.click();
}
Could you tell me the right way to click on the check box?
Thanks,
Karunagara Pandi G
I think the td contains only the data.
What you can try is to navigate back to the immediate parent table-row (tr) containing table-data(td). Then searching for the input 'checkbox' there.
<table>
<tr>
<td>
<center><input type='checkbox'/></center>
</td>
<td>
<span>Cell Desc</span>
</td>
<td>
<hyperlink>
</td>
</tr>
</table>
To click the checkbox you can use xpath:
//*[#text='Cell Desc']/ancestor::tr//input
To make the xpath dynamic you can fetch the value and use that value
String value = "Cell Desc";
String xpath = "//*[#text='" + value + "']/ancestor::tr//input";
This worked for me please try the below code:
for(WebElement td : TDs)
{
if (td.getText().contains("Your Text")
td.click;
}
//if you are unable to click with td.click; use below code
for(WebElement td : TDs)
{
if (td.getText().contains("Your Text")
{
WebElement particularTd = td.findElement(By.xpath("//*[#type='checkbox']//preceding::input"));
particularTd.click()
}
}
Can anyone help me to find out the list of child tagnames using reference of parent tagname.
In a table I have list of rows and columns which means each row has 14 columns and each column has list of inner tags like span, span, input. Now I need to find the list of items under column td[11] for which I have written the below code:
element=driver.findElement(shopviewtableid);
items=element.findElements(shopviewrow);
if(items.size()>0) {
for(WebElement ele:items) {
columnvalues=ele.findElements(shopviewcolumn);
for(WebElement item:columnvalues) {
System.out.println("Inside Tag name of each column"+item..toString());
In the above code I am passing table id in shopviewtable id and tagname tr for shopviewrow and xpath //td[11] for shopviewcolumn. Now after fetching the td[11] for each row again I am fetching the list of items under td[11]
for(WebElement item:columnvalues) {
System.out.println("Inside Tag name of each column"+item..toString());" .
Here under td[11] I have three items with tagname as span,span,input. PFA screenshot How do I get name of these tags from the list[enter image description here]
Tried using item.getTagname() for each item but it displays td as tagname and not the name of the element inside the td[11].
It would be great if anyone could help me on this issue.
Here is my Html structure:
<td role="gridcell" style="width: 11%;" class="jqnoDetails">
<span id="detailsForm:j_id_5q:0:minQuantity" class="hidden">1</span>
<span id="detailsForm:j_id_5q:0:incQuantity" class="hidden">1</span>
<span id="detailsForm:j_id_5q:0:originalQuantity" class="hidden">1.0000</span>
<input id="detailsForm:j_id_5q:0:quantity" name="detailsForm:j_id_5q:0:quantity" type="text" value="1" min="0" inc="1" onblur="PrimeFaces.bcn(this,event,[function(event){handleQuantityChanged(this); updatePrice($(this), 11.23);},function(event){jsf.ajax.request('detailsForm:j_id_5q:0:quantity',event,{execute:'#this ',render:'#this ','CLIENT_BEHAVIOR_RENDERING_MODE':'OBSTRUSIVE','javax.faces.behavior.event':'blur'})}])" style="width: 85%;" aria-required="true" class="ui-inputfield ui-inputtext ui-widget ui-state-default ui-corner-all jqQuantityInput textCenter" role="textbox" aria-disabled="false" aria-readonly="false">
</td>
I am assuming that you have the mechanism to find the cell using iteration as shown. Now try to get all child elements of particular grid cell using XPath like this -
List<WebElement> childElements =item.findElements(By.xpath(".//child::*"));
//try even (".//*") as XPath to get the child elements
once you have a list of elements, you can iterate using for loop to get required tag or another data getAttribute method of WebElement.
Please find the below code to get the tag names of each element inside a cell.
element=driver.findElement(shopviewtableid);
items=element.findElements(shopviewrow);
if(items.size()>0) {
for(WebElement ele:items) {
columnvalues=ele.findElements(shopviewcolumn);
for(WebElement item:columnvalues) {
System.out.println("Inside Tag name of each column");
insideElements=item.findElements(By.xpath("//*");
for(WebElement ele:insideElements)
{
System.out.println("Inside Element tag:"+ ele.getTagName();
}
}
I want a generic approach to perform click link in table cell by providing column name and row index.
There may be multiple type of HTML table structure, but I need generic function which perform action in every table which looks like a generic HTML table.
For eg. following some generic tables are define :-
1- first table structure
<table>
<tr>
<th>column1</th><th>column2</th><th>column3</th>
</tr>
<tr>
<td>Link1</td><td>Link2</td><td>Link2</td>
</tr>
</table>
2- second table structure
<table>
<tr>
<td>column1</td><th>column2</th><td>column3</td>
</tr>
<tr>
<td>Link1</td><th>Link2</th><td>Link2</td>
</tr>
</table>
3- third table structure
<table>
<tr>
<td>column1</td><td>column2</td><td>column3</td>
</tr>
<tr>
<td>Link1</td><td>Link2</td><td>Link2</td>
</tr>
</table>
Here If I provide two parameter for eg.
String columnName = "column2", int rowIndex = 1;
then My generic function perform click link Link2 in table cell at 2,1 in all tables.
I can find the table using WebDriver as follows :-
WebDriverWait wait = new WebDriverWait(driver, 10000);
WebElement tableElment = wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//table")));
But I do not know how to make a generic function to process this table as I want.
Please help me to create a generic function in Java to achieve this task.
Using JavascriptExecutor in WebDriver is also acceptable..
Pseudo code or Algorithm to achieve this is also acceptable..
Thanks in advance...:)
You could get the index of the column matching the targeted header and then return the link in the targeted row/column.
I would use a piece of JavaScript for this task:
static WebElement getTableLink(WebElement table, String column, int row) {
JavascriptExecutor js = (JavascriptExecutor)((RemoteWebElement)table).getWrappedDriver();
WebElement link = (WebElement)js.executeScript(
"var rows = arguments[0].rows, header = arguments[1], iRow = arguments[2]; " +
"var iCol = [].findIndex.call(rows[0].cells, (td) => td.textContent == header); " +
"return rows[iRow].cells[iCol].querySelector('a'); " ,
table, column, row);
return link;
}
Usage:
// get the table
WebElement tableElement = wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("table")));
// click the link in column "column2", row 1
getTableLink(tableElement, "column2", 1).click();
I need to get the download link in this table:
<table cellpadding="0" cellspacing="3" border="0">
<tr>
<td><img class="img" src="...path" /></td>
<td>File -
<a id="1569" class="tepLink" href="javascript:void(0);">[Click me]</a>
</td>
</tr>
</table>
and this is what I tried:
Element table = doc.select("table[cellpadding=\"0\" cellspacing=\"3\" border=\"0\"]").first();
Element dwlLink = table.select("td:has(a)").first();
String absPath = dwlLink.attr("abs:href");
//use download manager to download from string absPath
I always get a "null object reference" so I must be wrong with that code, what should it do?
Just select all anchor tags and then get the first element in the Elements object.
Elements anchorTags = doc.select("table[cellpadding=0][cellspacing=3][border=0] a");
if(anchorTags.isEmpty())
{
System.out.println("Not found");
}
else
{
System.out.println(anchorTags.first());
}
EDIT:
I changed the select method to include the cellpadding, cellspacing and border attributes since that seems like what you were after in one of your examples.
Also, the Element.first() method returns null if the Elements list is empty. Always check for null when calling that method to prevent NullPointerExceptions.
table.select("td:has(a)").first(); will select the first <tr> element that contains an anchor. It will not select the anchor <a> itself.
here is what you can do:
Element aEl = doc.select("table[cellpadding] td a").first();
Here is the sample HTML Code :
<table width="100%" cellspacing="0" cellpadding="0" border="0">
<tbody>
<tr>
<tr class="tinyfont">
<tr height="2px">
<tr height="1px">
<tr height="1px">
<tr>
<tr height="2px">
<tr height="1px">
<tr height="1px">
<tr height="2px">
</tbody>
</table>
I am using selenium webdriver.
I have received the all the child elements from this code but now I want to exclude one particular child element in logic, how I can exclude one of the child element from my array.
I want to exclude tr[6] child element..
List<WebElement> list = driver.findElements(By.xpath("/html/body/table/tbody //*"));
ArrayList<String> al1 = new ArrayList<String>();
for(WebElement ele:list){
String className = ele.getAttribute("class");
System.out.println("Class name = "+className);
al1.add(className);
}
Thanks in Advance!!
Either omit the 6th table row, then select all descendants:
/html/body/table/tbody/tr[position() != 6]//*
or only select all table rows that are not at position 1 and have an attribute (and then select their descendants):
/html/body/table/tbody/tr[position() = 1 or #*]//*
or to be more specific, also check the attribute name:
/html/body/table/tbody/tr[position() = 1 or #height or #class]//*
Is it always element 6 that you want to avoid? If it is, use a for look with an increment and just avoid element 6 with an if statement.
int numOfElements = driver.findElements(By.xpath("/html/body/table/tbody //*")).count();
ArrayList<String> al1 = new ArrayList<String>();
for(int i = 1; i<= numOfElements; i++)
{
if(i!=6)
{
String className = driver.findElement(By.xpath("/html/body/table/tbody/tr["+i+"]")).getAttribute("class");
System.out.println("Class name = "+className);
al1.add(className);
}
}
This wont sound like a solution that you are looking for, but it still is a round about way to achieve what you want. Off the top of my head, I cant think of another way unless you have a attribute that contains something to compare off of or to exclude