Contents

    Guides

    Web Table in Selenium: Complete Guide

    Published on

    September 17, 2025
    Web Table in Selenium: Complete Guide

    Web tables are commonly used for reporting dashboards, product listings, user management systems, and transactional data. However, automating interactions with web tables is often complex because they can vary from simple static tables to highly dynamic tables with multiple levels, pagination, or embedded interactive elements. 

    In Selenium, testers need to locate tables accurately, read data efficiently, and perform actions like clicking buttons, selecting checkboxes, or handling dropdowns within table cells. 

    This guide explains the different types of web tables, techniques to access and manipulate their data, and strategies to validate dynamic updates and nested structures.

    What Are Web Tables in Real-World Web Applications?

    Web tables are HTML elements that organize information in a structured format with rows and columns. They are used wherever tabular data needs to be presented clearly. 

    Examples include inventory lists, financial reports, user management panels, and analytics dashboards. Each table cell can contain plain text, links, buttons, checkboxes, or even nested tables, which makes handling them in automation more challenging than standard page elements.

    Here are the common aspects of web tables in real-world applications:

    • Row and Column Structure: Each row typically represents a single record while each column represents a specific attribute of that record. For example, in a user table, columns might include Name, Email, Role, and Status.
    • Header and Footer Rows: Headers define column labels and are often used for sorting or filtering. Footers can summarize data, such as totals or averages.
    • Interactive Elements: Many tables include buttons, links, checkboxes, or dropdowns inside cells. For example, an Edit button in a row allows modifying that record directly from the table.
    • Dynamic Content: Tables can update automatically based on user actions, filters, or server-side events. Data can be loaded via AJAX or APIs, making the table content dynamic rather than static.

    When Should Testers Automate Web Table Actions in Selenium?

    Automation should be applied when tables are large, frequently updated, or contain interactive elements that need validation across multiple scenarios. Manual testing may work for static or small tables, but automation becomes essential when efficiency, accuracy, and repeatability are required.

    Below are scenarios where automating web table actions in Selenium provides significant value:

    • Large Data Sets: Tables with hundreds or thousands of rows are time-consuming to test manually. Automation allows testers to quickly read, validate, and interact with large data sets.
    • Frequent Updates: Tables that change regularly due to user input, server updates, or API-driven data require repeated validation. Automation ensures consistent verification without missing updates.
    • Interactive Cells: Tables containing checkboxes, buttons, links, or dropdowns need precise actions and validations. For example, clicking a “Delete” button in a row should remove the correct record.
    • Pagination and Sorting: When tables span multiple pages or allow sorting/filtering, automation ensures all pages are validated and the sorting functionality works as expected.
    • Dynamic Tables: Tables loaded via AJAX or updated asynchronously need automation scripts to handle timing and wait conditions effectively.

    Static vs Dynamic Web Tables

    Web tables can be static with fixed content or dynamic with data that changes based on user actions or server responses. Choosing the right approach depends on how the table behaves during testing.

    Feature Static Web Tables Dynamic Web Tables
    Content Changes Fixed until page reload Updates automatically via user actions or server
    Complexity Simple to locate and interact Requires handling AJAX, pagination, and delays
    Row and Column Variability Predictable Row and column counts can change dynamically
    Example Product specification table Live transaction or analytics dashboard
    Automation Consideration Direct cell access Use waits, handle variable row counts, avoid stale elements
    Nested Structures Rare Often present (expandable rows, nested tables)
    Sorting and Filtering Usually static headers Sorting and filtering can change DOM structure
    Pagination Minimal or none Common, requires iterating across pages
    Interactive Elements Minimal (mostly text) Buttons, links, checkboxes, dropdowns in cells
    Data Validation Straightforward Requires dynamic checks and conditional logic
    Performance Consideration Faster automation due to fixed content Slower due to dynamic loading and waits

    How Can You Locate Web Tables Efficiently?

    Locating web tables correctly is crucial before performing any actions or validations in Selenium. Using the right locator reduces errors, improves script reliability, and makes maintenance easier. Different locators work better depending on whether the table is static, dynamic, or nested. 

    Here’s how

    1. Using ID, Class, and CSS Selectors

    Locating web tables using IDs, class names, or CSS selectors is the most straightforward method when the table has identifiable attributes. These locators are faster and more stable than XPath in many cases, especially for static tables. Using these locators reduces maintenance overhead and improves test reliability.

    Below are practical approaches for Selenium automation:

    • Using ID: If a table has a unique ID, it is the most reliable locator. Testers can directly access the table element and perform row or cell operations. For example, driver.findElement(By.id("employeeTable")) allows direct interaction with the table without ambiguity.
    • Using Class Name: When multiple tables share the same class, testers can retrieve a list and select the specific table by index or additional attributes. For example, driver.findElements(By.className("data-table")).get(0) selects the first matching table.
    • Using CSS Selector: CSS selectors are flexible for targeting specific table elements, rows, or cells. For example, table.data-table > tbody > tr:nth-child(2) > td:nth-child(3) locates the third cell of the second row. CSS selectors can also target nested tables or tables with multiple classes efficiently.

    2. Using XPath for Dynamic Tables

    Dynamic web tables often change in structure or content, making CSS selectors or IDs less reliable. In such cases, XPath provides flexibility by locating elements based on text, attributes, or relative positions. This is especially useful for tables that load data asynchronously, have variable row counts, or include nested elements.

    Below are common XPath strategies for handling dynamic tables:

    • Locate rows by text content: Use XPath to select rows based on the value inside a cell. For example, //table[@id='orderTable']//tr[td[text()='Pending']] finds the row in the table orderTable where a cell contains the text "Pending".
    • Target cells with conditions: Combine row and column conditions to locate specific data. For example, //table[@id='userTable']//tr[td[text()='John']]//td[3] finds the third cell in the row where the first column has the value "John".
    • Handle variable row counts: Use functions like last() to work with dynamic row counts. For example, //table[@id='logTable']//tr[last()] selects the last row of the logTable, no matter how many rows it has.
    • Work with nested structures: Target inner tables by traversing multiple levels in the DOM. For example, //table[@id='mainTable']//tr//table[@class='nested']//td[2] finds the second cell in a nested table inside the main table.
    • Partial text matches: Locate cells even if their values change dynamically. For example, //table[@id='productTable']//td[contains(text(),'Laptop')] selects any cell in productTable containing the word "Laptop".

    How to Read Data from Rows, Columns, and Cells?

    Reading table data is one of the most common operations testers perform in Selenium. It helps in verifying values displayed on the UI against expected data from a database or API. 

    1. Read all rows

    When you want to count or list all the rows in a table, you can target the <tr> elements. This is useful for validating whether the table is displaying the expected number of records. For example:

    List<WebElement> rows = driver.findElements(By.xpath("//table[@id='employeeTable']//tr"));

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

    This prints the total number of rows in the employeeTable.

    2. Read all columns in a row

    Sometimes you only need to extract the values of a single row, for instance when checking details of a specific employee or order. You can do this by fetching all <td> elements for that row. For example:

    List<WebElement> cols = driver.findElements(By.xpath("//table[@id='employeeTable']//tr[2]/td"));

    for(WebElement col : cols) {

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

    }

    This retrieves all the column values from the second row.

    3. Read a single cell

    In cases where only one value matters, such as a price or status field, it is more efficient to directly locate that cell using a combination of row and column indexes. For example:

    String cell = driver.findElement(By.xpath("//table[@id='employeeTable']//tr[3]/td[2]")).getText();

    System.out.println("Cell value: " + cell);

    This gets the text from the second column of the third row.

    4. Read the entire table

    To loop through all rows and cells in a table, you can use nested iterations. This is often required for data-driven validations, where every record displayed on the UI needs to be compared with a source of truth. 

    For example:

    List<WebElement> allRows = driver.findElements(By.xpath("//table[@id='employeeTable']//tr"));

    for(WebElement row : allRows) {

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

        for(WebElement cell : cells) {

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

        }

        System.out.println();

    }

    This prints the entire table row by row and cell by cell.

    How Can You Interact with Table Elements?

    Reading data is only one part of working with tables. In real test scenarios, testers often need to interact with elements inside table cells. These could be action buttons, hyperlinks, checkboxes, or input fields that trigger workflows such as editing, deleting, or selecting records. Selenium allows direct interaction with these elements once they are located properly. 

    Below are the most frequent cases.

    1. Buttons, Links, and Checkboxes

    Tables often contain buttons for actions like “Edit” or “Delete,” links to navigate to a details page, or checkboxes for record selection. The key is to first locate the row of interest and then drill down to the cell containing the interactive element. For example:

    WebElement deleteBtn = driver.findElement(

        By.xpath("//table[@id='userTable']//tr[td[text()='John']]//button[text()='Delete']")

    );

    deleteBtn.click();

    This finds the row where the cell value is “John” and clicks the Delete button in that row.

    Similarly, a checkbox in a particular row can be selected like this:

    WebElement checkbox = driver.findElement(

        By.xpath("//table[@id='userTable']//tr[td[text()='Alice']]//input[@type='checkbox']")

    );

    checkbox.click();

    This selects the checkbox in the row where the name is “Alice.”

    2. Dropdowns and Inputs

    Some applications embed dropdowns or text fields inside tables to allow inline editing or status changes. Testers need to first locate the specific row and column, and then interact with the input element. For example:

    WebElement statusDropdown = driver.findElement(

        By.xpath("//table[@id='orderTable']//tr[td[text()='Order123']]//select")

    );

    Select select = new Select(statusDropdown);

    select.selectByVisibleText("Shipped");

    This locates the dropdown in the row where the order ID is Order123 and changes its value to “Shipped.”

    For text input fields:

    WebElement inputField = driver.findElement(

        By.xpath("//table[@id='orderTable']//tr[td[text()='Order123']]//input[@type='text']")

    );

    inputField.clear();

    inputField.sendKeys("Updated Notes");

    This edits the text field for the same row.

    Nested or Multi-Level Web Tables: What Testers Need to Know

    Not all web tables are flat structures. Many modern applications use nested or multi-level tables to group related information. A common example is a parent table that lists orders, with each order row expanding into a child table showing item details. Working with such structures requires testers to handle multiple <table> elements inside a single parent row.

    The first step is to identify whether the application uses true nested <table> tags or relies on hidden rows that become visible on expansion. Once confirmed, you can chain locators to reach the right table. For example:

    WebElement nestedCell = driver.findElement(

        By.xpath("//table[@id='mainTable']//tr[td[text()='Order123']]//table[@class='nested']//td[2]")

    );

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

    This locates the nested child table inside the row for Order123 and extracts the value of its second column.

    If the nested table appears only after clicking an expand icon, you need to add an interaction step:

    driver.findElement(

        By.xpath("//table[@id='mainTable']//tr[td[text()='Order123']]//button[@class='expand']")

    ).click();

    WebElement detailTable = driver.findElement(

        By.xpath("//table[@id='mainTable']//tr[@class='expanded']//table[@class='nested']")

    );

    Here, the expand button is clicked first, and then Selenium locates the child table within the expanded row.

    Dealing with multi-level structures often requires synchronization because nested content may load asynchronously. In such cases, explicit waits should be used before interacting with the child table.

    How to Verify Table Data Across Pagination or Dynamic Updates

    Large datasets are often split across multiple pages, or updated dynamically as users interact with filters or sorting. For testers, this adds complexity because the required data might not be present in the current view. Verification in such cases means handling both navigation and synchronization.

    1. Handling pagination

    When a table spans multiple pages, you must iterate through each page until the required data is found. This usually involves clicking a Next button or selecting a page number from pagination controls. 

    For example:

    boolean recordFound = false;

    while (!recordFound) {

        List<WebElement> rows = driver.findElements(By.xpath("//table[@id='employeeTable']//tr"));

        for (WebElement row : rows) {

            if (row.getText().contains("Alice")) {

                System.out.println("Record found: " + row.getText());

                recordFound = true;

                break;

            }

        }

        if (!recordFound) {

            WebElement nextBtn = driver.findElement(By.id("nextPage"));

            if (nextBtn.isEnabled()) {

                nextBtn.click();

            } else {

                break;

            }

        }

    }

    This loop searches all pages until the row with “Alice” is found or pagination ends.

    2. Handling dynamic updates

    Some tables update automatically when filters are applied or when new data is pushed from the backend. These updates may not reload the entire page, so you need to wait for the table contents to change before validating. For example:

    WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));

    wait.until(ExpectedConditions.textToBePresentInElementLocated(

        By.xpath("//table[@id='orderTable']//tr[1]/td[2]"), "Shipped")

    );

    This waits until the first row in the orderTable reflects the updated status “Shipped.”

    Dynamic tables may also regenerate their DOM structure, which invalidates old WebElement references. To avoid StaleElementReferenceException, always locate rows or cells after the update has occurred rather than reusing previously stored elements.

    Conclusion

    Web tables are widely used in applications, and testers need clear methods to read data, interact with elements, and manage cases like nested tables or pagination. Selenium supports these tasks when locators are chosen carefully and updates are handled properly.

    To ensure accuracy across environments, tests should also run on real browsers and devices. BrowserStack provides this through instant access to a wide range of browsers, devices, and versions, along with features like parallel execution and local testing. This helps testers validate table interactions in conditions that match real user environments.

    Run Selenium Tests on Cloud

    Data-rich bug reports loved by everyone

    Get visual proof, steps to reproduce and technical logs with one click

    Make bug reporting 50% faster and 100% less painful

    Rating LogosStars
    4.6
    |
    Category leader

    Liked the article? Spread the word

    Put your knowledge to practice

    Try Bird on your next bug - you’ll love it

    “Game changer”

    Julie, Head of QA

    star-ratingstar-ratingstar-ratingstar-ratingstar-rating

    Overall rating: 4.7/5

    Try Bird later, from your desktop