Friday, September 13, 2019

Post#49.Handling Web Table in Selenium


Handling Web Tables in Selenium WebDriver:

o    Step By Step Process Of Determining XPath For A Cell In The Web Table
o    How To Access Nested Tables In Selenium WebDriver
o    How To Handle Dynamic Tables In Selenium WebDriver


Web tables are most often used to represent information on a web page. And Software testers can use Selenium WebDriver for accessing tables and reading data at runtime. In this post, I will explain you multiple ways for handling Web tables in WebDriver. I will cover static tables, nested tables, and dynamic tables so that you can understand the concept thoroughly.
To help you out, I have added code examples for each method given here to handle the web tables. So that you can start practicing them even while you are reading this post. But apart from the Selenium WebDriver commands, you must also know how to use XPath to locate any element in the web table.
So let’s begin to learn the best ways out for handling Web tables.
Handling Web Tables in Selenium WebDriver.
Generally, there is an <id> or <name> attribute associated with all the HTML fields. And that becomes a unique identifier for locating the element on the web page.
But it isn’t the way that you can apply on a table for accessing its cells. Not even you can use methods that you normally do with Selenium like <By.id()>, <By.name()>, and <By.cssSelector()> to find a web element. Rather you should go with the <XPath> locator and <By.xpath()> method for handling Web tables and cells.
1.2- Step By Step Process Of Determining XPath For A Cell In The Web Table.
It’s essential for you to learn about XPath. It’ll help you in handling Web tables and accessing web elements. First of all, consider the following HTML code.
<html>
<head>
    <title>Sample Table</title>
</head>
<body>
    <table border="1">
        <tbody>
            <tr>
                <td>cell one</td>
                <td>cell two</td>
            </tr>
            <tr>
                <td>cell three</td>
                <td>cell four</td>
            </tr>
        </tbody>
    </table>
</body>
</html>



We will use the XPath locator to get the inner text of cell containing the text “cell four”.
Let’s find out the XPath for cell no. four.
Step 1 – Set The Parent Element (Table).
XPath locators in WebDriver always start with a double forward slash “//” followed by the parent element tag. Since we are dealing with tables, the parent element should always be the <table> tag. The first portion of our XPath locator should start with the “//table”.
Step 2 – Add The Child Elements.
The element immediately under <table> tag is <tbody> so we can say that <tbody> is the “child” of <table>. And also, <table> is the “parent” of <tbody>.
While forming an XPath, you need to place all child elements to the right of their parent element. And please remember to use a forward slash to chain the elements.

Step 3 – Add Predicates.
The <tbody> element contains two <tr> tags. We can now say that these two <tr> tags are “children” of <tbody>. Other way round <tbody> is parent of both the <tr> elements.
The two <tr> elements having same parent <tbody> can be called as siblings. Thus Siblings refer to child elements having the same parent.
To access the <td> (the one with the text “cell four”), we have to first go to the second <tr> and not the first. If we simply write “//table/tbody/tr”, then we will be accessing the first <tr> tag.
So, how to access the second <tr> then? The answer to this is to use Predicates.
Predicates represent the index of HTML child elements that are Siblings and are enclosed in a pair of square brackets “[ ]”. This index clearly distinguishes a child element from its siblings. Since the <tr> we need to access is the second one, so we’ll use “[2]” as the predicate.
//table/tbody/tr[2]
If you don’t use any predicate, then XPath will always point to the first sibling. Hence, both of them should access the first <tr>.
//table/tbody/tr
The above code will automatically locate the first <tr> as no predicate is specified. But the below line will select the same row because the predicate value is “1”.
//table/tbody/tr[1]

Step 4 – Add The Succeeding Child Elements Using The Appropriate Predicates.
In the previous steps, we’d reached to the second row. Next, we’ve to move to the second <td> element. Applying the same technique that we have used in steps 2 and 3, the XPath will come out to be the one shown below.
//table/tbody/tr[2]/td[2]
Using the above XPath locator, you can access the cell and obtain its inner text using the code below.
public static void main(String[] args) {
String baseUrl = “file: ///D:/Technology/Selenium/Table.html”;
Webdriver driver = new FirefoxDriver();
driver.get(baseUrl);
String cellText = driver.findElement(By.xpath(“ //table/tbody/tr[2]/td[2]”)).getText();
System.out.println(“Text in Cell four is: ”+cellText); driver.quit();
}
Output:
Text in Cell four is: cell four.
How to Access Nested Tables in Selenium WebDriver?

Nested tables are HTML tables defined within a table. For handling HTML tables you can try the same way as given above. Consider the below code.
<html>
<head>
    <title>Sample Table</title>
</head>
<body>
    <table border="1">
        <tbody>
            <tr>
                <td>NAME</td>
                <td>ADDRESS</td>
            </tr>
            <tr>
                <td>ALICE</td>
                <td>
                    <!-- inner table -->
                    <table border="1">
                        <tbody>
                            <tr>
                                <td> Elephanta Road</td>
                                <td> Delhi</td>
                            </tr>
                            <tr>
                                <td> Electronic City</td>
                                <td> Noida</td>
                            </tr>
                        </tbody>
                    </table>
                </td>
            </tr>
        </tbody>
    </table>
</body>
</html>

To access the cell with the text “Electronic City” using the “//parent/child” and predicate concepts that we learned in the previous section, we get the following XPath.

//table/tbody/tr[2]/td[2]/table/tbody/tr/td[2]
Below is the complete Selenium WebDriver code for handling HTML tables and the text of the cell that we discussed.
public static void main(String[] args) {
String baseUrl = “file: ///D:/Technology/Selenium/ Nested_Table.html”;
Webdriver driver = new FirefoxDriver();
driver.get(baseUrl);
String cellText = driver.findElement(By.xpath( //table/tbody/tr[2]/td[2]/table/tbody/tr/td[2]”)).getText();
System.out.println(“Text in Cell five is: ”+cellText); driver.quit();
}
Output:
Text in Cell is: Electronic city.
How To Handle Dynamic Tables In Selenium WebDriver?

Accessing data from table becomes difficult in the following cases.
1- When table rows and columns change after loading the page.
2- When a table has some rows with more cells and some rows with fewer cells, then you need to refactor the code to handle this.
For handling HTML tables you can try the same way as given above. Consider the below HTML code.
<html>
<head>
    <title>Sample Table</title>
</head>
<body>
    <table border="1">
        <tbody>
            <tr>
                <td>A</td>
                <td>B</td>
                <td>C</td>
                <td>D</td>
            </tr>
            <tr>
                <td>E</td>
                <td>F</td>
                <td>G</td>
            </tr>
            <tr>
                <td>H</td>
                <td>I</td>
                <td>J</td>
                <td>K</td>
            </tr>
            <tr>
                <td>L</td>
                <td>M</td>
            </tr>
            <tr>
                <td>N</td>
                <td>O</td>
                <td>P</td>
            </tr>
        </tbody>
    </table>
</body>
</html>


Above HTML code forms a dynamic table with rows having inconsistent no. of cells. The logic to read data from such a table is to first move to a row of that table, then count the number of cells in that row and based on the number of cells retrieve data from a particular cell.
1.3.2- Sample Selenium WebDriver Code for Handling HTML Tables.
import java.util.List;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
public class dynamic_table {
public static void main(String[] args) throws InterruptedException {
WebDriver driver = new FirefoxDriver();
driver.manage().window().maximize();
driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
String baseUrl = "file:///D:/Technology/Selenium%20cases/dynamic_table.html";
driver.get(baseUrl);
//To locate table.
WebElement mytable = driver.findElement(By.xpath("html/body/table/tbody"));
//To locate rows of table.
List < WebElement > rows_table = mytable.findElements(By.tagName("tr"));
//To calculate no of rows In table.
int rows_count = rows_table.size();
//Loop will execute for all the rows of the table
for (int row = 0; row < rows_count; row++) {
//To locate columns(cells) of that specific row.
List < WebElement > Columns_row = rows_table.get(row).findElements(By.tagName("td"));
//To calculate no of columns(cells) In that specific row.
int columns_count = Columns_row.size();
System.out.println("Number of cells In Row " + row + " are " + columns_count);
//Loop will execute till the last cell of that specific row.
for (int column = 0; column < columns_count; column++) {
//To retrieve text from the cells.
String celltext = Columns_row.get(column).getText();
System.out.println("Cell Value Of row number " + row + " and column number " + column + " Is " + celltext);
}
}
}
}

Exercise:
Print all the value present in the table.

package pack2;
import java.util.List;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;

public class WebTableEx {

            public static void main(String[] args) {
                        System.setProperty("webdriver.gecko.driver","c:\\path\\geckodriver.exe");
                        FirefoxDriver driver = new FirefoxDriver();
                        driver.manage().window().maximize();
                        driver.get("http://www.timeanddate.com/worldclock/");
                        WebElement tab = driver.findElement(By.xpath("html/body/div[1]/div[7]/section[2]/div[1]/table"));
                        List<WebElement> rows =tab.findElements(By.tagName("tr"));
                        System.out.println(rows.size());
                        for(int i=0;i<rows.size();i++)
                        {
                                    List<WebElement> cols =rows.get(i).findElements(By.tagName("td"));
                                   
                                    for(int j=0;j<cols.size();j++)
                                    {
                                                System.out.print(cols.get(j).getText()+"--");
                                    }
                                    System.out.println("");
                        }
driver.quit();
            }

}


No comments:

Post a Comment