{{announcement.body}}
{{announcement.title}}

How To Handle Web Table in Selenium WebDriver?

DZone 's Guide to

How To Handle Web Table in Selenium WebDriver?

While performing test automation you'd often come across scenarios where you need to handle web tables. Find out how!

· Performance Zone ·
Free Resource

Web tables or data tables are often used in scenarios where you need to display the information in a tabular format. The data being displayed can either be static or dynamic. You’d often see such examples in e-commerce portals, where product specifications are displayed in a web table. With its wide use, you’d often come across scenarios where you’ll need to handle them in your Selenium test automation scripts. 

In this Selenium WebDriver tutorial, I’ll take a look at how to handle a web table in Selenium along with a few useful operations that can be performed on web tables. By the end of this tutorial, you’ll gain a thorough understanding of web tables in Selenium test automation along with methodologies used to access content in the web table. To know more about What is Selenium, you can refer to our detailed page on the topic. 

Below are the sub-topics covered as a part of this Selenium WebDriver tutorial:

What Is a Web Table in Selenium?

Web table in Selenium is a WebElement just like any other popular WebElements like text boxes, radio buttons, checkboxes, drop-down menus, etc. Web table and its contents can be accessed by using the WebElement functions along with locators to identify the element (row/column) on which the operation needs to be performed.

A table consists of rows and columns. The table created for a web page is called a web table. Below are some of the important tags associated with a web table:

  • < table > – Defines an HTML table

  • < th > – Contains header information in a table

  • < tr > – Defines a row in a table

  • < td > – Defines a column in a table

Types of Web Tables in Selenium

There are two broad categories of tables namely:

Static Web Table 

As the name indicates, the information in the table is static.

Dynamic Web Table

The information displayed in the table is dynamic. E.g. Detailed Product information on e-commerce websites, sales reports, etc.

For the demonstration to handle the table in Selenium, we make use of a table that is available in the w3school HTML table page. Though there are fewer cross-browser testing issues when using tables, some of the old browser versions of Internet Explorer, Chrome, and other web browsers don't support HTML Table APIs.

Now that we’ve covered the basics, next in this Selenium WebDriver tutorial, I’ll take a look at some of the frequently used operations to handle tables in Selenium that would help in your Selenium test automation efforts.

Handling Web Tables in Selenium

I’ll use the local Selenium WebDriver for performing browser actions to handle tables in Selenium, present on w3schools HTML table page. The HTML code for the web table used for demonstration is available on the tryit adapter page.

web tables

The Selenium WebDriver for popular browsers can be downloaded from the locations mentioned below:

I’ll use the Python unit test framework to handle tables in Selenium WebDriver. The core logic for accessing elements in web tables remains the same even if you are using other programming languages for Selenium test automation.

Note – Implementation in the setUp() and teardown() remains the same for all the scenarios. We would not repeat that section in every example being shown in the blog.

Handling Number Of Rows and Columns In Web Table

The < tr > tag in the table indicates the rows in the table and that tag is used to get information about the number of rows in it. Number of columns of the web table in Selenium are calculated using XPath (//*[@id=’customers’]/tbody/tr[2]/td). XPath of the rows and columns are obtained using the inspect tool in the browser to handle tables in Selenium for automated browser testing.

html table example

Though the header in a web table does not the the < th > tag could still be used in the current example to calculate the number of columns. The XPath for computing the number of columns using < th > tag is //*[@id=’customers’]/tbody/tr/th

A WebDriverWait of 30 seconds is added to ensure that the loading of the Web Table (CLASS_NAME = w3-example) is complete before any operations are performed to handle the table in Selenium.

Get number of rows for a web table in Selenium

num_rows = len (driver.find_elements_by_xpath

("//*[@id='customers']/tbody/tr")) 

Get number of columns for a web table in Selenium

num_cols = len (driver.find_elements_by_xpath

("//*[@id='customers']/tbody/tr[2]/td")) 

Complete Implementation

Python
 




xxxxxxxxxx
1
50


 
1
 
           
2
import unittest
3
import time
4
from selenium import webdriver
5
from selenium.webdriver.support.select import Select
6
from selenium.webdriver.common.by import By
7
from selenium.webdriver.support.ui import WebDriverWait
8
from selenium.webdriver.support import expected_conditions as EC
9
 
           
10
 
           
11
test_url = "https://www.w3schools.com/html/html_tables.asp"
12
 
           
13
 
           
14
class WebTableTest(unittest.TestCase):
15
 
           
16
 
           
17
   def setUp(self):
18
       self.driver = webdriver.Chrome()
19
       self.driver.maximize_window()
20
 
           
21
 
           
22
   def test_1_get_num_rows_(self):
23
       driver = self.driver
24
       driver.get(test_url)
25
      
26
       WebDriverWait(driver, 60).until(EC.presence_of_element_located((By.CLASS_NAME, "w3-example")))
27
 
           
28
 
           
29
       num_rows = len (driver.find_elements_by_xpath("//*[@id='customers']/tbody/tr"))
30
       print("Rows in table are " + repr(num_rows))
31
 
           
32
 
           
33
   def test_2_get_num_cols_(self):
34
       driver = self.driver
35
       driver.get(test_url)
36
      
37
       WebDriverWait(driver, 60).until(EC.presence_of_element_located((By.CLASS_NAME, "w3-example")))
38
       # num_cols = len (driver.find_elements_by_xpath("//*[@id='customers']/tbody/tr/th"))
39
       num_cols = len (driver.find_elements_by_xpath("//*[@id='customers']/tbody/tr[2]/td"))
40
       print("Columns in table are " + repr(num_cols))
41
 
           
42
 
           
43
   def tearDown(self):
44
       self.driver.close()
45
       self.driver.quit()
46
 
           
47
 
           
48
if __name__ == "__main__":
49
   unittest.main()
50
 
           



Below is the output snapshot.

output snapshot

Print Content Of The Web Table In Selenium

To access the content present in every row and column to handle the table in Selenium, we iterate every row (< tr >) in the web table. Once the details about the rows are obtained, we iterate the < td > tags under that row.

In this case for this Selenium WebDriver tutorial, both the rows (< tr >) and columns (< td >) would be variable. Hence, the row numbers and column numbers are computed dynamically. Shown below is the XPath for accessing information in specific rows and columns:

  • XPath to access Row : 2, Column : 2 – //*[@id=”customers”]/tbody/tr[2]/td[1]

  • XPath to access Row : 3, Column : 1 – //*[@id=”customers”]/tbody/tr[3]/td[1]

The table on which Selenium test automation is being performed has 7 rows and 3 columns. Hence, a nested for loop is executed with rows ranging from 2..7 and columns ranging from 1..4. The variables factors i.e. row number and column number are added to formulate the final XPath.

Python
 




xxxxxxxxxx
1
10
9


1
for t_row in range(2, (rows + 1)):
2
  for t_column in range(1, (columns + 1)):
3
      FinalXPath = before_XPath + str(t_row) + aftertd_XPath + str(t_column) + aftertr_XPath
4
      cell_text = driver.find_element_by_xpath(FinalXPath).text
5
 
           



Shown below in this Selenium WebDriver tutorial, is the complete implementation to get all the contents present to handle the table in Selenium.

Python
 




xxxxxxxxxx
1
35


 
1
 
           
2
import unittest
3
import time
4
test_url = "https://www.w3schools.com/html/html_tables.asp"
5
 
           
6
 
           
7
before_XPath = "//*[@id='customers']/tbody/tr["
8
aftertd_XPath = "]/td["
9
aftertr_XPath = "]"
10
 
           
11
 
           
12
   def test_get_row_col_info_(self):
13
       driver = self.driver
14
       driver.get(test_url)
15
      
16
       # time.sleep(30)
17
       WebDriverWait(driver, 60).until(EC.presence_of_element_located((By.CLASS_NAME, "w3-example")))
18
 
           
19
 
           
20
       rows = len(driver.find_elements_by_xpath("//*[@id='customers']/tbody/tr"))
21
       # print (rows)
22
       columns = len(driver.find_elements_by_xpath("//*[@id='customers']/tbody/tr[2]/td"))
23
       # print(columns)
24
      
25
       # print("Company"+"               "+"Contact"+"               "+"Country")
26
 
           
27
 
           
28
       for t_row in range(2, (rows + 1)):
29
           for t_column in range(1, (columns + 1)):
30
               FinalXPath = before_XPath + str(t_row) + aftertd_XPath + str(t_column) + aftertr_XPath
31
               cell_text = driver.find_element_by_xpath(FinalXPath).text
32
               # print(cell_text, end = '               ')
33
               print(cell_text)
34
           print()  
35
 
           



The output snapshot to print content to handle table in Selenium is below:

selenium table

Read Data In Rows To Handle Table In Selenium

For accessing the content present in every row, to handle table in Selenium, the rows (< tr >) are variable whereas the columns (< td >) would remain constant. Hence, the rows are computed dynamically. Below in this Selenium WebDriver tutorial is the XPath for accessing information with rows being the variable factor and columns remaining constant for Selenium test automation.

  • XPath to access Row : 1, Column : 1 – //*[@id=”customers”]/tbody/tr[1]/td[1]

  • XPath to access Row : 2, Column : 2 – //*[@id=”customers”]/tbody/tr[2]/td[2]

  • XPath to access Row : 3, Column : 2 – //*[@id=”customers”]/tbody/tr[3]/td[2]

A for loop is executed with rows ranging from 2..7. The column values are appended to the XPath are td[1]/td[2]/td[3] depending on the row & column that has to be accessed to handle the table in Selenium.

Python
 




xxxxxxxxxx
1
19
9


 
1
before_XPath = "//*[@id='customers']/tbody/tr["
2
aftertd_XPath_1 = "]/td[1]"
3
aftertd_XPath_2 = "]/td[2]"
4
aftertd_XPath_3 = "]/td[3]"
5
for t_row in range(2, (rows + 1)):
6
    FinalXPath = before_XPath + str(t_row) + aftertd_XPath_1
7
    cell_text = driver.find_element_by_xpath(FinalXPath).text
8
    print(cell_text)
9
 
           



Complete Implementation

Python
 




xxxxxxxxxx
1
58


 
1
 
           
2
#Selenium webdriver tutorial  to handletable in Selenium for Selenium test automation
3
import unittest
4
import time
5
from selenium import webdriver
6
from selenium.webdriver.support.select import Select
7
from selenium.webdriver.common.by import By
8
from selenium.webdriver.support.ui import WebDriverWait
9
from selenium.webdriver.support import expected_conditions as EC
10
 
           
11
 
           
12
test_url = "https://www.w3schools.com/html/html_tables.asp"
13
 
           
14
 
           
15
before_XPath = "//*[@id='customers']/tbody/tr["
16
aftertd_XPath_1 = "]/td[1]"
17
aftertd_XPath_2 = "]/td[2]"
18
aftertd_XPath_3 = "]/td[3]"
19
#aftertr_XPath = "]"
20
 
           
21
 
           
22
   def test_get_row_col_info_(self):
23
       driver = self.driver
24
       driver.get(test_url)
25
      
26
       # time.sleep(30)
27
       WebDriverWait(driver, 60).until(EC.presence_of_element_located((By.CLASS_NAME, "w3-example")))
28
 
           
29
 
           
30
       rows = len(driver.find_elements_by_xpath("//*[@id='customers']/tbody/tr"))
31
       # print (rows)
32
       columns = len(driver.find_elements_by_xpath("//*[@id='customers']/tbody/tr[2]/td"))
33
       # print(columns)
34
 
           
35
 
           
36
       print("Data present in Rows, Col - 1")
37
       print()
38
       for t_row in range(2, (rows + 1)):
39
           FinalXPath = before_XPath + str(t_row) + aftertd_XPath_1
40
           cell_text = driver.find_element_by_xpath(FinalXPath).text
41
           print(cell_text)
42
      
43
       print()   
44
       print("Data present in Rows, Col - 2")
45
       print()
46
       for t_row in range(2, (rows + 1)):
47
           FinalXPath = before_XPath + str(t_row) + aftertd_XPath_2
48
           cell_text = driver.find_element_by_xpath(FinalXPath).text
49
           print(cell_text)
50
          
51
       print()
52
       print("Data present in Rows, Col - 3")
53
       print()
54
       for t_row in range(2, (rows + 1)):
55
           FinalXPath = before_XPath + str(t_row) + aftertd_XPath_3
56
           cell_text = driver.find_element_by_xpath(FinalXPath).text
57
           print(cell_text)
58
 
           



The output snapshot to read data in rows to handle table in Selenium is below:

selenium

Read Data In Columns To Handle Table In Selenium

For column-wise access to handle table in Selenium, the rows remain constant whereas the column numbers are variable i.e. the columns are computed dynamically. Below in this Selenium WebDriver Tutorial is the XPath for accessing information where columns are variable and rows are constant.

  • XPath to access Row : 2, Column : 2 – //*[@id=”customers”]/tbody/tr[2]/td[2]

  • XPath to access Row : 2, Column : 3 – //*[@id=”customers”]/tbody/tr[2]/td[3]

  • XPath to access Row : 2, Column : 4 – //*[@id=”customers”]/tbody/tr[2]/td[4]

A for loop is executed with columns ranging from 1 to 4 The row values are appended to the XPath are tr[1]/tr[2]/tr[3] depending on the row and column that has to be accessed.

Python
 




xxxxxxxxxx
1


 
1
before_XPath_1 = "//*[@id='customers']/tbody/tr[1]/th["
2
before_XPath_2 = "//*[@id='customers']/tbody/tr[2]/td["
3
after_XPath = "]"
4
for t_col in range(1, (num_columns + 1)):
5
   FinalXPath = before_XPath_1 + str(t_col) + after_XPath
6
   cell_text = driver.find_element_by_xpath(FinalXPath).text
7
   print(cell_text)
8
 
           



Complete Implementation

Python
 




xxxxxxxxxx
1
46


 
1
 
           
2
import unittest
3
import time
4
from selenium import webdriver
5
from selenium.webdriver.support.select import Select
6
from selenium.webdriver.common.by import By
7
from selenium.webdriver.support.ui import WebDriverWait
8
from selenium.webdriver.support import expected_conditions as EC
9
 
           
10
 
           
11
test_url = "https://www.w3schools.com/html/html_tables.asp"
12
 
           
13
 
           
14
before_XPath_1 = "//*[@id='customers']/tbody/tr[1]/th["
15
before_XPath_2 = "//*[@id='customers']/tbody/tr[2]/td["
16
after_XPath = "]"
17
 
           
18
 
           
19
def test_get_row_col_info_(self):
20
       driver = self.driver
21
       driver.get(test_url)
22
      
23
       # time.sleep(30)
24
       WebDriverWait(driver, 60).until(EC.presence_of_element_located((By.CLASS_NAME, "w3-example")))
25
 
           
26
 
           
27
       num_rows = len(driver.find_elements_by_xpath("//*[@id='customers']/tbody/tr"))
28
       # print (rows)
29
       num_columns = len(driver.find_elements_by_xpath("//*[@id='customers']/tbody/tr[2]/td"))
30
       # print(columns)
31
 
           
32
 
           
33
       print("Data present in Col - 1 i.e. Title")
34
       print()
35
       for t_col in range(1, (num_columns + 1)):
36
           FinalXPath = before_XPath_1 + str(t_col) + after_XPath
37
           cell_text = driver.find_element_by_xpath(FinalXPath).text
38
           print(cell_text)
39
          
40
       print("Data present in Col - 2")
41
       print()
42
       for t_col in range(1, (num_columns + 1)):
43
           FinalXPath = before_XPath_2 + str(t_col) + after_XPath
44
           cell_text = driver.find_element_by_xpath(FinalXPath).text
45
           print(cell_text)
46
 
           



As seen in the execution snapshot, the header column is also read to fetch the title of the columns.

execution snapshot

Locating An Element To Handle Table In Selenium

The intention of this test for this Selenium WebDriver tutorial is to look for the presence of an element in the web table. For doing the same, content in every cell of the web table is read and compared with the search term. If the element is present, the corresponding row and element are printed to handle the table in Selenium.

As it involves reading the data in every cell, we make use of the logic covered in the section titled Print content of the web table in Selenium. A case insensitive search is performed to validate the presence of the search term to handle the table in Selenium.

Python
 




xxxxxxxxxx
1


 
1
for t_row in range(2, (num_rows + 1)):
2
  for t_column in range(1, (num_columns + 1)):
3
      FinalXPath = before_XPath + str(t_row) + aftertd_XPath + str(t_column) + aftertr_XPath
4
      cell_text = driver.find_element_by_xpath(FinalXPath).text
5
      if ((cell_text.casefold()) == (search_text.casefold())):
6
        print("Search Text "+ search_text +" is present at row " + str(t_row) + " and column " + str(t_column))
7
        elem_found = True
8
        break



Complete Implementation

Python
 




xxxxxxxxxx
1
46


 
1
 
           
2
import unittest
3
import time
4
from selenium import webdriver
5
from selenium.webdriver.support.select import Select
6
from selenium.webdriver.common.by import By
7
from selenium.webdriver.support.ui import WebDriverWait
8
from selenium.webdriver.support import expected_conditions as EC
9
 
           
10
 
           
11
test_url = "https://www.w3schools.com/html/html_tables.asp"
12
 
           
13
 
           
14
before_XPath_1 = "//*[@id='customers']/tbody/tr[1]/th["
15
before_XPath_2 = "//*[@id='customers']/tbody/tr[2]/td["
16
after_XPath = "]"
17
 
           
18
 
           
19
search_text = "mAgazzini Alimentari rIUniti"
20
 
           
21
 
           
22
   def test_get_row_col_info_(self):
23
       driver = self.driver
24
       driver.get(test_url)
25
      
26
       # time.sleep(30)
27
       WebDriverWait(driver, 60).until(EC.presence_of_element_located((By.CLASS_NAME, "w3-example")))
28
 
           
29
 
           
30
       num_rows = len(driver.find_elements_by_xpath("//*[@id='customers']/tbody/tr"))
31
       num_columns = len (driver.find_elements_by_xpath("//*[@id='customers']/tbody/tr[2]/td"))
32
      
33
       elem_found = False
34
 
           
35
 
           
36
       for t_row in range(2, (num_rows + 1)):
37
           for t_column in range(1, (num_columns + 1)):
38
               FinalXPath = before_XPath + str(t_row) + aftertd_XPath + str(t_column) + aftertr_XPath
39
               cell_text = driver.find_element_by_xpath(FinalXPath).text
40
               if ((cell_text.casefold()) == (search_text.casefold())):
41
                   print("Search Text "+ search_text +" is present at row " + str(t_row) + " and column " + str(t_column))
42
                   elem_found = True
43
                   break
44
       if (elem_found == False):
45
           print("Search Text "+ search_text +" not found")
46
 
           



As seen in the execution snapshot for this Selenium WebDriver tutorial, the search term was present at row-7 and column-1.

python

Though many such operations can be carried out on a web table in Selenium, we have covered the core aspects of this Selenium WebDriver tutorial.

All In All

Web tables are commonly used when information has to be displayed in tabular format. The information in the cells can be static or dynamic. Web tables in Selenium are tested using WebElement APIs along with usage of appropriate locators like XPath, CSS class name, CSS ID, etc.

I hope you liked this Selenium WebDriver tutorial to handle the table in Selenium. Do leave your thoughts on using web tables in Selenium test automation in the comments section down below. Feel free to share it with your peers. Till then. 

Happy Testing!

Topics:
automation testing, performance, selenium, selenium automated testing, selenium automation, tutorial, webdriver io

Published at DZone with permission of Himanshu Sheth . See the original article here.

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}