How to Handle Web Table in Selenium
โก Smart Summary
Selenium Web Table handling lets QA engineers read tabular data from HTML rows and columns using XPath, CSS, and Selenium 4 relative locators. This article walks through static tables, nested tables, attribute predicates, and AI techniques for dynamic grids.

What is a Web Table in Selenium?
A Web Table in Selenium is a WebElement used for the tabular representation of data or information. The data displayed can be either static or dynamic. Web table cells and rows are accessed through WebElement methods combined with locators. A typical example is the product specifications grid shown on an eCommerce product page.
Reading an HTML Web Table
There are many times when testers need to access elements, usually text values, located inside HTML tables. However, web designers seldom provide an id or name attribute on individual cells. Therefore, methods such as By.id(), By.name(), or By.cssSelector() rarely work. In this scenario, the most reliable option is By.xpath() because it walks the parent-child relationships inside the table tag.
How to Handle Web Table in Selenium
Consider the HTML code below for handling web tables in Selenium.
We will use XPath to get the inner text of the cell containing the text “fourth cell.”
Step 1 – Set the Parent Element (table)
XPath locators in WebDriver always start with a double forward slash “//” followed by the parent element. Since we are dealing with web tables in Selenium, the parent element should always be the <table> tag. The first portion of our Selenium XPath table locator must therefore start with “//table”.
Step 2 – Add the child elements
The element directly under <table> is <tbody>, so <tbody> is the child of <table>. Conversely, <table> is the parent of <tbody>. All child elements in XPath are placed to the right of their parent element, separated by one forward slash “/” as shown below.
.png)
Step 3 – Add Predicates
The <tbody> element contains two <tr> tags. These two <tr> tags are children of <tbody>, so <tbody> is the parent of both. The two <tr> elements are siblings. Siblings are child elements that share the same parent.
To reach the <td> that contains “fourth cell”, we must first access the second <tr>, not the first. Writing only “//table/tbody/tr” would target the first <tr> tag.
So how do we access the second <tr>? The answer is to use Predicates. Predicates are numbers or HTML attributes enclosed in square brackets “[ ]” that distinguish a child element from its siblings. Since the row we need is the second one, we use “[2]” as the predicate.
If we omit the predicate, XPath returns the first sibling. Therefore, either of the XPath codes below will reach the first <tr>.
Step 4 – Add the Succeeding Child Elements Using the Appropriate Predicates
The next element we need is the second <td>. Applying the rules from Steps 2 and 3, we arrive at the XPath shown below.
Now that we have the correct XPath locator, we can access the cell and read its inner text using the code below. This assumes you have saved the HTML page as “newhtml.html” inside your C drive.
public static void main(String[] args) {
String baseUrl = "https://demo.guru99.com/test/write-xpath-table.html";
WebDriver driver = new FirefoxDriver();
driver.get(baseUrl);
String innerText = driver.findElement(
By.xpath("//table/tbody/tr[2]/td[2]")).getText();
System.out.println(innerText);
driver.quit();
}
Accessing Nested Tables
The same principles apply to nested tables. Nested tables are tables placed inside another table. An example is shown below.
To access the cell with the text “4-5-6” using the parent/child and predicate ideas from the previous section, we can compose the XPath shown below.
The WebDriver code below retrieves the inner text of the targeted cell.
public static void main(String[] args) {
String baseUrl = "https://demo.guru99.com/test/accessing-nested-table.html";
WebDriver driver = new FirefoxDriver();
driver.get(baseUrl);
String innerText = driver.findElement(
By.xpath("//table/tbody/tr[2]/td[2]/table/tbody/tr/td[2]")).getText();
System.out.println(innerText);
driver.quit();
}
The output below confirms that the inner table was successfully accessed.
Using Attributes as Predicates
If the element sits deep inside the HTML, where counting siblings becomes painful, we can use that element’s unique attribute instead.
In the example below, the “New York to Chicago” cell is buried far inside the Mercury Tours homepage.
We can use the table’s unique attribute (width=”270″) as the predicate. Attributes are used as predicates by prefixing them with the @ symbol. In the example above, the “New York to Chicago” cell is located in the first <td> of the fourth <tr>, so our XPath should look like the one shown below.
Remember that when you put the XPath inside Java, escape the double quotes around “270” with a backslash so the By.xpath() string is not terminated early.
We are now ready to access that cell using the code below.
public static void main(String[] args) {
String baseUrl = "https://demo.guru99.com/test/newtours/";
WebDriver driver = new FirefoxDriver();
driver.get(baseUrl);
String innerText = driver.findElement(By
.xpath("//table[@width=\"270\"]/tbody/tr[4]/td"))
.getText();
System.out.println(innerText);
driver.quit();
}
Shortcut: Use Inspect Element for Accessing Tables in Selenium
If the index or attribute of an element is hard to obtain, the fastest way to generate the XPath is by using Inspect Element in modern browser DevTools.
Consider the example below from the Mercury Tours homepage.
Step 1
Right-click the target cell and pick Inspect to view the DOM path, then copy the full XPath.
Step 2
Look for the first “table” parent element and delete everything to the left of it.
Step 3
Prefix the remaining XPath with double forward slash “//” and copy it into your WebDriver code.
The WebDriver code below retrieves the inner text of the deeply nested element.
public static void main(String[] args) {
String baseUrl = "https://demo.guru99.com/test/newtours/";
WebDriver driver = new FirefoxDriver();
driver.get(baseUrl);
String innerText = driver.findElement(By
.xpath("//table/tbody/tr/td[2]"
+ "//table/tbody/tr[4]/td/"
+ "table/tbody/tr/td[2]/"
+ "table/tbody/tr[2]/td[1]/"
+ "table[2]/tbody/tr[3]/td[2]/font"))
.getText();
System.out.println(innerText);
driver.quit();
}
How to Count Rows and Columns in a Dynamic Web Table
Dynamic web tables, such as dashboards or search results, render different numbers of rows on every load. To handle them, use findElements to fetch every <tr> into a List, then loop through to read each cell. The snippet below counts rows and reads every cell in a table whose id is “customers”.
List<WebElement> rows = driver.findElements(
By.xpath("//table[@id='customers']//tr"));
System.out.println("Total rows: " + rows.size());
for (int i = 1; i <= rows.size(); i++) {
List<WebElement> cells = driver.findElements(
By.xpath("//table[@id='customers']//tr[" + i + "]/td"));
for (WebElement cell : cells) {
System.out.println(cell.getText());
}
}
Wrap the locator in a WebDriverWait with visibilityOfAllElementsLocatedBy when the table is loaded by AJAX. This prevents stale element references on slow-rendering grids.
Selenium 4 Relative Locators for Web Tables
Selenium 4 introduced relative locators that target elements by visual position. They are useful when XPath indexes break because rows are reordered. The methods above(), below(), toLeftOf(), toRightOf(), and near() all accept an anchor WebElement.
import static org.openqa.selenium.support.locators.RelativeLocator.with;
WebElement emailHeader = driver.findElement(By.xpath("//th[text()='Email']"));
WebElement emailCell = driver.findElement(
with(By.tagName("td")).below(emailHeader));
System.out.println(emailCell.getText());
Relative locators stay readable when the column order shifts. Pair them with explicit waits for the strongest results on data-driven pages.
AI Tools for Handling Dynamic Web Tables
AI-assisted testing platforms reduce locator maintenance on grids that change often. Tools like Testim, Mabl, and Functionize use computer vision plus DOM models to detect column shifts and self-heal locators. They identify rows by header text and cell similarity rather than fixed XPath indexes.
For pure Selenium projects, libraries such as Healenium wrap the WebDriver and rewrite broken locators at runtime. Combine these tools with WebDriverWait to keep dynamic table scripts stable without rewriting selectors after every UI change.
Summary
- By.xpath() is the most reliable way to access cells of a Web Table in Selenium.
- If counting siblings is hard, use a unique attribute as a predicate, prefixed with the @ symbol.
- findElements returns a List<WebElement> that supports row counting in dynamic tables.
- Selenium 4 relative locators (above, below, near) reduce dependency on positional XPath.
- Inspect Element in DevTools accelerates XPath generation for deeply buried cells.
- AI tools such as Testim, Mabl, and Healenium self-heal locators for changing grids.

.png)
.png)



















