Selenium - How to count the number of rows in a table dynamically? - java

In my html page there's a table with 10 rows; those rows will display based on filter (dynamically). Let's say, for example, without any filters by default 10 row will be returned.
after applying the filter, less than 10 rows will be returned, depending on the type of filter, so i want to get that dynamic count of table rows (after filter) using selenium web driver.
i tried with driver.findElements(By.xpath("abcd")).size() but this is giving default count 10; however, after applying the filter only 2 rows are appearing.
Please suggest how to get dynamic count (count=2 as appearing 2 rows in UI) .

To find the total number of elements on dynamic webpage we need to use driver.findElements().size() method. But sometimes it's not useful at all.
First get the size of all element matching with the row count. Once we have it then you can use dynamic xpath ie replace row and column number run time to get the data.
{
List<WebElement> rows_table = mytable.findElements(By.tagName("tr"));
//To calculate no of rows In table.
int rows_count = rows_table.size();
//Loop will execute till the last row of table.
for (int row=0; row<rows_count; row++){
//To locate columns(cells) of that specific row.
List<WebElement> Columns_row = rows_table.get(row).findElements(By.tagName("td"));
//To calculate no of columns(cells) In that specific row.
int columns_count = Columns_row.size();
System.out.println("Number of cells In Row "+row+" are "+columns_count);
//Loop will execute till the last cell of that specific row.
for (int column=0; column<columns_count; column++){
//To retrieve text from that specific cell.
String celtext = Columns_row.get(column).getText();
System.out.println("Cell Value Of row number "+row+" and column number "+column+" Is "+celtext);
}
System.out.println("--------------------------------------------------");
}

I'll prefix this with the fact that I'm not a Java dev but I use a lot of webdriver in other languages.
The best way to setup tests is to wait for the outcome of the action that your testing. Sometimes you can get away without doing waits, or timed waits, but then you go and run your tests on a slower grid box and everything falls in a heap.
Things like "div exists", "div has class", whatever your outcome may be. In your case, it sounds like you may not be able to test for a div to be rendered but you can probably use your size test as the outcome to wait for.
Selenium can use any ExpectedCondition or you can specify a function
WebDriverWait wait = new WebDriverWait(getDriver(), 5);
wait.until(new ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver driver) {
int elementCount = driver.findElement(By.xpath("xxxx")).size();
if (elementCount == 2)
return true;
else
return false;
}
});
Code from https://sqa.stackexchange.com/a/8701

Related

Iterate through dynamic table in for loop in java

on my project there is dynamically loaded table so each time when we scroll down, table is updating and rowcount starts from 0 or 1 i guess. and i want to iterate through whole table and get specific cell's text from every row. how can i do that? please, help.
what i have done so far is:
List<WebElement> currentGridTableRowsList = driver.findElements(
By.xpath("//table[#role='grid'] //tbody/tr"));
//print current rows count
int currentGridTableRows = currentGridTableRowsList.size();
System.out.println(currentGridTableRows);
for (WebElement row : currentGridTableRowsList){
List<WebElement> tdCollection = row.findElements(By.tagName("td"));
for (WebElement td : tdCollection){
String cellText = td.getText();
System.out.println(cellText);
}
}
currentGridTableRowsList.size() returns current grid number of rows - 10 for example. But attribute aria-rowcount returns 30 rows.
I know there is a snippet
WebElement element = driver.findElement(By.xpath(“//table[#id = ‘tableID’]/tbody//tr[last()]”));
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript(“arguments[0].scrollIntoView();”, element);
but i don't know how to apply that, how to make correct for loops in Java language, so that when it is end of table (current grid), webdriver will scroll and when it is end of table (aria-rowcount) driver will quit. can you please tell me how to write correct for loop for the table and how to get specific cell value, for example td[2] of each row?

How to get a row count for a table that does not display all rows at once?

I have a table that when the page is fully displayed has a row count of 20 rows. However, if there is more than 20, and the user scrolls down additional rows are added. Since it only gets the initial row count, I can never find the element I'm trying to search for.
What I have right now is something along these lines.
boolean isFound = false;
List<WebElement> rowList = webdriver.findElements(By.xpath("//*[contains(#class, 'requestRow')]"));
int rowCount = rowList.size();
String rowNum = null;
for (int i = 1; i <=rowCount+1; i++){
rowNum = Integer.toString(i);
}
Any idea of how I can have the table expanded and capture the new value?
OK, so what I did was create a list based on the current row count.
I then loop through the list incrementing one each time. If the number I'm looking for is found in the table, it does what I need doing. If it gets to a number higher than the current count of rows, I click the load more button, add the new value to my row count, and keep searching.

How to handle webtables in angular using selenium?

I want to automate the webtable in angular. Here's the site- http://demo.automationtesting.in/WebTable.html
I want to capture all the records of all rows. Here what I tried-
List<WebElement> wbt=drv.findElements(By.cssSelector("div[role='rowgroup'][class='ui-grid-viewport ng-isolate-scope']"));
System.out.println("size"+wbt.size());
for(int i=0; i<wbt.size();i++){
System.out.println("values-"+wbt.get(i).getText());
}
But the size coming out is 1.
I also tried with div[class='ui-grid-contents-wrapper'], but with no success.
You selector is pointing to the table div and to the rows. To get table rows you can use .ui-grid-row selector, that will give you table body rows.
List<WebElement> rows = drv.findElements(By.cssSelector(".ui-grid-row"));
for (WebElement row : rows) {
System.out.println("values-" + row.getText());
}
To get each column element by row, you can use .ui-grid-cell-contents selector inside the loop:
List<WebElement> rows = drv.findElements(By.cssSelector(".ui-grid-row"));
for (WebElement row : rows) {
columns = row.findElements(By.cssSelector(".ui-grid-cell-contents"));
columns.forEach(column -> System.out.println(column.getText().trim()));
}
You can learn about selectors here.
Also you may need to wait until some conditions is met, information you can get from: When to use explicit wait vs implicit wait in Selenium Webdriver?

Select a particular value from the data grid that is pulled dynamically

I am trying to find a particular "Incident Number" from the table that is visible in the data grid that is generated dynamically. How can I access this?
Attached is the table view of the page from where I'm trying to see if the Incident number is present in the table or not.
Here is the html code, where I'm trying to access verify if the highlighted Incident number is present in this page or not,
We have to iterate through the data grid rows to find out the Incident Number expected i.e INC000006300863. Once we find out the incident number, we will store the row number and click on the check-box present on the same row. Coding will look like something below:
String xpath_rows = "//div[#class='ngCanvas']//div[contains(#class, 'Row')]";
String expectedIncidentNumber = "INC000006300863";
int numberOfRows = driver.findElements(By.xpath(xpath_rows)).size();
int matchedRow;
// Find out row number for **INC000006300863** incident number
for(int i=1; i<=numberOfRows; i++)
{
if(driver.findElement(By.xpath(xpath_rows +"[" +i +"]//a[contains(text(), 'INC')]")).getText().equals(expectedIncidentNumber))
{
matchedRow = i;
break;
}
}
// Click on the checkbox present on the matched row
driver.findElement(By.xpath(xpath_rows +"[" +i +"]//input[#type='checkbox']")).click();
Hope it helps!

iText formatting tables

I'm generating a PDF document (for those who have seen his before, yes still) using the iText5 library. Compliments to Bruno Lowagie; I've found it to be a really great API!
However, part of my task is to format some phrases. I used a nested PdfPTable to format the data, but I'm getting bizarre spacing issues. Here is an example of the problem I'm facing:
As you can see, rows with only a couple of phrases in them tend to have huge gaps in between them. I can understand why this is happening; the rows above are stretching the table. Is there a way to only make the table as big as it needs to be, and no larger?
Code
Generating the prices collection
I'm creating the prices with this snippet:
Paragraph pricePara = new Paragraph();
pricePara.add(price);
pricePara.add(generateBreakLine());
pricePara.add(time);
pricePara.add(generateBreakLine());
allPrices.add(pricePara);
where generateBreakLine() returns an empty Paragraph object.
Adding them into the cell
I add them into the cell with the following snippet:
// 5 is just the amount of prices we can fit on one line.
PdfPTable pricesCellValue = new PdfPTable(elements.size() > 5 ? 5 : elements.size());
// Make it appear that the prices are just horizontal, as opposed to in a table.
pricesCellValue.getDefaultCell().setBorder(PdfPCell.NO_BORDER);
// Cycle through each price. Add to cell. Add cell to the table.
for (com.lowagie.text.Element elem : elements) {
PdfPCell cell = new PdfPCell((Paragraph) elem);
cell.setBorder(PdfPCell.NO_BORDER);
cell.setPadding(2);
pricesCellValue.addCell(cell);
}
return pricesCellValue;
The above snippet, I believe, is where I can make sure the table is only as wide as it needs to be, as opposed to filling up all the space around it. How would I go about doing that?
Solved
Found a simple way of fixing it. In stead of changing the amount of columns based on the number of prices, I make sure the column number is always 5, and then append empty cells on:
if(elements.size() < 5)
{
int diff = 5 - elements.size();
for(int x = 0; x < diff; x++)
{
pricesCellValue.addCell(new Paragraph(" "));
}
}

Categories