9w. WebDriver – Looping through table elements

Welcome back, Warriors! We just saw how to check if a particular data is present in a table’s specific cell with and without using XPath. Time to loop through each element and visualize the power of Selenium WebDriver. Let us go back to our Demo Site and focus on “Books & Authors” table to understand this concept.

Step 1:

Locate the table “Books & Authors” using its id, ‘BooksAuthorsTable’. The HTML code is as below,

<table id="BooksAuthorsTable" class="table table-bordered">

Code:

WebElement BooksTable = driver.findElement(By.id("BooksAuthorsTable"));

Step 2:

Calculate the total number of rows and columns using XPath.

Let us find the total number of rows using absolute XPath. Note that the XPath ends with the tag name, ‘tr’. The size() method gives the number of elements returned by findElements() using XPath.

Code:

int rowNum = driver.findElements(By.xpath("/html/body/form/div[5]/div/div/table/tbody/tr")).size();

Let us switch gears a bit and find the total number of columns using relative XPath.

Code:

int colNum = driver.findElements(By.xpath("//table[@id='BooksAuthorsTable']/tbody/tr[1]/th")).size();

This method of finding the total number of rows and columns is useful in case of tables whose rows and columns change dynamically.

Step 3:

Looping through table elements

If the table rows and column numbers are fixed, then looping through each table element becomes pretty easy. Two for() loops, one for rows and the other for accessing column values can be used.

Code:

for(int i=2; i<=6; i++){
for(int j=1; j<=4; j++){
	System.out.print(driver.findElement(By.
xpath("//table[@id='BooksAuthorsTable']/tbody/tr[" + i +"]/td[" + j + "]")).getText() + "\t");
	}
	System.out.println("");
}

Someday, if you are lucky, you might stumble across a table that loads dynamically with each page refresh and hence the number of rows usually varies. And therefore, the row count is to be calculated every single time test is executed.

First, let us get all elements with tag name ‘tr’ and put them in a list named ‘rowVals’.

List<WebElement> rowVals = BooksTable.findElements(By.tagName("tr"));

To get the header elements from the first row, find all elements with tag name ‘th’ and put them in a list named ‘colHeader’.

List<WebElement> colHeader = rowVals.get(0).findElements(By.tagName("th"));

To print each header text to console, loop through the header values from colHeader list and use getText() method.

for(int i=0; i<colHeader.size(); i++){
System.out.println(colHeader.get(i).getText());
}

To print table contents to console, loop through the each row. For every row, traverse through each column and print the values using the same getText() method.

for(int i=1; i<rowNum; i++){
List<WebElement> colVals = rowVals.get(i).findElements(By.tagName("td"));
for(int j=0; j<colNum; j++){
		System.out.println(colVals.get(j).getText());
	}
}

Is your ability to focus sliding downhill? If yes, let us look at a BrainBell!

BrainBell – Visualize! Most of us know that creating a mental picture for the concept we wish to remember makes it clearer and easier to remember than words. What we don’t know or do is, visualizing it carefully for a few seconds. This will help to recall it with ease.

With that being said, let us see the overall picture of what we discussed so far!

Scenario

  1. Open Firefox browser
  2. Navigate to the demo site
  3. Locate ‘Books & Authors’ table using id
  4. Get the total number of rows using absolute XPath
  5. Get the total number of columns using relative XPath
  6. Print row and column count to console
  7. Get all row values by tag name ‘tr’
  8. Get the column header values in a list by tag name ‘th’
  9. Loop through the header values and print them to console
  10. Loop through the table contents (all columns for each row) and get its text
  11. Print the values to console
  12. Print the table contents to console using fixed row and column numbers

JUnit code for this scenario is,

package com.blog.junitTests;

import java.util.List;
import java.util.concurrent.TimeUnit;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;

public class LoopingThroughTableElements {
	// Declaring variables
		private WebDriver driver;
		private String baseUrl;

		@Before
		public void setUp() throws Exception {
			// Selenium version 3 beta releases require system property set up
			System.setProperty("webdriver.gecko.driver", "E:\\Softwares\\"Selenium\\geckodriver-v0.10.0-win64\\geckodriver.exe");
			// Create a new instance for the class FirefoxDriver
			// that implements WebDriver interface
			driver = new FirefoxDriver();
			// Implicit wait for 5 seconds
			driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
			// Assign the URL to be invoked to a String variable
			baseUrl = " https://chandanachaitanya.github.io/selenium-practice-site/";
		}

		@Test
		public void testPageTitle() throws Exception {
			// Open baseUrl in Firefox browser window
			driver.get(baseUrl);

			// Locate 'Books & Authors' table using id
			WebElement BooksTable = driver.findElement(By.id("BooksAuthorsTable"));
			//Get all web elements by tag name 'tr'
			List<WebElement> rowVals = BooksTable.findElements(By.tagName("tr"));
			
			//Get number of rows and columns
			//using absoulute xpath
			int rowNum = driver.findElements(By.xpath("/html/body/form/div[5]/div/div/table/tbody/tr")).size();
			//using relative xpath
			int colNum = driver.findElements(By.xpath("//table[@id='BooksAuthorsTable']/tbody/tr[1]/th")).size();
			System.out.println("Total number of rows = " + rowNum);
			System.out.println("Total number of columns = " + colNum);
			
			//Get column header values from first row
			List<WebElement> colHeader = rowVals.get(0).findElements(By.tagName("th"));
			//Loop through the header values and print them to console
			System.out.println("Header values:");
			for(int i=0; i<colHeader.size(); i++){
				System.out.println(colHeader.get(i).getText());
			}
			System.out.println("---------------");
			//Loop through the remaining rows
			for(int i=1; i<rowNum; i++){
				//Get each row's column values by tag name
				List<WebElement> colVals = rowVals.get(i).findElements(By.tagName("td"));
				//Loop through each column
				for(int j=0; j<colNum; j++){
					//Print the coulumn values to console
					System.out.println(colVals.get(j).getText());
				}
				//Just a separator for each row
				System.out.println("---------------");
			}			
			
			//Printing table contents to console for fixed row and column numbers
			for(int i=2; i<=6; i++){
				for(int j=1; j<=4; j++){
					System.out.print(driver.findElement(By.
							xpath("//table[@id='BooksAuthorsTable']/tbody/tr[" + i +"]/td[" + j + "]")).getText() + "\t");
				}
				System.out.println("");
			}
			
		} //End of @Test

		@After
		public void tearDown() throws Exception {
			// Close the Firefox browser
			driver.close();
		}
	}

Execution Result:

Each line of code is well explained as part of concept covered thus far.

Upon noticing eclipse IDE’s JUnit view, green bar shows that the test case is executed successfully.

Table looping eclipse output

Console window shows the absence of any errors. It also shows the printed table contents for both fixed and dynamically calculated row and column count as expected.

Table looping console output

Hope I always give you something to ponder! See you soon in another post.

Have a nice day!

5 Comments

  1. If I want to save the data of the table into a model (i. e. List()), to compare it with an expected value (another list with values), how can I do that?

  2. I am new this Selenium framework and I was in a real need to find a solution, which is posted here. it really helped me very very much in my time of need. I thank you very much for my bottom of my heart.
    Thanks,
    Joshua Jeyaseelan Albert

  3. hi , how to validate the expected table header values with actual table header values , Could you please tell

  4. Using Tagname with tr and td takes much too long with big tables.
    Create the array using javascript and use Javascript injection instead.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.