In the last Selenium WebDriver tutorial, we learned various commonly and routinely used Selenium WebDriver commands, including important topics like handling iframe and exceptions in Selenium scripts.
Moving ahead in our comprehensive series of tutorials on Selenium, we will discuss handling Web tables, iframe, and dynamic elements which are an essential part of any web project.
Table of Contents:
Handling Web Tables, iframe, and Dynamic Elements
This tutorial comprises 3 different topics and their handling mechanisms in selenium script.
- Web Tables/HTML tables
- Frames
- Dynamic elements
#1) Web Tables/HTML Tables
In this module, we will learn about the web tables or HTML tables on a web page, tags available in HTML, and how to handle web tables dynamically.
Web tables are a group of elements that are logically stored in a row and column format. It is used to organize similar information on a web page.
Below is an example of an HTML table:
Below is the snippet of the HTML structure of an HTML table:
The tags listed below are defined in HTML tables:
1.’table’ tag defines an HTML table.
2.’tbody’ tag defines a container for rows and columns.
3.’tr’ defines rows in an HTML table.
4.’td’/’th’ defines the column of an HTML table.
Find the details of a web table:
There are many ways we can handle a web table.
Approach #1:
Below is the xpath of one of the cells in html table. Let’s say “firstname”
//div[@id=’main’]/table[1]/tbody/tr[1]/th[1]
tr[1] defines first row and th[1] defines the first column.
If several rows and columns are always constant, our HTML table will always have 5 rows and 3 columns.
for(int numberOfRows=1; numberOfRows<=5; numberOfRows++)
{
for(int numberOfCol=1; numberOfCol <=3; numberOfCol++)
{
System.out.println(driver.findElement(By.xpath
(“//div[@id='main']/table[1]/tbody/tr
[“+numberOfRows+”]/th[“+numberOfCol+”]”)));
}
}
Except for row and column numbers, each component of XPath remains the same. So you can iterate using “for loop” for each row and column as mentioned above.
Approach #2:
The first approach is best suitable for the table, which doesn’t change its dimensions and always remains the same. The above approach will not be a perfect solution for dynamically changing web tables.
Let’s take the above HTML table as an example:
WebElement htmltable=driver.findElement(By.xpath("//*[@id='main']/table[1]/tbody"));
List<WebElement> rows=htmltable.findElements(By.tagName("tr"));
for(int rnum=0;rnum<rows.size();rnum++)
{
List<WebElement> columns=rows.get(rnum).findElements(By.tagName("th"));
System.out.println("Number of columns:"+columns.size());
for(int cnum=0;cnum<columns.size();cnum++)
{
System.out.println(columns.get(cnum).getText());
}
}
Step #1: First get the entire HTML table and store this in a variable ‘htmltable’ of type web element.
Step #2: Get all the rows with the tag name ‘tr’ and store all the elements in a list of web elements. Now all the elements with the tag ‘tr’ are stored in the ‘rows’ list.
Step #3: Loop through each row and get the list of elements with tag ‘th’. ‘rows.get(0)’ will give the first row and ‘findElements(By.tagName(“th”))’ will give a list of columns for the row.
Step #4: Iterate using ‘columns.getsize()’ and get the details of each cell.
Note: The above approach will be most suitable if the table dimensions change dynamically.
This concludes the topic of how to handle web tables in selenium. Next, we will learn about handling an element inside a frame.
#2) Frames
In this section, we will learn about the frames on a web page and how to identify the frames. Also, we will find out how we can handle a frame in Selenium WebDriver.
Many developers like to place elements inside a frame. The frame is just like a container where a few elements can be grouped.
Identification of a frame:
Different ways to know if the element is present inside a frame or not
#1) Right-click on the element. Check if the “This Frame” option is available. If This frame option is available, it means that the element is inside a frame.
#2) View the page source of the web page and check if any tag is available for ‘iframe’.
Verify Number of frames in a webpage:
All the frames have the tag name as “iframe”.
List<WebElement> frameList=driver.findElements(By.tagName(“iframe”));
System.out.println(frameList.size());
In the above example: frameList will have all the list of frames and frameList.size() will give the number of frames.
Handling an element inside the frame:
If an element is inside a frame, then the control has to switch to the frame first and then start operating on the elements.
Step #1: To switch inside a frame:
driver.switchTo().frame(1); //pass frame number as parameter.
or
driver.switchTo().frame(“frame Name”); //pass frame name as parameter.
or
driver.switchTo().frame(“xpath of the frame”);
Step #2: After switching inside a frame, selenium will operate on elements.
driver.findElement(//*[@id='username']).sendKeys(“username”);
driver.findElement(//*[@id='pass']).sendKeys(“password”);
Here, we have learned how to handle an element inside frame and next we will cover about the different ways to handle dynamic elements.
#3) Dynamic Elements
In this section, we will learn different ways to handle dynamic elements and construct a generic Xpath.
In a few scenarios, element attributes change dynamically. It can be ‘id’, ’name’ etc.
Example: let’s say the ‘id’ of a username field is ‘username_123’ and the XPath will be
//*[@id=’username_123′] but when you open the page again the ‘id’ of ‘username’ field might have changed and the new value may be ‘username_234’.
Here, the test will fail because the selenium could not find the XPath you passed earlier as the id of the field has changed to some other value.
There are many approaches depending on the type of problem:
Problem Type #1: If part of the attribute value changes.
Example: As in the above example, id value changes but a few fields remain constant.
‘username_123’ changed to ‘username_234’ but ‘username’ always remained constant.
You can construct xpath as below:
driver.findElement(By.xpath(“//*[contains(@id,'username')]”)).sendKeys(“username”);
driver.findElement(By.xpath(“//*[starts-with(@id,'user')]”)).sendKeys(“username”);
‘contains’ is a Java method that checks if id contains the substring username.
starts-with() checks if any attribute starts with “user”.
Problem Type #2: If the entire value of the attribute changes dynamically.
Again, in this case, there could be different approaches:
For example: if the id of the ‘login’ field changes dynamically and there is no constant value to use the contains method.
Solution: Use of sendKeys.
Selenium provides different APIs to use function keys. For example, tab key, enter keys, F5, etc.
Step #1: Enter password
driver.findElement(By.id(“password”)).sendKeys(“password”));
Step 2: Use key functions to navigate to the element.
driver.findElement(By.id(“password”)).sendKeys(Keys.ENTER));
or
driver.findElement(By.id(“password”)).sendKeys(Keys.TAB));
Conclusion
Web tables, frames, and dynamic elements are essential parts of any web project. It is always desirable to write effective code to handle web tables and dynamic elements.
Understanding the construction of generic XPath is very helpful while handling dynamic elements. In case of a frame, your script has to switch the frame and then operate on the element.
Next tutorial #19: In the next Selenium tutorial, we will learn about types of exceptions and how to handle exceptions in Java in Selenium scripts.
Please post your queries related to Web tables, frames, and handling dynamic elements if you have any.
nice tutorial.
can we use class name or value instead of id in dynamic changing element?
How can i know a particular iframe is displayed or not on UI
Hi,
Can anyone advice how to write the code for example there is web table with multiple rows and columns, one of column is “NAME” and other column is “CITY” and many other columns too. So to write the code to get the CITY column text value of Robert (NAME Column) in web table, and here multiple rows of info available.
If you’re using the .NET version of WebDriver, I’ve just released an extension specifically designed to help with issues like this. You can find it here: https://github.com/jkindwall/TableDriver.NET. For this case, the code using TableDriver would look something like this:
Table table = Table.Create(driver.FindElement(By.Id(“the-table-id”)));
string city = table.FindCell(“NAME=Robert”, “CITY”).Element.Text;
…And if you’re using Java, the Java version of TableDriver is now available. More info here: https://github.com/jkindwall/TableDriver.Java
Get an error “The method findElements(By) is undefined for the type Object” at line 6 while trying to run the code for dynamic web table.
Can you help me resolve it.
i new selenium . while testing a application
I am facing problem while finding fa fa icon in table for a recor .
really helps
very nice tutorial
In dynamic webtable, data is presented number of times.Now i want to count the repeated values in table.
How can i get repeated data ??
How to get the particular cell data?in web table
For example in a table 10 rows and 20 colms are there.I want only 9 colom and 10 row data.
Hi,
Thanks a lot for the useful solutions.
I have screen with one to many mapping, example
I have a user group “ABC” and it is having multiple users attached it in the multiple entry block of the screen.
Record Heading
User ID Name Age Sex
Data should be as below
1001 aaaaaa 20 Male
1002 bbbbbb 25 Female
1003 cccccc 22 Male
1004 dddddd 30 Female
In this scenario, How to add these test cases to the Excel sheet and add these values to the screen while running the automation script.
your help will be highly appreciated
Kind Regards
Benc
thanks a lot !!! extremely useful tutorial and very well explained
How to declare all frames in method as function which could be called in other program as generic function??
Ex:
public static void Machint_Click(String LocatorType, String LocatorValue, String WaitType) throws Exception
{
try
{
locator = locatorValue(LocatorType, LocatorValue);
element = driver.findElement(locator);
Machint_Wait(WaitType);
element.click();
Thread.sleep(2000);
}
catch (NoSuchElementException e)
{
System.err.format(LocatorType+ ” is invalid”);
}
}
In #1 Approach to find the data from web table.the xpath is not working which is as shown :
//div[@id=’main’]/table[1]/tbody/tr[1]/th[1]
However, I checked it, it is td[1] NOT th[1].
In other words it should be:
//div[@id=’main’]/table[1]/tbody/tr[1]/td[1]
#saikrishna
first needs to traverse the table row and traverse row’s column saved it list now you can play with list and can get the particular cell value
//find the table
Arraylist tab =table.findElements(By.tagName(“tr”));
//store the table row’s in table_row object
ArrayList table_row =(ArrayList) table.findElements(By.tagName(“tr”));
//get the row count
int rowcount=table_row.size();
System.out.println(rowcount);
//traverse the row to get column
for(int row=1;row<rowcount;row++)
{
//store the row's colmun in row_column object
ArrayList row_column =(ArrayList) table_row.get(row).findElements(By.tagName(“td”));
//get the column size
int columncount=row_column.size();
System.out.println(row+”rows column count is”+columncount);
//traverse row’s column’s
//for(int col=0;col<columncount;col++)
{
//get the cell value
String cellValue=row_column.get(col).getText();
values.add(cellValue);
System.out.println(row+"rowth"+col+"colth"+cellValue);
}
}
// if you want to reduce the table row's column
you can reduce the for loop condition statement
for(int row=1;row<rowcount;row++)
you can change the rowcount to actual need row_count
same for column
for(int col=0;col<columncount;col++)
change the columncount to actual need columncount
How to get how many frames in a web page? pls help to me
Nice one
If I want to get text of perticular cell but without using Xpath, could any one help me for this
Excellent solutions !!! Please keep posting on such new stuff in Selenium
Thank u for your solution
Very well explained… It’s understandable for any body… Thanks… Keep posting like this
this is useful. and also i want to know meaning of web tables and its usage. where it is used? any one tell the as
Hi,
Please clarify by below doubt.
I need to select a row in the table based on the value present in a particular cell. Currently, I am using xpath as driver.findElement(By.xpath(“//div//table[@id=”]/tbody[1]/tr[12]/td[1]”)); to select that particular row.
Is it possible to select the row by giving the value present in the particular cell instead of giving row id like tr[12]?
Please help.
There is now a Java version of TableDriver available here (https://github.com/jkindwall/TableDriver.Java)
There are ways to do this simply using xpaths, but it can get kind of long and convoluted. However, if you happen to be using the .NET version of WebDriver, I’ve just released an extension called TableDriver.NET that makes working with tables and specifically finding rows by their contents much easier. You can find the project here: https://github.com/jkindwall/TableDriver.NET. Here’s a quick example of how its used:
Assuming we are working with the html table in section #1 of this article, and we want to look up how many points Eve Jackson has, with the TableDriver extension to WebDriver, the code would look like this:
Table table = Table.Create(driver.FindElement(By.Id(“main”)));
string points = table.FindCell(“Firstname=Eve&Lastname=Jackson”, “Points”).Element.Text;
Data Parser error is coming, cf= dataparser(filepath, sheetname) –in this line and showing null pointer exception, while trying to execute, can anyone help.
How to get data from excel sheet that has n no of rows and sheet, how to handle this with array?
I want to get html page source , after loading all dynamic data .
is any other way is available instead of using findelements or some hord coding div elemets ???? .. please help … !
public void f() throws IOException, BiffException {
int rows = driver.findElements(By.tagName(“tr”)).size();
System.out.println(“totalrows–“+rows);
int columns = driver.findElements(By.xpath(“//*[@id=’leftcontainer’]/table/thead/tr[1]/th”)).size();
System.out.println(“totalcolumns–“+columns);
List Wvalues = new ArrayList();
for(int m=1;m<=rows;m++)
{
for(int n=1;n<=columns;n++)
{
String data = driver.findElement(By.xpath("//*[@id='leftcontainer']/table/tbody/tr["+m+"]/td["+n+"]")).getText();
System.out.println(data);
Wvalues.add(data);
how could i print the rows and columns text values in selenium. and how could i get the xlvalues from rows and columns from excel sheet.
In my use case I am trying to return the .getText() of my elements tags, if there is text. If no text I need to check if my element has a child element like an tag and get that child elements .getAttribute(“title”) if there is a child element. Any Guidance on this process would be appreciated.
hello,
You can use the xpath followed by /. (ex: //span[@class=’reply’]/.)
That this in List of webelements and iterate:
List element= driver.findElements(By.xpath(“//span[@class=’reply’]/.”));
For(WebElement el1: element)
{
String title=el1. .getAttribute(“title”);
system.out.println(title);
}
hello,
You can use the xpath followed by /. (ex: //span[@class=’reply’]/.)
It returns child node of selected elements
Take this in List of WebElements and iterate:
List element= driver.findElements(By.xpath(“//span[@class=’reply’]/.”));
For(WebElement el1: element)
{
String title=el1. .getAttribute(“title”);
system.out.println(title);
}
??????????css????????css????Xpath????
Excellent, the way of explanation is very nice.
I appreciate the efforts but i also suggest to add few more real time problems.
@Monisha
I have find the solution to the problem you are facing
please use the two for loop to generate the xpath dynamically and it should work .It worked for me
How to get Html table data which is not having Id, class name and having multiple tables divs using c#Selinium
HI Thanks for your tutorial, it is really helpful.I am working on webtable it contains 18 records right now , 10 records in one page and remaining in 2 nd page and so on depends on no of records. I would like to get total no of records ,how to iterate through no of pages.
Thanks in advance.
I am learning selenium, thanks for the post.
I am facing one problem.
i have one tree view control. nodes creating dynamically with context menu – insert command.
I need get that textbox and to give node value.
i have tried with given options in – Dynamic elements part but i didn’t get solution.
In mycase javascript using to insert a textbox and click on anywhere in page, box should disapper.
can you please help in this issue?
thank you for helping us …
HI Thanks for your tutorial, it is really helpful.I am working on webtable it contains 18 records right now , 10 records in one page and remaining in 2 nd page and so on depends on no of records. I would like to get total no of records ,how to iterate through no of pages.
Thanks in advance.
Table data can be fetched in another way…its quite simple for me….
WebDriver dr=new FirefoxDriver();
dr.manage().window().maximize();
dr.get(“xyz.com”);
List td=dr.findElements(By.xpath(“//td”));
String data[]=new String[td.size()];
for(int i=0;i<td.size()-1;i++){
WebElement wel=td.get(i);
String x=data[i]=wel.getText();
System.out.println(x);
Hi,
please help me in getting the cell value of a dynamic webtable.
i am trying to automate a scenario to cancel a room in the above mention site based on the order#. These order numbers were displayed in a dynamic webtable. i want to read the each order# and compare with the order# to be cancelled. I am able to iterate the table but couldn’t get the value of the cell. Please help , thanks in advance