Sunday, October 18, 2015

Multiple Column Sorting On WebTable

On previous post we learn how to handle webtable in a better manner. Now we try to validate the webtable with sorting facility.

Steps 1 :
 Load page which contains WebTable
e.g :
driver.get("https://en.wikipedia.org/wiki/List_of_largest_oil_and_gas_companies_by_revenue");

Step 2 :
 Access the WebTable.
e.g :
WebTable table =WebTable.getTable(driver.findElement(By.xpath(".//*[@id='mw-content-text']/table/tbody/tr/td/table")));

Step 3 :
  Store each row as a object in a list.
e.g :
for (int tableBodyRow =0; tableBodyRow < table.getTableBody().getRowCount();tableBodyRow++) {
TableDataObject tabObj = new TableDataObject();
for (int tableBodyColumn = 0; tableBodyColumn <  table.getTableBody().getRow(tableBodyRow).getCoulmnCount(); tableBodyColumn++) {
//System.out.print(" TableBody Row : " + (tableBodyRow+1) + " TableBody Column : " + (tableBodyColumn+1)); 
if(tableBodyColumn==0){
//System.out.println(" TableBody Cell Text : " + table.getTableBody().getRowElement(tableBodyRow).findElement(By.xpath(".//span/a/img")).getAttribute("alt"));
tabObj.setCountry_Name(table.getTableBody().getRowElement(tableBodyRow).findElement(By.xpath(".//span/a/img")).getAttribute("alt").trim());
}
else if(tableBodyColumn ==1){
//System.out.println(" TableBody Cell Text : " + table.getTableBody().getRow(tableBodyRow).getCell(tableBodyColumn).getText());
tabObj.setCompany_Name(table.getTableBody().getRow(tableBodyRow).getCell(tableBodyColumn).getText().trim());
}
else if(tableBodyColumn ==2){
//System.out.println(" TableBody Cell Text : " + table.getTableBody().getRow(tableBodyRow).getCell(tableBodyColumn).getText());
tabObj.setRevenue_2014(table.getTableBody().getRow(tableBodyRow).getCell(tableBodyColumn).getText().trim());
}
}
ltTableDataObj.add(tabObj);
Step 4 :
 Now click on the desired column header to sort the table.

e.g :
driver.findElement(By.cssSelector(".headerSort:first-child+th")).click();

Step 5 :
 Now sort the previously stored list.

e.g :
Collections.sort(ltTableDataObj, new TableDataObject.CompanyNameSort()); 

This is the most important part of this post. Sorting a list of any object can not be done using only sort method. To get this facility from object we need to implement comparable or comparator. If we use comparable then we can choose only one field to sort but here we need to sort the objects against different column so we implement comparator.

e.g :
/**
 * Comparator implementation using anonymous class
 */
static Comparator<TableDataObject> country_NameComparator = new Comparator<TableDataObject>() {
@Override
public int compare(TableDataObject o1, TableDataObject o2) {
if(o1.getCountry_Name().equals(o2.getCountry_Name())){
if(o1.getRevenue_2014().compareTo(o2.getRevenue_2014())>1){
return o2.getCountry_Name().compareTo(o1.getCountry_Name());
}
else {
return o1.getCountry_Name().compareTo(o2.getCountry_Name());
}

}
else {
return o1.getCountry_Name().compareTo(o2.getCountry_Name());
}
}
};

/**
 * Comparator implementation using sub class
 */
static class CompanyNameSort implements Comparator<TableDataObject>{

@Override
public int compare(TableDataObject o1, TableDataObject o2) {
return o1.company_Name.compareToIgnoreCase(o2.company_Name);
}

}

Step 6 :
 Now iterate on the webtable again and store this on another different list of object.

Step 7 :
 Now compare two list

e.g :
System.out.println(ltTableDataObj.equals(ltTableDataObj2));

Comple Code Given Below :

Table Object Class :

import java.util.Comparator;

public class TableDataObject {
private String country_Name;
private String company_Name;
private String revenue_2014;

@Override
public String toString() {
return "TableDataObject [country_Name=" + country_Name + ", company_Name=" + company_Name + ", revenue_2014="
+ revenue_2014 + "]";
}

@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((company_Name == null) ? 0 : company_Name.hashCode());
result = prime * result + ((country_Name == null) ? 0 : country_Name.hashCode());
result = prime * result + ((revenue_2014 == null) ? 0 : revenue_2014.hashCode());
return result;
}

@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
TableDataObject other = (TableDataObject) obj;
if (company_Name == null) {
if (other.company_Name != null)
return false;
} else if (!company_Name.equals(other.company_Name))
return false;
if (country_Name == null) {
if (other.country_Name != null)
return false;
} else if (!country_Name.equals(other.country_Name))
return false;
if (revenue_2014 == null) {
if (other.revenue_2014 != null)
return false;
} else if (!revenue_2014.equals(other.revenue_2014))
return false;
return true;
}

public String getCountry_Name() {
return country_Name;
}

public void setCountry_Name(String country_Name) {
this.country_Name = country_Name;
}

public String getCompany_Name() {
return company_Name;
}

public void setCompany_Name(String company_Name) {
this.company_Name = company_Name;
}

public String getRevenue_2014() {
return revenue_2014;
}

public void setRevenue_2014(String reevenue_2014) {
this.revenue_2014 = reevenue_2014;
}
/**
* Implement Comparator using anonymous class
*/
static Comparator<TableDataObject> country_NameComparator = new Comparator<TableDataObject>() {
@Override
public int compare(TableDataObject o1, TableDataObject o2) {
if(o1.getCountry_Name().equals(o2.getCountry_Name())){
if(o1.getRevenue_2014().compareTo(o2.getRevenue_2014())>1){
return o2.getCountry_Name().compareTo(o1.getCountry_Name());
}
else {
return o1.getCountry_Name().compareTo(o2.getCountry_Name());
}

}
else {
return o1.getCountry_Name().compareTo(o2.getCountry_Name());
}
}
};
/**
* Implement Comparator using inner class
*/
static class CompanyNameSort implements Comparator<TableDataObject>{

@Override
public int compare(TableDataObject o1, TableDataObject o2) {
return o1.company_Name.compareToIgnoreCase(o2.company_Name);
}
}
}

Test Class :

import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxBinary;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxProfile;

import com.automation.webtable.table.WebTable;

public class AccessTable {
public static void main(String[] args) {
List<TableDataObject> tableExpected = new ArrayList<TableDataObject>();
List<TableDataObject> tableOnPage = new ArrayList<TableDataObject>();
WebDriver driver = new FirefoxDriver(new FirefoxBinary(new File("G:/Program Files/Mozilla Firefox/firefox.exe")),new FirefoxProfile());
try{
driver.get("https://en.wikipedia.org/wiki/List_of_largest_oil_and_gas_companies_by_revenue");
WebTable table =WebTable.getTable(driver.findElement(By.xpath(".//*[@id='mw-content-text']/table/tbody/tr/td/table")));
System.out.println("Table Body Row Count : " + table.getTableBody().getRowCount() + " Table Body Column Count : " + table.getTableBody().getRow(0).getCoulmnCount());
for (int tableBodyRow =0; tableBodyRow < table.getTableBody().getRowCount();tableBodyRow++) {
TableDataObject tabObj = new TableDataObject();
for (int tableBodyColumn = 0; tableBodyColumn <  table.getTableBody().getRow(tableBodyRow).getCoulmnCount(); tableBodyColumn++) { 
if(tableBodyColumn==0){
tabObj.setCountry_Name(table.getTableBody().getRowElement(tableBodyRow).findElement(By.xpath(".//span/a/img")).getAttribute("alt").trim());
}
else if(tableBodyColumn ==1){
tabObj.setCompany_Name(table.getTableBody().getRow(tableBodyRow).getCell(tableBodyColumn).getText().trim());
}
else if(tableBodyColumn ==2){
tabObj.setRevenue_2014(table.getTableBody().getRow(tableBodyRow).getCell(tableBodyColumn).getText().trim());
}
}
tableExpected.add(tabObj);
}
driver.findElement(By.cssSelector(".headerSort:first-child")).click();
Collections.sort(tableExpected, TableDataObject.country_NameComparator);
System.out.println("After Sorted Data : "+ tableExpected);
for (int tableBodyRow =0; tableBodyRow < table.getTableBody().getRowCount();tableBodyRow++) {
TableDataObject tabObj = new TableDataObject();
for (int tableBodyColumn = 0; tableBodyColumn <  table.getTableBody().getRow(tableBodyRow).getCoulmnCount(); tableBodyColumn++) {
if(tableBodyColumn==0){
tabObj.setCountry_Name(table.getTableBody().getRowElement(tableBodyRow).findElement(By.xpath(".//span/a/img")).getAttribute("alt").trim());
}
else if(tableBodyColumn ==1){
tabObj.setCompany_Name(table.getTableBody().getRow(tableBodyRow).getCell(tableBodyColumn).getText().trim());
}
else if(tableBodyColumn ==2){
tabObj.setRevenue_2014(table.getTableBody().getRow(tableBodyRow).getCell(tableBodyColumn).getText().trim());
}
}
tableOnPage.add(tabObj);
}
System.out.println("New Table :"+ tableOnPage);
System.out.println(tableExpected.equals(tableOnPage));
driver.findElement(By.cssSelector(".headerSort:first-child+th")).click();

/**
* Sort using inner class which is defined in TableDataObject class.
*/
//Collections.sort(ltTableDataObj, new TableDataObject.CompanyNameSort());
Collections.sort(tableExpected, new Comparator<TableDataObject>() {

@Override
public int compare(TableDataObject o1, TableDataObject o2) {
return o1.getCompany_Name().compareToIgnoreCase(o2.getCompany_Name());
}
});
System.out.println("After Sorted Data : "+ tableExpected);
for (int tableBodyRow =0; tableBodyRow < table.getTableBody().getRowCount();tableBodyRow++) {
TableDataObject tabObj = new TableDataObject();
for (int tableBodyColumn = 0; tableBodyColumn <  table.getTableBody().getRow(tableBodyRow).getCoulmnCount(); tableBodyColumn++) {
//System.out.print(" TableBody Row : " + (tableBodyRow+1) + " TableBody Column : " + (tableBodyColumn+1)); 
if(tableBodyColumn==0){
//System.out.println(" TableBody Cell Text : " + table.getTableBody().getRowElement(tableBodyRow).findElement(By.xpath(".//span/a/img")).getAttribute("alt"));
tabObj.setCountry_Name(table.getTableBody().getRowElement(tableBodyRow).findElement(By.xpath(".//span/a/img")).getAttribute("alt").trim());
}
else if(tableBodyColumn ==1){
//System.out.println(" TableBody Cell Text : " + table.getTableBody().getRow(tableBodyRow).getCell(tableBodyColumn).getText());
tabObj.setCompany_Name(table.getTableBody().getRow(tableBodyRow).getCell(tableBodyColumn).getText().trim());
}
else if(tableBodyColumn ==2){
//System.out.println(" TableBody Cell Text : " + table.getTableBody().getRow(tableBodyRow).getCell(tableBodyColumn).getText());
tabObj.setRevenue_2014(table.getTableBody().getRow(tableBodyRow).getCell(tableBodyColumn).getText().trim());
}
}
tableOnPage.add(tabObj);
}
System.out.println("New Table :"+ tableOnPage);
System.out.println(tableExpected.equals(tableOnPage));
}
finally{
driver.close();
}
}
}

WebTable Code:

Complete Code given on previous post.


Sunday, October 11, 2015

Complete Code Of WebTable Using Selenium WebDriver

On previous post we learn how to play with WebTable in a simple manner. Now we will try to write a code where we can separate our table body cell,row,header and footer part.

So code example is given below :

This class is our main entry point.
package com.automation.webtable.table;

import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;

import com.automation.webtable.cellandrow.WebTableRow;
import com.automation.webtable.part.WebTablePart;

public class WebTable {
private WebElement tableElement;

private WebTable(WebElement tableElement) {
this.tableElement = tableElement;
}

public static WebTable getTable(WebElement tableElement) {
return new WebTable(tableElement);
}

public WebElement getTableCaptionElement() {
// return tableElement.findElement(By.tagName("caption"));
return tableElement.findElement(By.xpath("./caption"));
}

public String getTableCaptionText() {
return getTableCaptionElement().getText();
}

public WebTableRow getRow(int index) {
return new WebTableRow(getRowElement(index));
}

public WebElement getRowElement(int index) {
// WebElement rowElement = (WebElement) tableElement.findElements(By.tagName("tr")).get(index);
WebElement rowElement = (WebElement) tableElement.findElements(By.xpath("./tr")).get(index);
return rowElement;
}

public int getRowCount() {
return tableElement.findElements(By.tagName("tr")).size();
}

public WebTablePart getTableHeader() {
return new WebTablePart(getTableHeaderElement());
}

public WebElement getTableHeaderElement() {
// WebElement tableHeadElement = tableElement.findElement(By.tagName("thead"));
WebElement tableHeadElement = tableElement.findElement(By.xpath("./thead"));
return tableHeadElement;
}

public WebTablePart getTableFooter() {
return new WebTablePart(getTableFooterElement());
}

public WebElement getTableFooterElement() {
// WebElement tableFootElement = tableElement.findElement(By.tagName("tfoot"));
WebElement tableFootElement = tableElement.findElement(By.xpath("./tfoot"));
return tableFootElement;
}

public WebTablePart getTableBody() {
return new WebTablePart(getTableBodyElement());
}

public WebElement getTableBodyElement() {
// WebElement tableBodyElement = tableElement.findElement(By.tagName("tbody"));
WebElement tableBodyElement = tableElement.findElement(By.xpath("./tbody"));
return tableBodyElement;
}
}

This class is created to handle Row for a particular part of the WebTable.
package com.automation.webtable.part;

import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;

import com.automation.webtable.cellandrow.WebTableRow;

public class WebTablePart {
private WebElement tablePartElement;

public WebTablePart(WebElement tablePartElement) {
this.tablePartElement = tablePartElement;
}

public WebTableRow getRow(int index) {
return new WebTableRow(getRowElement(index));
}

public WebElement getRowElement(int index) {
// WebElement rowElement = (WebElement) tablePartElement.findElements(By.tagName("tr")).get(index);
WebElement rowElement = (WebElement) tablePartElement.findElements(By.xpath("./tr")).get(index);
return rowElement;
}
public int getRowCount() {
// return tablePartElement.findElements(By.tagName("tr")).size();
return tablePartElement.findElements(By.xpath("./tr")).size();
}
}

This class is created to handle Row for the particular part of a Table. 

package com.automation.webtable.cellandrow;

import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;

public class WebTableRow {
private WebElement rowElement;

public WebTableRow(WebElement rowElement) {
this.rowElement = rowElement;
}

public WebTableCell getCell(int index) {
return new WebTableCell(getCellElement(index));
}

public WebElement getCellElement(int index) {
// WebElement cellElement = (WebElement) rowElement.findElements(By.tagName("td")).get(index);
WebElement cellElement = (WebElement) rowElement.findElements(By.xpath("./td")).get(index);
return cellElement;
}

public int getCoulmnCount() {
// return rowElement.findElements(By.tagName("td")).size();
return rowElement.findElements(By.xpath("./td")).size();
}

public int getHeaderCoulmnCount() {
// return rowElement.findElements(By.tagName("th")).size();
return rowElement.findElements(By.xpath("./th")).size();
}

public WebTableCell getHeaderCell(int index) {
return new WebTableCell(getHeaderCellElement(index));
}

public WebElement getHeaderCellElement(int index) {
// WebElement cellElement = (WebElement) rowElement.findElements(By.tagName("th")).get(index);
WebElement cellElement = (WebElement) rowElement.findElements(By.xpath("./th")).get(index);
return cellElement;
}
}

This class is created to handle Row of a particular Cell. 
package com.automation.webtable.cellandrow;

import org.openqa.selenium.Dimension;
import org.openqa.selenium.Point;
import org.openqa.selenium.WebElement;

public class WebTableCell {
 private WebElement cellElement;
 
 public WebTableCell(WebElement cellElement)
 {
   this.cellElement = cellElement;
 }
 
 public String getText() {
   return cellElement.getText();
 }
 
 public String getAttribute(String attribute)
 {
   return cellElement.getAttribute(attribute);
 }
 
 public Point getLocation() {
   return cellElement.getLocation();
 }
 
 public Dimension getSize() {
   return cellElement.getSize();
 }
 
 public boolean isDisplayed() {
   return cellElement.isDisplayed();
 }
 
 public boolean isEnabled() {
   return cellElement.isEnabled();
 }
}

This class is a example class for accessing WebTable. 
import java.io.File;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxBinary;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxProfile;

import com.automation.webtable.table.WebTable;

public class AccessTable {
public static void main(String[] args) {
WebDriver driver = new FirefoxDriver();
try{
driver.get("https://en.wikipedia.org/wiki/List_of_largest_oil_and_gas_companies_by_revenue");
WebTable table =WebTable.getTable(driver.findElement(By.xpath(".//*[@id='mw-content-text']/table/tbody/tr/td/table")));
System.out.println("Table Head Row Count : " + table.getTableHeader().getRowCount() + " Table Head Column Count : " + table.getTableHeader().getRow(0).getHeaderCoulmnCount());
System.out.println("Table Body Row Count : " + table.getTableBody().getRowCount() + " Table Body Column Count : " + table.getTableBody().getRow(0).getCoulmnCount());
System.out.println("Table Footer Row Count : " + table.getTableFooter().getRowCount());
for (int tableHeaderRow =0; tableHeaderRow < table.getTableHeader().getRowCount();tableHeaderRow++) {
for (int tableHeaderColumn = 0; tableHeaderColumn < table.getTableHeader().getRow(tableHeaderRow).getHeaderCoulmnCount(); tableHeaderColumn++) {
System.out.println(" TableHeader Row : " + (tableHeaderRow+1) + " TableHeader Column : " + (tableHeaderColumn+1) + 
" TableHeader Cell Text : " + table.getTableHeader().getRow(tableHeaderRow).getHeaderCell(tableHeaderColumn).getText());
}
}
for (int tableBodyRow =0; tableBodyRow < table.getTableBody().getRowCount();tableBodyRow++) {
for (int tableBodyColumn = 0; tableBodyColumn <  table.getTableBody().getRow(tableBodyRow).getCoulmnCount(); tableBodyColumn++) {
System.out.print(" TableBody Row : " + (tableBodyRow+1) + " TableBody Column : " + (tableBodyColumn+1)); 
if(tableBodyColumn==0){
System.out.println(" TableBody Cell Text : " + table.getTableBody().getRowElement(tableBodyRow).findElement(By.xpath(".//span/a/img")).getAttribute("alt"));
}
else
System.out.println(" TableBody Cell Text : " + table.getTableBody().getRow(tableBodyRow).getCell(tableBodyColumn).getText());
}
}
for (int tableFooterRow =0; tableFooterRow < table.getTableFooter().getRowCount();tableFooterRow++) {
for (int tableFooterColumn = 0; tableFooterColumn < table.getTableFooter().getRow(tableFooterRow).getCoulmnCount(); tableFooterColumn++) {
System.out.println(" TableFooter Row : " + (tableFooterRow+1) + " TableFooter Column : " + (tableFooterColumn+1) + 
" TableFooter Cell Text : " + table.getTableFooter().getRow(tableFooterRow).getCell(tableFooterColumn).getText());
}
}
}
finally{
driver.close();
}

}
}


Saturday, October 10, 2015

WebTable Handling Using Selenium WebDriver

It is  nothing but a table in HTML where we can represent all data within a tabular form in web page.

Q. How we can understand that data represented in a tabular form ?
Ans : It is very easy to understand that if we can find that data is enclosed within <table> tag in DOM structure.

Now we learn some HTML tags those are related with table:

<thead> : This tag represent the table header.
<th> : This tag denotes the header column. 
<tfoot> : This tag represent the table footer
<tbody> : This tag means that main table body table data starts from here.
<td> : This tag is used to create table column .
<tr> : This tag is used to create table row.

Q. How we can access table using selenium webdriver ?
Ans : Concept is very simple at first we need to find the desire webtable from HTML page then we find the all Row elements.After getting the all row elements we find the all Column elements on each row element.

Now one thing keep in mind that table header column or cell and normal table column or cell represents in different way,for table header column represented by <th> tag and normal table column represent with <tr> tag.

So if we talk about the code then this is the way to handle webtable using Selenium WebDriver:

Getting TableBody :
driver.findElement(By.tagName("tbody"));
                            Or
driver.findElement(By.xpath("./tbody"));

Getting all Rows :
driver.findElements(By.tagName("tr"));
                            Or
driver.findElements(By.xpath("./tr"));

Getting all Columns or Cells From A Row :
driver.findElements(By.tagName("td"));
                             Or
driver.findElements(By.xpath("./td"));

Getting all Header Columns or Cells :
driver.findElements(By.tagName("th"));
                             Or
driver.findElements(By.xpath("./th"));

Sample Complete Code :

import java.io.File;
import java.util.List;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxBinary;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxProfile;


public class TableExample{

public static void main(String[] args) {

WebDriver driver = null;
try{
driver = new FirefoxDriver();
driver.get("https://en.wikipedia.org/wiki/List_of_largest_oil_and_gas_companies_by_revenue");
WebElement webTable =driver.findElement(By.xpath(".//*[@id='mw-content-text']/table/tbody/tr/td/table"));

/**
* Table header handling. Row denotes with <tr> tag and column denotes 
                 * with <th> tag.
*/
WebElement webTableHeader = webTable.findElement(By.xpath("./thead"));
List<WebElement> webTableHeaderRows = webTableHeader.findElements(By.xpath("./tr"));
for (WebElement headerRow : webTableHeaderRows) {
List<WebElement> webTableHeaderColumns = headerRow.findElements(By.xpath("./th"));
System.out.println(" TableHeader Cell Text : ");
for (WebElement headerColumn : webTableHeaderColumns) {
System.out.print(headerColumn.getText() + "\t");
}
System.out.println("");
}
/**
* Table Body Handling. Row denotes with <tr> tag and column denotes 
                 * with <td> tag.
*/
WebElement webTableBody = webTable.findElement(By.xpath("./tbody"));
List<WebElement> webTableBodyRows = webTableBody.findElements(By.xpath("./tr"));
System.out.println(" TableBody Cell Text : ");
for (WebElement tableBodyRow : webTableBodyRows) {
List<WebElement> webTableBodyColumns = tableBodyRow.findElements(By.xpath("./td"));
int column =0;
for (WebElement webTableBodyColumn : webTableBodyColumns) {
/**
* We can extract tool tip from first column or cell.
*/
if(column==0){
column++;
System.out.print(webTableBodyColumn.findElement(By.xpath(".//span/a/img")).getAttribute("alt") + "\t");
}
else{
System.out.print(webTableBodyColumn.getText() + "\t");
}
}
System.out.println("");
}
/**
* Table Footer Handling. Row denotes with <tr> tag and column denotes 
                 * with <th> tag.
*/
WebElement webTableFooter = webTable.findElement(By.xpath("./tfoot"));
List<WebElement> webTableFooterRows = webTableFooter.findElements(By.xpath("./tr"));
for (WebElement webTablefooterRow : webTableFooterRows) {
List<WebElement> webTableFooterColumns = webTablefooterRow.findElements(By.xpath("./td"));
System.out.println(" TableFooter Cell Text : ");
for (WebElement webTableFooterColumn : webTableFooterColumns) {
System.out.print(webTableFooterColumn.getText() + "\t");
}
System.out.println("");
}
}
catch(Exception e){
System.out.println(e.getMessage());
}
finally {
driver.quit();
}
}


}