Popular Searches
Popular Course Categories
Popular Courses

Web Tables

Dropdowns & Advanced Elements

Web Tables in Selenium WebDriver

Web Tables are one of the most common components found in modern web applications. They are used to display structured information such as employee records, customer details, product lists, order information, transaction history, student records, reports, and dashboard data. In Selenium WebDriver automation, testers frequently need to read table data, validate rows and columns, identify a particular record, click buttons inside a row, select checkboxes, edit or delete records, and handle tables that change dynamically.

Selenium WebDriver provides powerful methods such as findElement() and findElements() that can be combined with XPath, CSS selectors, WebElement methods, loops, conditions, and explicit waits to automate web tables effectively.

Selenium Training Resources: Selenium Training Course | Register for Course Demo


1. What is a Web Table?

A Web Table is an HTML element used to represent structured data in rows and columns. A typical HTML table consists of a table container, rows, headers, and individual data cells.

For example, an employee table may contain Employee ID, Name, Department, Salary, Status, and Actions columns.

2. Why Web Tables are Important in Selenium

Web tables are important because many business applications display critical information in tabular form. Automation scripts may need to verify that the displayed information is correct and interact with a particular record.

  • Read table data.
  • Validate table headers.
  • Count rows and columns.
  • Find a particular record.
  • Click buttons inside a row.
  • Select checkboxes inside rows.
  • Edit a specific record.
  • Delete a specific record.
  • Validate sorting.
  • Handle pagination.
  • Validate filtered results.
  • Compare UI data with expected data.


3. Basic HTML Structure of a Web Table

A standard HTML table can contain the following elements:

  • <table> - Defines the table.
  • <thead> - Contains table headers.
  • <tbody> - Contains table data.
  • <tfoot> - Contains footer information.
  • <tr> - Defines a table row.
  • <th> - Defines a header cell.
  • <td> - Defines a data cell.

4. Example HTML Web Table

<table id="employeeTable">

    <thead>

        <tr>

            <th>ID</th>

            <th>Name</th>

            <th>Department</th>

            <th>Salary</th>

            <th>Action</th>

        </tr>

    </thead>

    <tbody>

        <tr>

            <td>101</td>

            <td>John</td>

            <td>QA</td>

            <td>50000</td>

            <td><button>Edit</button></td>

        </tr>

        <tr>

            <td>102</td>

            <td>David</td>

            <td>Development</td>

            <td>70000</td>

            <td><button>Edit</button></td>

        </tr>

    </tbody>

</table>


5. Web Table Automation Flow

Open Web Page

      |

      v

Locate Table

      |

      v

Locate Rows

      |

      v

Locate Cells

      |

      v

Read Table Data

      |

      +------------------+

      |                  |

      v                  v

Validate Data       Perform Action

                         |

              +----------+----------+

              |          |          |

              v          v          v

            Edit       Delete    Checkbox


6. Locating the Complete Table

The first step is usually to locate the table element using an ID, name, CSS selector, XPath, or another suitable locator.

WebElement table = driver.findElement(By.id("employeeTable"));

Using XPath:

WebElement table = driver.findElement(

    By.xpath("//table[@id='employeeTable']")

);


7. Locating All Rows

The findElements() method can be used to locate multiple rows.

List<WebElement> rows = driver.findElements(

    By.xpath("//table[@id='employeeTable']//tbody/tr")

);

 

System.out.println("Total rows: " + rows.size());

8. Why findElements() is Used for Rows

A table contains multiple rows. Therefore, findElements() is generally more appropriate when we want to retrieve all matching rows.

List<WebElement> rows = driver.findElements(

    By.cssSelector("#employeeTable tbody tr")

);


9. Counting Table Rows

List<WebElement> rows = driver.findElements(

    By.xpath("//table[@id='employeeTable']//tbody/tr")

);

 

int rowCount = rows.size();

 

System.out.println("Number of rows: " + rowCount);

10. Counting Table Columns

List<WebElement> columns = driver.findElements(

    By.xpath("//table[@id='employeeTable']//thead/tr/th")

);

 

System.out.println("Number of columns: " + columns.size());


11. Reading All Table Rows

List<WebElement> rows = driver.findElements(

    By.xpath("//table[@id='employeeTable']//tbody/tr")

);

 

for (WebElement row : rows) {

    System.out.println(row.getText());

}

12. Reading All Cells from Every Row

List<WebElement> rows = driver.findElements(

    By.xpath("//table[@id='employeeTable']//tbody/tr")

);

 

for (WebElement row : rows) {

    List<WebElement> cells = row.findElements(By.tagName("td"));

 

    for (WebElement cell : cells) {

        System.out.print(cell.getText() + " | ");

    }

 

    System.out.println();

}


13. Reading Table Headers

List<WebElement> headers = driver.findElements(

    By.xpath("//table[@id='employeeTable']//thead/tr/th")

);

 

for (WebElement header : headers) {

    System.out.println(header.getText());

}

14. Getting a Specific Cell

Suppose we want to retrieve the value from the second row and third column.

WebElement cell = driver.findElement(

    By.xpath("//table[@id='employeeTable']//tbody/tr[2]/td[3]")

);

 

System.out.println(cell.getText());

XPath indexing starts from 1, so tr[2] means the second row and td[3] means the third cell.


15. Getting a Specific Row

WebElement row = driver.findElement(

    By.xpath("//table[@id='employeeTable']//tbody/tr[2]")

);

 

System.out.println(row.getText());

16. Getting a Specific Column

To retrieve all names from the Name column:

List<WebElement> names = driver.findElements(

    By.xpath("//table[@id='employeeTable']//tbody/tr/td[2]")

);

 

for (WebElement name : names) {

    System.out.println(name.getText());

}


17. Finding a Row Using Text

This is one of the most useful techniques for dynamic web tables. Instead of depending on a row number, we can identify the row using unique cell text.

WebElement row = driver.findElement(

    By.xpath("//table[@id='employeeTable']//tbody/tr[td[normalize-space()='John']]")

);

 

System.out.println(row.getText());

18. Understanding the Dynamic XPath

//table[@id='employeeTable']//tbody/tr[

    td[normalize-space()='John']

]

This XPath means: locate a row inside the employee table where one of its cells contains the text John.


19. Finding a Cell by Text

WebElement cell = driver.findElement(

    By.xpath("//table[@id='employeeTable']//td[normalize-space()='John']")

);

 

System.out.println(cell.getText());

20. Finding a Row by Employee ID

WebElement row = driver.findElement(

    By.xpath("//table[@id='employeeTable']//tbody/tr[td[normalize-space()='101']]")

);

 

System.out.println(row.getText());


21. Finding an Action Button Inside a Row

Many tables contain buttons such as Edit, Delete, View, Approve, Reject, or Download. Once the correct row is identified, we can locate the button relative to that row.

WebElement row = driver.findElement(

    By.xpath("//table[@id='employeeTable']//tbody/tr[td[normalize-space()='John']]")

);

 

WebElement editButton = row.findElement(

    By.cssSelector("button.edit")

);

 

editButton.click();


22. Edit a Record Based on Row Data

WebElement row = driver.findElement(

    By.xpath("//table[@id='employeeTable']//tbody/tr[td[normalize-space()='John']]")

);

 

row.findElement(By.cssSelector("button.edit")).click();

This approach is much more reliable than clicking a hard-coded row number.


23. Delete a Record Based on Row Data

WebElement row = driver.findElement(

    By.xpath("//table[@id='employeeTable']//tbody/tr[td[normalize-space()='David']]")

);

 

row.findElement(By.cssSelector("button.delete")).click();

24. Click a View Button Inside an Order Row

WebElement orderRow = driver.findElement(

    By.xpath("//table[@id='orders']//tbody/tr[td[normalize-space()='ORD1001']]")

);

 

orderRow.findElement(By.cssSelector("button.view")).click();


25. Selecting a Checkbox Inside a Row

WebElement row = driver.findElement(

    By.xpath("//table[@id='users']//tbody/tr[td[normalize-space()='John']]")

);

 

WebElement checkbox = row.findElement(

    By.cssSelector("input[type='checkbox']")

);

 

if (!checkbox.isSelected()) {

    checkbox.click();

}

26. Getting the Number of Cells in a Row

WebElement row = driver.findElement(

    By.xpath("//table[@id='employeeTable']//tbody/tr[1]")

);

 

List<WebElement> cells = row.findElements(By.tagName("td"));

 

System.out.println("Cells: " + cells.size());


27. Reading a Row Cell by Cell

WebElement row = driver.findElement(

    By.xpath("//table[@id='employeeTable']//tbody/tr[1]")

);

 

List<WebElement> cells = row.findElements(By.tagName("td"));

 

for (WebElement cell : cells) {

    System.out.println(cell.getText());

}

28. Printing the Complete Table

List<WebElement> rows = driver.findElements(

    By.xpath("//table[@id='employeeTable']//tbody/tr")

);

 

for (WebElement row : rows) {

    List<WebElement> cells = row.findElements(By.tagName("td"));

 

    for (WebElement cell : cells) {

        System.out.print(cell.getText() + "\t");

    }

 

    System.out.println();

}


29. Web Table Using CSS Selectors

List<WebElement> rows = driver.findElements(

    By.cssSelector("#employeeTable tbody tr")

);

 

List<WebElement> cells = driver.findElements(

    By.cssSelector("#employeeTable tbody tr td")

);

30. XPath vs CSS for Tables

RequirementXPathCSS
Locate table by ID//table[@id='employeeTable']#employeeTable
Locate rows//table[@id='employeeTable']//tbody/tr#employeeTable tbody tr
Locate cells//table[@id='employeeTable']//tbody/tr/td#employeeTable tbody tr td
Find row by textSupported directlyRequires different strategy
Navigate parent/ancestorVery powerfulMore limited


31. Static Web Table

A static web table contains a relatively fixed set of rows and columns. The number and structure of rows usually remain stable during the interaction.

List<WebElement> rows = driver.findElements(

    By.xpath("//table[@id='employeeTable']//tbody/tr")

);

 

for (WebElement row : rows) {

    System.out.println(row.getText());

}

32. Dynamic Web Table

A dynamic web table can change its content, number of rows, columns, pagination, or records based on API responses, database data, search filters, sorting, user actions, or asynchronous requests.

For dynamic tables, avoid depending only on row indexes. Instead, locate rows using stable attributes or unique business data.


33. Static vs Dynamic Web Tables

FeatureStatic TableDynamic Table
RowsUsually predictableCan change
DataUsually fixedOften generated dynamically
PaginationMay not existCommon
SearchMay be simpleOften dynamic
AutomationRelatively simpleRequires robust locators and synchronization


34. Why Hard-Coded Row Numbers Should Be Avoided

Consider the following XPath:

//table[@id='orders']//tbody/tr[3]/td[2]

This may fail when the application sorts the table or when a new record is inserted above the third row.

A better approach is to locate the row using a unique value.

//table[@id='orders']//tbody/tr[td[normalize-space()='ORD1001']]/td[2]


35. Getting Another Cell from the Identified Row

Suppose the order ID is known and we need the customer name from the same row.

WebElement customer = driver.findElement(

    By.xpath("//table[@id='orders']//tbody/tr[td[normalize-space()='ORD1001']]/td[2]")

);

 

System.out.println(customer.getText());

36. Getting Price from a Product Row

WebElement price = driver.findElement(

    By.xpath("//table[@id='products']//tbody/tr[td[normalize-space()='Laptop']]/td[3]")

);

 

System.out.println(price.getText());


37. Validating a Cell Value

String actualStatus = driver.findElement(

    By.xpath("//table[@id='orders']//tbody/tr[td[normalize-space()='ORD1001']]/td[4]")

).getText();

 

String expectedStatus = "Delivered";

 

Assert.assertEquals(actualStatus, expectedStatus);

38. Validating Whether a Row Exists

List<WebElement> matchingRows = driver.findElements(

    By.xpath("//table[@id='orders']//tbody/tr[td[normalize-space()='ORD1001']]")

);

 

Assert.assertFalse(matchingRows.isEmpty());


39. Validating Table Headers

List<WebElement> headers = driver.findElements(

    By.xpath("//table[@id='employeeTable']//thead/tr/th")

);

 

List<String> actualHeaders = new ArrayList<>();

 

for (WebElement header : headers) {

    actualHeaders.add(header.getText().trim());

}

 

List<String> expectedHeaders = Arrays.asList(

    "ID", "Name", "Department", "Salary", "Action"

);

 

Assert.assertEquals(actualHeaders, expectedHeaders);


40. Validating Number of Rows

int actualRows = driver.findElements(

    By.xpath("//table[@id='employeeTable']//tbody/tr")

).size();

 

Assert.assertEquals(actualRows, 10);

41. Handling an Empty Table

Some applications display a message such as “No records found” when a table contains no data.

List<WebElement> rows = driver.findElements(

    By.xpath("//table[@id='employeeTable']//tbody/tr")

);

 

if (rows.isEmpty()) {

    System.out.println("No records found");

} else {

    System.out.println("Records available: " + rows.size());

}


42. Handling No Search Results

List<WebElement> rows = driver.findElements(

    By.xpath("//table[@id='employeeTable']//tbody/tr")

);

 

if (rows.size() == 0) {

    WebElement message = driver.findElement(

        By.xpath("//*[contains(normalize-space(),'No records found')]")

    );

 

    System.out.println(message.getText());

}

43. Dynamic Tables and Explicit Wait

Dynamic tables may require synchronization because table rows can appear after an API call or AJAX request.

WebDriverWait wait = new WebDriverWait(

    driver,

    Duration.ofSeconds(10)

);

 

wait.until(ExpectedConditions.visibilityOfElementLocated(

    By.xpath("//table[@id='employeeTable']//tbody/tr")

));


44. Waiting for a Specific Row

WebDriverWait wait = new WebDriverWait(

    driver,

    Duration.ofSeconds(10)

);

 

WebElement row = wait.until(

    ExpectedConditions.visibilityOfElementLocated(

        By.xpath("//table[@id='orders']//tbody/tr[td[normalize-space()='ORD1001']]")

    )

);

45. Waiting for Table Data to Load

By tableRows = By.xpath("//table[@id='orders']//tbody/tr");

 

wait.until(ExpectedConditions.numberOfElementsToBeMoreThan(

    tableRows,

    0

));


46. Dynamic AJAX Table

AJAX-based tables may load data without refreshing the entire page. Selenium must wait for the relevant table content instead of using fixed delays.

wait.until(ExpectedConditions.invisibilityOfElementLocated(

    By.cssSelector(".table-loader")

));

 

wait.until(ExpectedConditions.visibilityOfElementLocated(

    By.cssSelector("#orders tbody tr")

));

47. Why Thread.sleep() Should Be Avoided

Using Thread.sleep() introduces a fixed delay regardless of whether the table is ready. Explicit waits are generally more flexible because they wait for a specific condition.

Thread.sleep(5000);

Prefer:

wait.until(ExpectedConditions.visibilityOfElementLocated(

    By.cssSelector("#orders tbody tr")

));


48. Handling Pagination in Web Tables

Large tables often divide records into multiple pages. Automation must navigate through pages and collect or validate records.

Page 1

  |

  v

Read rows

  |

  v

Click Next

  |

  v

Wait for new rows

  |

  v

Read rows

  |

  v

Click Next

  |

  v

Repeat

  |

  v

Last Page


49. Identifying the Next Button

WebElement nextButton = driver.findElement(

    By.cssSelector(".pagination .next")

);

50. Checking Whether Next Button is Disabled

WebElement nextButton = driver.findElement(

    By.cssSelector(".pagination .next")

);

 

boolean disabled = !nextButton.isEnabled();

 

System.out.println("Next disabled: " + disabled);

Some applications indicate the disabled state using a CSS class or the disabled attribute. Always inspect the application's actual HTML structure.


51. Looping Through All Pages

while (true) {

    List<WebElement> rows = driver.findElements(

        By.cssSelector("#orders tbody tr")

    );

 

    for (WebElement row : rows) {

        System.out.println(row.getText());

    }

 

    WebElement nextButton = driver.findElement(

        By.cssSelector(".pagination .next")

    );

 

    if (!nextButton.isEnabled()) {

        break;

    }

 

    nextButton.click();

 

    wait.until(ExpectedConditions.stalenessOf(rows.get(0)));

}

52. Important Point About Pagination

When navigating between pages, Selenium should wait for the old page elements to become stale or for the new table content to appear. This helps prevent synchronization problems.


53. Handling StaleElementReferenceException

When a table refreshes, previously stored WebElement objects may no longer refer to the current DOM elements. Selenium can then throw StaleElementReferenceException.

A safer approach is to locate the rows again after the table refresh.

driver.findElement(By.cssSelector(".next")).click();

 

wait.until(ExpectedConditions.presenceOfElementLocated(

    By.cssSelector("#orders tbody tr")

));

 

List<WebElement> updatedRows = driver.findElements(

    By.cssSelector("#orders tbody tr")

);


54. Searching Inside a Table

Many tables have a search field. The test can enter a value and validate the filtered result.

WebElement searchBox = driver.findElement(

    By.id("tableSearch")

);

 

searchBox.clear();

searchBox.sendKeys("John");

 

wait.until(ExpectedConditions.visibilityOfElementLocated(

    By.cssSelector("#employeeTable tbody tr")

));

55. Validating Filtered Results

List<WebElement> rows = driver.findElements(

    By.cssSelector("#employeeTable tbody tr")

);

 

for (WebElement row : rows) {

    Assert.assertTrue(

        row.getText().toLowerCase().contains("john")

    );

}


56. Sorting a Web Table

Tables may provide sortable columns such as Name, Price, Date, Salary, or Status. Selenium can click a header and validate the resulting order.

driver.findElement(

    By.xpath("//table[@id='employeeTable']//th[normalize-space()='Name']")

).click();

57. Reading Values Before Sorting

List<WebElement> nameCells = driver.findElements(

    By.xpath("//table[@id='employeeTable']//tbody/tr/td[2]")

);

 

List<String> names = new ArrayList<>();

 

for (WebElement cell : nameCells) {

    names.add(cell.getText().trim());

}


58. Validating Alphabetical Sorting

List<String> actual = new ArrayList<>(names);

List<String> expected = new ArrayList<>(names);

 

Collections.sort(expected);

 

Assert.assertEquals(actual, expected);

59. Descending Sort Validation

List<String> expected = new ArrayList<>(names);

 

expected.sort(Collections.reverseOrder());

 

Assert.assertEquals(actual, expected);


60. Numeric Table Data Validation

Numbers displayed in tables are often retrieved as strings. Convert them into numeric values before performing mathematical comparisons.

String priceText = cell.getText().replace("$", "").replace(",", "");

 

double price = Double.parseDouble(priceText);

 

System.out.println(price);

61. Validating Prices

String priceText = cell.getText()

    .replace("$", "")

    .replace(",", "")

    .trim();

 

double price = Double.parseDouble(priceText);

 

Assert.assertTrue(price > 0);


62. Date Validation in Tables

Date columns require careful handling because the displayed format may vary.

String dateText = cell.getText().trim();

 

DateTimeFormatter formatter =

    DateTimeFormatter.ofPattern("dd-MM-yyyy");

 

LocalDate date = LocalDate.parse(dateText, formatter);

 

System.out.println(date);

63. Status Validation

String status = driver.findElement(

    By.xpath("//table[@id='orders']//tbody/tr[td[normalize-space()='ORD1001']]/td[4]")

).getText();

 

Assert.assertEquals(status, "Delivered");


64. Working with Links Inside Tables

WebElement row = driver.findElement(

    By.xpath("//table[@id='users']//tbody/tr[td[normalize-space()='John']]")

);

 

row.findElement(By.tagName("a")).click();

65. Working with Buttons Inside Tables

WebElement row = driver.findElement(

    By.xpath("//table[@id='users']//tbody/tr[td[normalize-space()='John']]")

);

 

row.findElement(By.tagName("button")).click();


66. Multiple Buttons in the Same Row

If a row contains multiple buttons, use a specific class or attribute rather than simply selecting the first button.

row.findElement(By.cssSelector("button.edit")).click();

67. Multiple Actions Example

row.findElement(By.cssSelector("button.view")).click();

row.findElement(By.cssSelector("button.edit")).click();

row.findElement(By.cssSelector("button.delete")).click();


68. Extracting Table Data into a List

List<List<String>> tableData = new ArrayList<>();

 

List<WebElement> rows = driver.findElements(

    By.cssSelector("#employeeTable tbody tr")

);

 

for (WebElement row : rows) {

    List<String> rowData = new ArrayList<>();

 

    for (WebElement cell : row.findElements(By.tagName("td"))) {

        rowData.add(cell.getText().trim());

    }

 

    tableData.add(rowData);

}


69. Creating a Reusable Web Table Utility

public List<List<String>> getTableData(

        By tableRowsLocator) {

 

    List<List<String>> data = new ArrayList<>();

 

    List<WebElement> rows =

        driver.findElements(tableRowsLocator);

 

    for (WebElement row : rows) {

        List<String> rowData = new ArrayList<>();

 

        List<WebElement> cells =

            row.findElements(By.tagName("td"));

 

        for (WebElement cell : cells) {

            rowData.add(cell.getText().trim());

        }

 

        data.add(rowData);

    }

 

    return data;

}


70. Utility Method to Find a Row

public WebElement findRowByText(

        By rowsLocator,

        String expectedText) {

 

    List<WebElement> rows =

        driver.findElements(rowsLocator);

 

    for (WebElement row : rows) {

        if (row.getText().contains(expectedText)) {

            return row;

        }

    }

 

    throw new NoSuchElementException(

        "Row not found: " + expectedText

    );

}

71. Utility Method to Get Cell Value

public String getCellValue(

        By rowLocator,

        int columnIndex) {

 

    WebElement row = driver.findElement(rowLocator);

 

    List<WebElement> cells =

        row.findElements(By.tagName("td"));

 

    return cells.get(columnIndex - 1)

        .getText()

        .trim();

}


72. Page Object Model for Web Tables

In a Page Object Model framework, table locators and table operations can be placed inside a page class or reusable component class.

public class EmployeePage {

 

    private WebDriver driver;

 

    private By employeeRows =

        By.cssSelector("#employeeTable tbody tr");

 

    public EmployeePage(WebDriver driver) {

        this.driver = driver;

    }

 

    public List<WebElement> getEmployeeRows() {

        return driver.findElements(employeeRows);

    }

}


73. Page Object Method to Find Employee

public WebElement getEmployeeRow(String employeeName) {

 

    return driver.findElement(

        By.xpath("//table[@id='employeeTable']//tbody/tr[

            td[normalize-space()='" + employeeName + "']

        ]")

    );

}

For complex applications, it is better to construct dynamic locators carefully and validate input values before using them in XPath.


74. E-Commerce Product Table Example

Imagine an application displaying products with Product Name, Category, Price, Stock, and Action.

ProductCategoryPriceStockAction
LaptopElectronics75000AvailableBuy
KeyboardAccessories1500AvailableBuy
MonitorElectronics18000Out of StockView

75. Finding a Product Row

WebElement productRow = driver.findElement(

    By.xpath("//table[@id='products']//tbody/tr[

        td[normalize-space()='Laptop']

    ]")

);


76. Clicking Buy for a Specific Product

productRow.findElement(

    By.cssSelector("button.buy")

).click();

77. Checking Product Availability

String stock = productRow.findElement(

    By.cssSelector(".stock")

).getText();

 

Assert.assertEquals(stock, "Available");


78. Employee Table Example

List<WebElement> rows = driver.findElements(

    By.cssSelector("#employeeTable tbody tr")

);

 

for (WebElement row : rows) {

 

    List<WebElement> cells =

        row.findElements(By.tagName("td"));

 

    String id = cells.get(0).getText();

    String name = cells.get(1).getText();

    String department = cells.get(2).getText();

    String salary = cells.get(3).getText();

 

    System.out.println(

        id + " | " +

        name + " | " +

        department + " | " +

        salary

    );

}


79. Order Management Table Example

Order management systems frequently use tables containing Order ID, Customer, Date, Amount, Status, and Actions.

WebElement orderRow = driver.findElement(

    By.xpath("//table[@id='orders']//tbody/tr[

        td[normalize-space()='ORD1001']

    ]")

);

 

String customer = orderRow.findElement(

    By.cssSelector(".customer")

).getText();

 

String status = orderRow.findElement(

    By.cssSelector(".status")

).getText();

 

System.out.println(customer);

System.out.println(status);


80. Handling Nested Tables

Some applications contain a table inside a table cell. In such cases, first locate the parent row or cell and then search inside it.

WebElement parentRow = driver.findElement(

    By.cssSelector("#orders tbody tr")

);

 

WebElement nestedTable = parentRow.findElement(

    By.cssSelector("table")

);

 

List<WebElement> nestedRows =

    nestedTable.findElements(By.cssSelector("tbody tr"));


81. Web Table Inside an IFrame

If the table exists inside an iframe, Selenium must switch into that iframe before locating the table.

WebElement frame = driver.findElement(

    By.cssSelector("iframe#tableFrame")

);

 

driver.switchTo().frame(frame);

 

List<WebElement> rows = driver.findElements(

    By.cssSelector("#employeeTable tbody tr")

);

 

driver.switchTo().defaultContent();


82. Web Table Inside a Modal

WebElement modal = driver.findElement(

    By.cssSelector(".modal")

);

 

List<WebElement> rows = modal.findElements(

    By.cssSelector("table tbody tr")

);

83. Handling Hidden Rows

Some tables may contain hidden rows. Selenium can locate elements that exist in the DOM even when they are not currently visible.

List<WebElement> rows = driver.findElements(

    By.cssSelector("#employeeTable tbody tr")

);

 

for (WebElement row : rows) {

    if (row.isDisplayed()) {

        System.out.println(row.getText());

    }

}


84. Handling Row Highlighting

Some tables highlight a row when it is selected. Selenium can click the row and then validate its class or selected state.

WebElement row = driver.findElement(

    By.xpath("//table[@id='users']//tbody/tr[td[normalize-space()='John']]")

);

 

row.click();

 

String className = row.getAttribute("class");

 

Assert.assertTrue(

    className.contains("selected")

);


85. Complete Web Table TestNG Example

import java.time.Duration;

import java.util.List;

import org.openqa.selenium.By;

import org.openqa.selenium.WebDriver;

import org.openqa.selenium.WebElement;

import org.openqa.selenium.chrome.ChromeDriver;

import org.openqa.selenium.support.ui.ExpectedConditions;

import org.openqa.selenium.support.ui.WebDriverWait;

import org.testng.Assert;

import org.testng.annotations.AfterMethod;

import org.testng.annotations.BeforeMethod;

import org.testng.annotations.Test;

 

public class WebTableTest {

 

    WebDriver driver;

    WebDriverWait wait;

 

    @BeforeMethod

    public void setup() {

        driver = new ChromeDriver();

        wait = new WebDriverWait(

            driver,

            Duration.ofSeconds(10)

        );

 

        driver.manage().window().maximize();

    }

 

    @Test

    public void validateEmployeeTable() {

 

        driver.get("https://example.com/employees");

 

        By rowsLocator =

            By.cssSelector("#employeeTable tbody tr");

 

        wait.until(

            ExpectedConditions.numberOfElementsToBeMoreThan(

                rowsLocator,

                0

            )

        );

 

        List<WebElement> rows =

            driver.findElements(rowsLocator);

 

        Assert.assertTrue(rows.size() > 0);

 

        for (WebElement row : rows) {

            System.out.println(row.getText());

        }

 

        WebElement johnRow = driver.findElement(

            By.xpath("//table[@id='employeeTable']//tbody/tr[

                td[normalize-space()='John']

            ]")

        );

 

        Assert.assertTrue(

            johnRow.isDisplayed()

        );

    }

 

    @AfterMethod

    public void tearDown() {

        if (driver != null) {

            driver.quit();

        }

    }

}


86. Web Table Test Scenario

  1. Launch the application.
  2. Navigate to the employee page.
  3. Wait for the table to load.
  4. Verify the table is displayed.
  5. Verify table headers.
  6. Count the number of rows.
  7. Search for an employee.
  8. Identify the employee row.
  9. Read employee information.
  10. Validate the department.
  11. Validate the salary.
  12. Click Edit.
  13. Update employee information.
  14. Save changes.
  15. Verify the updated information.


87. Web Table with Checkboxes

List<WebElement> rows = driver.findElements(

    By.cssSelector("#users tbody tr")

);

 

for (WebElement row : rows) {

 

    String userName = row.findElement(

        By.cssSelector(".username")

    ).getText();

 

    if (userName.equals("John")) {

 

        WebElement checkbox = row.findElement(

            By.cssSelector("input[type='checkbox']")

        );

 

        if (!checkbox.isSelected()) {

            checkbox.click();

        }

 

        break;

    }

}


88. Web Table with Edit and Delete Actions

WebElement row = driver.findElement(

    By.xpath("//table[@id='users']//tbody/tr[

        td[normalize-space()='John']

    ]")

);

 

row.findElement(By.cssSelector("button.edit")).click();

 

wait.until(ExpectedConditions.visibilityOfElementLocated(

    By.cssSelector("#editUserModal")

));


89. Negative Testing for Web Tables

Web table automation should also verify incorrect, missing, empty, or unexpected data.

  • Search for a non-existing record.
  • Verify no-result message.
  • Validate empty table behavior.
  • Validate duplicate records.
  • Validate missing values.
  • Validate incorrect status.
  • Validate invalid numeric values.
  • Validate invalid date formats.
  • Verify disabled action buttons.
  • Verify pagination boundaries.


90. Boundary Testing for Tables

  • Zero records.
  • One record.
  • Maximum records on one page.
  • Exactly one full page of data.
  • More records than one page.
  • Last page containing one record.
  • Very large datasets.


91. Duplicate Record Validation

Set<String> employeeNames = new HashSet<>();

 

for (WebElement row : rows) {

    String name = row.findElement(

        By.cssSelector("td:nth-child(2)")

    ).getText().trim();

 

    boolean added = employeeNames.add(name);

 

    Assert.assertTrue(

        added,

        "Duplicate employee found: " + name

    );

}


92. Validating Table Data Against Expected Data

List<String> expectedNames =

    Arrays.asList("John", "David", "Robert");

 

List<String> actualNames = new ArrayList<>();

 

for (WebElement row : rows) {

    actualNames.add(

        row.findElement(

            By.cssSelector("td:nth-child(2)")

        ).getText().trim()

    );

}

 

Assert.assertEquals(actualNames, expectedNames);


93. Common Selenium Exceptions with Web Tables

ExceptionPossible CauseSolution
NoSuchElementExceptionIncorrect locator or row not loadedVerify locator and use an explicit wait
StaleElementReferenceExceptionTable refreshedLocate the row again
ElementClickInterceptedExceptionAnother element blocks the buttonWait for clickable state or handle overlay
TimeoutExceptionExpected table condition did not occurReview wait condition and application state
IndexOutOfBoundsExceptionRequested cell does not existCheck row/column count


94. Common Mistakes in Web Table Automation

  • Using fixed row numbers everywhere.
  • Using absolute XPath unnecessarily.
  • Not waiting for dynamic data.
  • Storing WebElements across table refreshes.
  • Ignoring pagination.
  • Not handling empty results.
  • Assuming every row has the same number of cells.
  • Using Thread.sleep() for synchronization.
  • Not validating that the correct row was selected.
  • Using generic locators when stable attributes are available.


95. Best Practices for Web Tables

  • Prefer stable IDs and data attributes when available.
  • Use relative XPath for dynamic rows.
  • Locate actions relative to the identified row.
  • Use explicit waits for dynamic content.
  • Do not depend unnecessarily on row indexes.
  • Re-locate elements after table refreshes.
  • Build reusable table utility methods.
  • Keep table logic inside Page Objects or reusable components.
  • Validate both positive and negative scenarios.
  • Handle pagination systematically.
  • Keep locators readable and maintainable.


96. Recommended Locator Strategy

PriorityLocatorExample
1IDBy.id("employeeTable")
2Stable data attributeBy.cssSelector("[data-testid='employee-table']")
3CSS SelectorBy.cssSelector("#employeeTable tbody tr")
4Relative XPathBy.xpath("//table[@id='employeeTable']//tbody/tr")
5Absolute XPathAvoid when possible


97. Web Table Automation Architecture

TestNG Test

     |

     v

Page Object

     |

     v

Web Table Utility

     |

     +---- Locate Table

     |

     +---- Locate Rows

     |

     +---- Locate Cells

     |

     +---- Read Data

     |

     +---- Find Row

     |

     +---- Click Action

     |

     +---- Validate Data

     |

     v

Application


98. Real-World Use Cases

  • Employee management systems.
  • Banking transaction tables.
  • E-commerce product tables.
  • Order management systems.
  • CRM customer tables.
  • Student management systems.
  • Hospital patient records.
  • Admin dashboards.
  • Financial reports.
  • Inventory management systems.
  • Flight booking records.
  • Payment transaction history.


99. Practical Mini Project

Create an automation test for an Employee Management application.

Requirements

  1. Open the employee management application.
  2. Locate the employee table.
  3. Verify the table headers.
  4. Count the available records.
  5. Search for an employee.
  6. Identify the employee row dynamically.
  7. Read employee department and salary.
  8. Validate employee status.
  9. Click Edit for the selected employee.
  10. Update the employee information.
  11. Save the changes.
  12. Verify the updated row.
  13. Test pagination.
  14. Test sorting.
  15. Test empty search results.


100. Web Table Interview Questions

Q1. What is a Web Table?

A Web Table is an HTML component that displays structured information in rows and columns.

Q2. Which HTML tags are commonly used in a table?

The common tags are <table>, <tr>, <th>, and <td>.

Q3. How do you find all rows of a table?

driver.findElements(

    By.xpath("//table[@id='employeeTable']//tbody/tr")

);

Q4. How do you find all cells from a row?

row.findElements(By.tagName("td"));

Q5. How do you find a particular row based on text?

By.xpath("//table[@id='employeeTable']//tbody/tr[

    td[normalize-space()='John']

]")

Q6. How do you click an Edit button for a particular row?

WebElement row = driver.findElement(

    By.xpath("//table[@id='employeeTable']//tbody/tr[

        td[normalize-space()='John']

    ]")

);

 

row.findElement(By.cssSelector("button.edit")).click();

Q7. How do you handle dynamic tables?

Use stable locators, identify rows using unique data, apply explicit waits, and re-locate elements after table refreshes.

Q8. How do you handle pagination?

Read the current page, identify whether the Next button is available, click it, wait for the new data, and repeat until the last page.

Q9. Why is findElements() useful for tables?

It returns a collection of matching WebElements, making it useful for processing multiple rows or cells.

Q10. How do you handle StaleElementReferenceException?

Re-locate the table row or cell after the DOM has been refreshed and use appropriate synchronization.


101. Quick Revision

  • Use findElement() for one table element.
  • Use findElements() for multiple rows or cells.
  • Use tr for rows.
  • Use td for data cells.
  • Use th for headers.
  • Use relative XPath to locate dynamic rows.
  • Identify rows using unique business data.
  • Perform actions relative to the selected row.
  • Use explicit waits for dynamic tables.
  • Handle pagination carefully.
  • Re-locate elements after table refreshes.
  • Validate sorting, filtering, and table data.
  • Use reusable Web Table utility methods.


102. Web Table Automation Checklist

TaskCompleted
Locate the table☐
Locate table headers☐
Locate table rows☐
Count rows☐
Count columns☐
Read table data☐
Find row by unique text☐
Click action inside row☐
Handle checkboxes☐
Handle dynamic data☐
Handle pagination☐
Handle sorting☐
Handle filtering☐
Validate table data☐
Handle empty results☐
Handle stale elements☐
Create reusable utility methods☐
Implement Page Object Model☐
Write TestNG test cases☐


103. Conclusion

Web Tables are an important part of Selenium WebDriver automation because enterprise applications frequently present business data in tabular form. Effective table automation requires more than simply locating rows and cells. A robust Selenium test should identify records using stable and meaningful information, locate actions relative to the correct row, synchronize with dynamically loaded data, handle pagination, validate sorting and filtering, and gracefully handle empty or changing tables.

By combining XPath, CSS selectors, findElements(), WebElement methods, explicit waits, loops, conditions, TestNG, and Page Object Model, testers can create reliable and maintainable automation for both static and dynamic web tables.

Learn more: Selenium Training Course | Register for Course Demo

whatsapp