Count Of Hidden Rows in WebTable By Using Selenium - selenium-webdriver

I have a hide button in the application that hides duplicate data entries on web table. I have been trying to capture the number of hidden rows. See html and my approaches below. Every attempt I have tried ended up with 0. However, the result should be 2.
HTML CODE:
<tbody>
<tr role = "row" class="odd">...<tr/>
<tr role = "row" class="even">...<tr/>
<tr role = "row" class="odd">...<tr/>
<tr role = "row" class="even">...<tr/>
<tr role = "row" class="odd">...<tr/>
<tr role = "row" class="odd duplicate" style="display: none;" >...<tr/>
<tr role = "row" class="even duplicate" style="display: none;" >...<tr/>
</tbody>
def getInvisibleTableRowCount()
{
WebDriver driver = DriverFactory.getWebDriver()
WebElement table = driver.findElement(By.xpath("//*[#id='DataTables_Table_0']/tbody"))
List<WebElement> rows_table= table.findElements(By.cssSelector("[display=none]"));
int rowSize = rows_table.size();
return rowSize;
}
Here is my other attempt:
def getInvisibleTableRowCount()
{
WebDriver driver = DriverFactory.getWebDriver()
WebElement table = driver.findElement(By.xpath("//*[#id='DataTables_Table_0']/tbody"))
List<WebElement> rows_table= table.findElements(By.tagName("tr[not(contains(#style,'display: none;'))]"));
int rowSize = rows_table.size();
return rowSize;
}
If I ran the xpath as //*[#id='DataTables_Table_0']/tbody/tr[not(contains(#style,'display: none;'))] , I can find the hidden rows on the browser.
I have also tried this:
def getInvisibleTableRowCount()
{
WebDriver driver = DriverFactory.getWebDriver()
WebElement table = driver.findElement(By.xpath("//*[#id='DataTables_Table_0']/tbody"))
List<WebElement> rows_table= table.findElements(By.tagName("tr"));
int rowSize = rows_table.size();
for(WebElement row: rows_table)
{
if(row.isDisplayed()==false)
{
rowSize = rowSize -1;
}
}
return rowSize;
}
After #Hac's comment, I tried JQuery. I ran the jQuery on browser, it works with no problem. But I get a "NULL" value returned in my function. I double checked the jQuery string that prompts correct in the comment line.
#Keyword
def getTableRowCountAfterHiding()
{
def jQuery='$'+'("#DataTables_Table_0 tbody tr:visible").length'
WebUI.comment(jQuery);
def visibleRowCounts = new utils.ExecuteJavaScript().executeJavaScript(jQuery);
return visibleRowCounts;
}
I defined utils to run JS as it is in below:
public class ExecuteJavaScript {
//This keyword is designed to execute JS.
#Keyword
def executeJavaScript(String javascript) {
((JavascriptExecutor) DriverFactory.getWebDriver()).executeScript(javascript)
}
}

This worked:
def getTableRowCountAfterHiding()
{
WebDriver driver = DriverFactory.getWebDriver()
List<WebElement> table = driver.findElements(By.xpath("//*[#id='DataTables_Table_0']/tbody/tr[not(contains(#style,'display: none;'))]"))
int rowSize = table.size();
return rowSize;
}

Related

How to print some text side by side using Selenium?

I have to print the hotel name and price side by side
example: oyo Rooms - 2000rs
I tried to use the Selenium web driver.
WebDriver driver = new ChromeDriver();
String baseUrl = "https:www.teletextholidays.co.uk";
driver.get(baseUrl);
driver.manage().window().maximize();
WebElement all_Inclusive = driver.findElement(By.xpath("//*[#class='header pstn-fxd edge txt-center fixed-nav-container']//div[#class='show-on-desktop inblock']//a[#class='top-nav-allinclusive nav-item txt-white inblock hover-out allinclusivelink']"));
all_Inclusive.click(); WebElement all_hotels =driver.findElement(By.xpath("//*[#class='lg-flex-box']"));
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("arguments[0].scrollIntoView();", all_hotels);
List<WebElement> hotellist = driver.findElements(By.xpath("//*[#class='deal-price pstn-reltv grid-stay items-center space-between']//span[#class='dstn-name txt-bold']"));
System.out.println(hotellist.get);
List<WebElement> pricelist = driver.findElements(By.xpath("//*[#class='deal-price pstn-reltv grid-stay items-center space-between']//span[#class='tth-price font-bold txt-sunset']" ));
/*for (WebElement hotel : hotellist) {
System.out.println(hotel.getText());
}*/
for (WebElement price : pricelist) {
System.out.println(price.getText());
if(price.getText().contains("157")) {
System.out.println(hotel);
}
}
Expected output: Oyo - 1000, alpha - 2345.
What am I doing wrongly?
We need to fetch parent elements first and then find hotel and price from that elements to keep co-relation b/w them.
Try the following code to print hotel - price format.
List<WebElement> listOfLinks = driver.findElements(By.cssSelector("a>div.deal-price"));
for(WebElement link: listOfLinks) {
System.out.print(link.findElement(By.cssSelector(".from-price>.dstn-name")).getText());
System.out.print(" - ");
System.out.println(link.findElement(By.cssSelector(".txt-right .tth-price")).getText());
}

Search for a value in a table and click corresponding link in another column of same table

I want to search for a particular value in a table and click the corresponding link in another column in the same row, The following is the code i wrote.I got table values of the cell content now i need to search and click the link
package checking;
import java.util.List;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.remote.RemoteWebDriver;
public class TableCorrespondingValueClick {
public static void main(String[] args) {
RemoteWebDriver driver;
//driver = new FirefoxDriver();
System.setProperty("webdriver.chrome.driver", "./drivers/chromedriver.exe");
driver = new ChromeDriver();
driver.manage().window().maximize();
driver.get("http://toolsqa.com/automation-practice-table");
String Searchvalue = "Taiwan";
List<WebElement> heading = driver.findElements(By.xpath(".//*[#id='content']/table/tbody/tr/th"));
List<WebElement> row = driver.findElements(By.xpath(".//*[#id='content']/table/tbody/tr"));
List<WebElement> cell = driver.findElements(By.xpath(".//*[#id='content']/table/tbody/tr/td"));
int rowcount = row.size();
int cellcount = cell.size();
System.out.println("No.of Rows in the Table : "+rowcount);
System.out.println("No.of Cells in the Table : "+cellcount);
for (WebElement c : cell) {
String cellvalue = c.getText();
System.out.println("Cell Values : "+cellvalue);
if (cellvalue.equalsIgnoreCase(Searchvalue)) {
System.out.println("Found");
}
}
driver.quit();
}
}
Can anyone suggest me the solution for this scenario
HTML source
<table class="tsc_table_s13" style="width: 100%;" summary="Sample Table" border="1">
<caption><strong>Sample Table</strong></caption>
<thead>
<tr>
<th style="text-align: justify;" scope="col">Structure</th>
<th scope="col">Country</th>
<th scope="col">City</th>
<th scope="col">Height</th>
<th scope="col">Built</th>
<th scope="col">Rank</th>
<th scope="col">…</th>
</tr>
</thead>
<tfoot>
<tr>
<th scope="row">Total</th>
<td colspan="7">4 buildings</td>
</tr>
</tfoot>
<tbody>
<tr>
<th scope="row">Burj Khalifa</th>
<td>UAE</td>
<td>Dubai</td>
<td>829m</td>
<td>2010</td>
<td>1</td>
<td>details</td>
</tr>
<tr class="odd">
<th scope="row">Clock Tower Hotel</th>
<td>Saudi Arabia</td>
<td>Mecca</td>
<td>601m</td>
<td>2012</td>
<td>2</td>
<td>details</td>
</tr>
<tr>
<th scope="row">Taipei 101</th>
<td>Taiwan</td>
<td>Taipei</td>
<td>509m</td>
<td>2004</td>
<td>3</td>
<td>details</td>
</tr>
<tr class="odd">
<th scope="row">Financial Center</th>
<td>China</td>
<td>Shanghai</td>
<td>492m</td>
<td>2008</td>
<td>4</td>
<td>details</td>
</tr>
</tbody>
</table>
Please do it like below
public class workingwithTable {
public static void main(String[] args) {
WebDriver driver = new FirefoxDriver();
driver.get("file:///C:/Users/rajnish/Desktop/Table.html");
driver.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS);
List<WebElement> allvalue = driver.findElements(By.xpath("//*[#class='tsc_table_s13']/tbody/tr"));
// for printing everything in the table
for(int i =0;i<allvalue.size();i++){
System.out.println("Value are : " + allvalue.get(i).getText());
}
// for printing a particular column rows
List<WebElement> allCountrymvalue = driver.findElements(By.xpath("//*[#class='tsc_table_s13']/tbody/tr/td[1]"));
for(int i =0;i<allCountrymvalue.size();i++){
System.out.println("Value are : " + allCountrymvalue.get(i).getText());
}
// for printing all links do it like belwo
List<WebElement> alllinks = driver.findElements(By.xpath("//*[#class='tsc_table_s13']/tbody/tr/td[6]/a"));
for(int i =0;i<alllinks.size();i++){
System.out.println("Link is : " + alllinks.get(i).getText());
}
// Now please note that inside the web-table all column and rows are fixed
// i.e size of each row for each column will be fixed
// i.e if size for Country is = 4 then ,size for City ,height ,build,rank
// and for link will be same i.e =4
// hence on that basic we can do it like below
String MyCountryVal = "Taiwan";
for(int i =0;i<allCountrymvalue.size();i++){
System.out.println("Value are : " + allCountrymvalue.get(i).getText() + "== Corresponding link is : " + alllinks.get(i).getText());
// now on the basis of column value click the corresponding link
if(allCountrymvalue.get(i).getText().equals(MyCountryVal)){
alllinks.get(i).click();
break;
}
}
}
}
try like below:
driver.manage().window().maximize();
driver.get("http://toolsqa.com/automation-practice-table");
Thread.sleep(4000);
String Searchvalue = "Taiwan";
//get name and details link element.
List<WebElement> countryname = driver.findElements(By.cssSelector("tbody>tr>th+td"));
List<WebElement> link = driver.findElements(By.cssSelector("tbody>tr>td>a"));
System.out.println("No.of Rows in the Table : "+countryname.size());
System.out.println("No.of link in the Table : "+link.size());
for (int i =0; i<countryname.size();i++) {
String country = countryname.get(i).getText();
System.out.println("country Values : "+country);
if (country.equalsIgnoreCase(Searchvalue)) {
System.out.println("Found");
link.get(i).click();
break;
}
}

How to skip the locator which does not exist in selenium webdriver?

I have around 50 rows in a page. But those items are in sequence.
The problem is when someone entered and deleted that table row. That id would not be there in page..
Example:
User added 1st record: id 101 added.
User added 2nd record: id 102 added
User added 3rd record: id 103 added.
If user deletes 2nd record, then two records would be there on the page but with id 101, 103.
I am trying to write that if that id is present then get the text else leave that in the for loop. I am getting only records till it found if that id is not found getting NoSuchElementException is displayed.
Please correct the code. But i want to the solution that if that id not exist, skip and run the else part.
for (int i = counterstart; i <= counterend; i++) {
if(driver.findElement(By.xpath("//*[#id='" + i + "']/a")).isDisplayed()){
System.out.println(i+" is present");
String Projects = driver.findElement(By.xpath("//*[#id='" + i + "']/a")).getText();
System.out.println(Projects);
} else{
System.out.println(i+" is NOT present");
}
}
The exception that I get:
Exception in thread "main" org.openqa.selenium.NoSuchElementException: Unable to find element with xpath == //*[#id='7593']/a (WARNING: The server did not provide any stacktrace information)
Command duration or timeout: 503 milliseconds
Try this method isPresent instead of isDisplayed.
public boolean isPresent(WebElement e) {
boolean flag = true;
try {
e.isDisplayed();
flag = true;
}
catch (Exception e) {
flag = false;
}
return flag;
}
How about this:
for (int i = counterstart; i <= counterend; i++) {
WebElement element;
try{
element = driver.findElement(By.xpath("//*[#id='" + i + "']/a"));
}catch(NoSuchElementException n)
{
element = null;
}
if(element !=null){
System.out.println(i+" is present");
String Projects = driver.findElement(By.xpath("//*[#id='" + i + "']/a")).getText();
System.out.println(Projects);
}else{
System.out.println(i+" is NOT present");
}
}
Find all the parent of all the elements you want to get the text from and use it to drill down, this way you won't get the exception
Assuming the html looks like this
<div id="parent">
<div id="11">
<a>text</a>
</div>
<div id="12">
<a>text</a>
</div>
<div id="13">
<a>text</a>
</div>
</div>
You can do this
// get all the elements with id
List<WebElement> ids = driver.findElements(By.cssSelector("#parent > div"));
// get all the texts using the id elements
for (WebElement id :ids) {
String projects = id.findElement(By.tagName("a")).getText();
System.out.println(projects);
}

send array of data from POJO to JSP

I had a problem on printing array of data in JSP, heres what happend.
I created a POJO called: popArayCustOrd
public class popAryCustOrd {
public String prodkey,descrp,strgth,stkunt;
double rprice;
int quantity;
popAryCustOrd(String prodkey,String descrp,int quantity,Double rprice,String stkunt,String strgth){
this.prodkey = prodkey;
this.descrp = descrp;
this.quantity = quantity;
this.rprice = rprice;
this.stkunt = stkunt;
this.strgth = strgth;
}
public void setProdkey(String prodkey){
this.prodkey = prodkey;
}
public String getProdkey(){
return(this.prodkey);
}
public void setDescrp(String descrp){
this.descrp = descrp;
}
public String getDescrp(){
return(this.descrp);
}
public void setQuantity(int quantity){
this.quantity = quantity;
}
public int getQuantity(){
return(this.quantity);
}
public void setRprice(double rprice){
this.rprice = rprice;
}
public double getRprice(){
return(this.rprice);
}
public void setStkunt(String stkunt){
this.stkunt = stkunt;
}
public String getStkunt(){
return(this.stkunt);
}
public void setStrgth(String strgth){
this.strgth = strgth;
}
public String getStrgth(){
return(this.strgth);
}
}
and in my servlet file called seekprod.java I assigned data coming from the database within a method....
connx.rs.beforeFirst();
while(connx.rs.next()){
popAryCustOrd[] prodList = new popAryCustOrd[]{new popAryCustOrd(connx.rs.getString("prodkey"),connx.rs.getString("descrp"),connx.rs.getInt("quantity"),connx.rs.getDouble("retailp"),connx.rs.getString("stkunit"),connx.rs.getString("strength"))};
request.setAttribute("prodList", prodList);
}
RequestDispatcher dispatcher = request.getRequestDispatcher("preOrdFrm.jsp? inKey="+this.inKey+"&transkey=drugs");
dispatcher.forward(request, response);
.......
and my JSP to access the data is.....
<c:forEach items="${prodList}" var="paramx" >
<tr>
<td>${paramx.prodkey}</td>
<td style="text-align: center; word-wrap: break-word; word-break:break-all; text-overflow: ellipsis;overflow:hidden;white-space: normal; white-space: -webkit-pre-wrap;">${paramx.descrp}</td>
<td>${paramx.stkunt}</td>
<td>${paramx.strgth}</td>
<td>${paramx.rprice}</td>
<td>${paramx.quantity}</td>
<td><input type="hidden" name="agentId" value="<%=uID %>">
<input type="hidden" name="pcode" value=${paramx.prodkey}>
<input type="hidden" name="inKey" value=${param.inKey}>
<input type="hidden" name="transKey" value="sveOrd">
<input style="font-size:50px; height:55px; width:100px" type="number" name="desqty" min="1" required="" value="1"/></td>
<td><input style="font-size:20px; height:55px; width:100px" type="submit" name="transact" value="Save"/></td>
</tr>
</c:forEach>
eventually it works but I got only one result instead of three records from the database table, my syntax in sql is correct and i checked it many times and compared with the result. I dont know where part of my code to fix. Im very much glad if you could help me .?
while(connx.rs.next()){
popAryCustOrd[] prodList = new popAryCustOrd[]{new
popAryCustOrd(connx.rs.getString("prodkey"),connx.rs.getString("descrp"),connx.rs.getInt("quantity"),connx.rs.getDouble("retailp"),connx.rs.getString("stkunit"),connx.rs.getString("strength"))};
request.setAttribute("prodList", prodList);
}
think about this code it sets and then resets prodList attribute in the request object with every loop execution, so your jsp will recieve only the last value set to prodList.
It would be better to initialize an ArrayList outside the loop and add values to it and then after the loop use that list to set the attribute prodList in request object.

ASP.Net table data link

public string GetMemberMessages(string ClubId, string acctno)
{
var data = "";
List<Hashtable> StartList = new List<Hashtable>();
string Conn = GetClubConnectionstring(ClubId);
if (Conn != "Invalid Connection")
{
Sconn = new SqlConnection(Conn);
string lsql ="select * from table where acctno='" + no + "' and datecompl is null order by entrydate desc";
Getdataset(lsql, "tblnotes", ds, ref da, Sconn);
if (ds.Tables["tblnotes"] != null && ds.Tables["tblnotes"].Rows.Count > 0)
{
for (int i = 0; i < ds.Tables["tblnotes"].Rows.Count; i++)
{
Hashtable hashtable = new Hashtable();
for (int j = 0; j < ds.Tables["tblnotes"].Columns.Count; j++)
{
hashtable[ds.Tables["tblnotes"].Columns[j].ToString()] = ds.Tables["tblnotes"].Rows[i][j].ToString();
}
StartList.Add(hashtable);
}
return js.Serialize(StartList);
}
else
{
data = null;
}
}
return js.Serialize(data);
}
<div data-bind="foreach: $root.dataSource">
<table > <tr>
<td>
<span data-bind=" text:notes"</span>>
</td>
</tr>
</table>
</div>
I have MSSQL table, in a field i had insert my messages (ex:Have a good day) with external website linkGoogle.
while i bind the data in my html table like this (have a good day www.google.com) values are shows into view, it working fine. but while i click on that external web linkGoogle. it doesn't navigate google page.
I had tried in SQL server with Html different type to link tags, what are that tag i had put into database, those tag also get visible alone with message and link.

Resources