Saturday, December 27, 2014

Page Object Model In Selenium WebDriver

What Is Page Object Model :

 Page Object Model is nothing but a code organization structure by which we can separated the web pages and Test classes.

Rule To Making This Structure :

 1. Separate the Test classes to WebPage classes.

 2. Create page related functionality on the same Page Class, from where we can perform functionality of this pages.

 3. If we perform any action on the page and redirect to the the another page, this method return type should be the another page object rather than void.If It stay on the same page then return the same page object or void.
               
     e.g : We can consider two page TestPage1 and TestPage2 for this example. 
TestPage1 and TestPage2 hold different component like button,image,checkbox,dropdown etc.Now we do some operational or structural work on this components like click,select etc to perform a logical or functional operation like login, sighout etc. After any individual logical or functional operation if we stay on the same page then this operation(method) return the same page object or void otherwise return the page object where it is redirected.

4. Isolate the Assertion(Pass,Fail) from the page classes and put them into test classes.

5. Page classes only hold the services that we can expect from this page.

6.Try to Exception handling into the test class.

Code Sample:

We have two page 

1. Blog Test Page
2. Google Search Page


We navigate Google search page from google link on Blog Test Page and give some text search on google page.So we must have 2 different class.BlogPage and GooglePage.

In BlogPage we have one operation click on google link which will navigate to the google page so this method return type should be google page object.But submit button on this page does not navigate to any other page it stay on this page so it's return type should be the blogpage object.

We follow the same structure in googlepage class also. 
  


Blog Test Page
---------------------------------
---------------------------------

package com.core.pageobject;


import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;

public class BlogPage {


    private final By inputBox=By.name("txtbox1");
    private final By submitBtn=By.name("btnsub");
    private final String googleLink="Google";
//    private final WebElement inputBox;
//    private final WebElement submitBtn;
//    private final WebElement googleLink;

    private final WebDriver driver;
   
    public BlogPage(WebDriver driver) {
        this.driver = driver; 

//      this.inputBox = driver.findElement(By.name("txtbox1"));
//      this.googleLink = driver.findElement(By.linkText("Google"));
//      this.submitBtn = driver.findElement(By.name("btnsub"));

    }
   

     
     /**********************************
     * This Method Return  BlogPage Object
     * Because After Submit It's Stay On The 

     * Same Page     
     **********************************/
    public BlogPage submitForm(String inputTxt){
        driver.findElement(inputBox).sendKeys(inputTxt);
        driver.findElement(submitBtn).click();
//        inputBox.sendKeys(inputTxt);
//        submitBtn.click();

    return new BlogPage(driver);
    }    


     /**********************************
     * This Method Return GoolePage Object
     * Because After Click On This Link

     * It's Redirect To The Google Page
     **********************************/

     public GooglePage clickonGoogleLink(){
        driver.findElement(By.linkText(googleLink)).click();
//         googleLink.click();
      return new GooglePage(driver);
    }
}

 

Google Test Page
-------------------------------
-------------------------------

package com.core.pageobject;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
 

public class GooglePage { 
    private final By searchBox=By.name("q");
//    private final WebElement searchBox;

    private final WebDriver driver;

    public GooglePage(WebDriver driver) {
        this.driver = driver; 

//      this.searchBox=driver.findElement(By.name("q"));
    }

     /**********************************
     * This Method Return Goole Page Object
     * Because After Click On Search Button

     * Redirect To The Google Page
     **********************************/

    public GooglePage searchTxt(String searchTxt){
      driver.findElement(searchBox).sendKeys(searchTxt); 
//      searchBox.sendKeys(searchTxt);
    return new GooglePage(driver);
    }
}

 


Page Object Model Test
--------------------------------------
--------------------------------------

package com.core.pageobject;

import java.io.File;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxBinary;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxProfile;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;

public class PageObjectModelTest {
    WebDriver driver;


     /**********************************
     *Initialize Driver For All Test
     ***********************************/

    @BeforeTest
    public void testSetUp(){
        FirefoxBinary bin=new FirefoxBinary(new File("G:\\Program Files\\Mozilla Firefox\\firefox.exe"));
        FirefoxProfile prof=new FirefoxProfile();
        driver=new FirefoxDriver(bin, prof);
    }


     /**********************************
     * This Is Created To Go the Base Page 

     * Before Every Test
     **********************************/
    @BeforeMethod
    public void testMethodSetUp(){
    driver.get("http://startingwithseleniumwebdriver.blogspot.in/2013/12/frmset1.html");
    }



    @Test()
    public void testSubmit() throws Exception{
        BlogPage blog=new BlogPage(driver);
        blog.submitForm("Test");
    } 



    @Test
     public void testGoogleLink()throws Exception{
        BlogPage blog=new BlogPage(driver);
        blog.clickonGoogleLink().searchTxt("Test");
    } 


     /**********************************
     * This  Is Created To Close The Driver

     **********************************/
    @AfterTest
    public void tearDown(){
    driver.quit();
    }
}
 



Sunday, November 30, 2014

Custom CSS Locator Creation Technique

Previously we learn how to create or get the CSS Path from FirePath(Firefox browser Add-ons).

Here we try to learn the meaning of each and every element in CSS path.

Some Basic Of CSS-Path  
.
 It denote the class name
 e.g:- .editable

#
 It is used when we try to find element using id

 e.g:- #postingComposeBox

> or Space
 When we try to access the webelement which is direct child of the particular element then use >
 If we try to access the webelement which is maybe child or sub child then use Space

e.g:- div>a Here a is direct child of div element
         div a  Here a is sub-child and child also

tag[attributename="attributevalue"]
 We can directly access any webelement using the attributename and the corresponding value

 e.g:- div[class="field-item even"][name='test']>pre

tag[attributename~="attrivutevalue"]
 We can matching the exact word from attribute value string

 e.g:-iframe[title ~="utility"]

Sub String Matching


^= Match a prefix
$= Match a suffix
*= Match a substring

tag[attributename^="attrivutevalue"]
 Attribute value text starts with Addtext
e.g:-iframe[title^="Add"]

tag[attributename$="attrivutevalue"]
 Attribute value text ends with me text
e.g:-iframe[title$="me"]

tag[attributename*="attrivutevalue"] 
 Attribute value text contains lity text
 e.g:-iframe[title*="lity"]
 


Monday, October 27, 2014

Taking Screen Shot Of A Particular WebElement

Here we try to take a screen shot of an particular web element within a webpage.Normally when we take a screen shot using WebDriver we take the screen shot of a full page.We cannot take the screen shot of a particular web element or area.

Here we can do the following step to get the screen shot of an particular web element:

1.We take the screen shot of the full screen
2.Store The taken screen shot file into the buffer.
3.Then crop the picture from buffer image and store it into the buffer.
4.Write buffer to a File.
5.Then Copy the File to the particular destination.


Now, We try to implement this step

1. Taking the screen shot of whole page.   

File screenShot=((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);

2. Store the image into the buffer   

 BufferedImage buffImg=ImageIO.read(screenShot);

3. This is the step from where we can crop the picture.

For cropping a picture we need to know the X and Y coordinate of  the web element at any end point it maybe bottom left,bottom right,top right or top left corner of a web element .
We get the X and Y coordinate of an web element using element.getLocation().getX() and element.getLocation().getY(). It returns the top left corner x,y coordinate value.

Now we need to know the height and width of an web element. We can know this using  element.getSize().getWidth()  and element.getSize().getHeight() .

So this is the way we can crop the Image from buffer.
 
BufferedImage eleBuffImg=buffImg.getSubimage(element.getLocation().getX(), element.getLocation().getX()
                                ,element.getSize().getWidth() , element.getSize().getHeight());


4. We can write the buffer image to the file using this.

 ImageIO.write(eleBuffImg, "png",screenShot );

5. Now we can write this file to the particular location using this.

 FileUtils.copyFile(screenShot, new File("Your File Storing Location"));

Full Code is given below:





package WebElementScreenShot;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;

public class WebElementScreenShot {

    public static void main(String[] args) {

        //System.setProperty("webdriver.chrome.driver", "./chromedriver_win32_2.1/chromedriver.exe");
        ChromeDriverService service=new ChromeDriverService.Builder()
         .usingChromeDriverExecutable(new File("./chromedriver_win32_2.1/chromedriver.exe"))
         .usingAnyFreePort().build();
        WebDriver driver=new ChromeDriver(service);
       
        //Maximize Browser Window Because If It Is not Maximized
        //Then It May Take Screen Shot For Wrong Element.It may
        //Happen On Chrome Driver

       

         driver.manage().window().maximize();
       
        //Open The desired URL
        driver.get("http://www.google.com");

        try {
           
            //Call The Element Image Screen Shot Methiod
            elementScreenShot(driver, By.id("gbqfq"));
        } catch (IOException e) {
            e.printStackTrace();
        }
        finally{
            driver.quit();
        }
    }
   
    public static void elementScreenShot(WebDriver driver,By byElement) throws IOException{
        WebElement element=driver.findElement(byElement);
       
        //This Is For To Surround The WebElement Before Taken The Screen Shot
        ((JavascriptExecutor)driver).executeScript("arguments[0].setAttribute('style', arguments[1]);",element, "color: Red; border: 2px solid red;");
       
        //Take The Full Page Screen Shot
        File screenShot=((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
       
        //Transfer Full Image To Buffered Image
        BufferedImage buffImg=ImageIO.read(screenShot);
       
        //Crop The Picture According To the Element Size From Buffered Image 
        BufferedImage eleBuffImg=buffImg.getSubimage(

             element.getLocation().getX(), element.getLocation().getX(),
             element.getSize().getWidth() , element.getSize().getHeight());
       
        //Write The Buffered Image into Main Taken Screen Shot File
        ImageIO.write(eleBuffImg, "png",screenShot );
       
        //Copy The Crop Image Into The Machine Drive
        FileUtils.copyFile(screenShot, new File("D:/Test.jpeg"));
       
    }

}


  


Sunday, September 28, 2014

HighLight Web Element During Execution

During Execution we need to highlight the web element for debugging or to check, that we find the right element of the web page.In QTP we can do this using Active Window if the object is stored into the Object Repository.

So, now question is how to implement this in Selenium WebDriver?

We can achieve this using java script executor,

js.executeScript("arguments[0].style.border='3px solid red'", element);

                                                                  OR
 
js.executeScript("arguments[0].setAttribute('style', arguments[1]);",element, "color: Red; border: 2px solid red;");

We can use any of them to set set the red solid border around the element.


The Complete code is given below:

package highlight;

import java.io.File;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;

public class HighLight {

    /**
     * @param args
     * @throws InterruptedException
     */
    public static void main(String[] args) throws InterruptedException {
     
      //#####################################################
      //Here We SetUp The Chrome Driver With Any Free Port
      //And We Also Set The Chrome Driver Path
      //#####################################################

  ChromeDriverService service=new ChromeDriverService.Builder()
            .usingChromeDriverExecutable(new File("./chromedriver_win32_2.1/chromedriver.exe"))
            .usingAnyFreePort().build();
        WebDriver driver=new ChromeDriver(service);
        driver.get("http://www.google.com");
        findElement(driver,By.name("q"));
       
    }



      //#####################################################
      //Below Two Methods Do The Same Thing But They Use 
      //Different Java Script.
      //#####################################################

      //#####################################################
      //Method 1
      //#####################################################  
     public static WebElement findElement(By by,WebDriver driver) throws InterruptedException {
        WebElement element = driver.findElement(by);
      
        // draw a border around the found element
        if (driver instanceof JavascriptExecutor) {
            JavascriptExecutor js = (JavascriptExecutor) driver;
            js.executeScript("arguments[0].style.border='3px solid red'", element);
            Thread.sleep(1000);
            js.executeScript("arguments[0].style.border=''",element, "");
            Thread.sleep(1000);
        }
        return element;
    }


      //#####################################################
      //Method 2
      //#####################################################  
    public static WebElement findElement(WebDriver driver, By by) throws InterruptedException {
        WebElement element = driver.findElement(by);
        

         // draw a border around the found element
           if (driver instanceof JavascriptExecutor) {
                JavascriptExecutor js = (JavascriptExecutor) driver;
                js.executeScript("arguments[0].setAttribute('style', arguments[1]);",element, "color: Red; border: 2px solid red;");
                Thread.sleep(1000);
                js.executeScript("arguments[0].setAttribute('style', arguments[1]);",element, "");
                Thread.sleep(1000);
            }
        return element;
    }
}

Sunday, August 3, 2014

Custom XPath Creation Technique

Mainly we use FirePath for getting XPath of an element but sometime we need to make XPath manually or need to customize the XPath.

Some Basic of XPath Notation

/                                                    
Select from the root node                   
ex: html/body/.......

//                                               
Select nodes form the current node     
ex: //table/tbody/tr/.............

@                                                  
Select attribute                                  
ex: //input[@id='abc']

//input[@id='Some Value']          
Select element with tag name and id        

//input[contains(text(),'TextValue')] 
Select element with text containing abc
ex: //input[contains(text(),'abc')]

//input[starts-with(text(),'TextValue')] 
Select element with text starting with abc
ex: //input[starts-with(text(),'abc')]

//input[contains(@id, 'TextValue')]    
identify element containing 'abc' in value attribute

//input[contains(@id, 'searchInput') and contains(@text,'google')]
look at two attributes in input node

//input[starts-with(@type, 'abc')]
find input node with attribute type and its value is starting with 'abc'

//*[@accesskey='abc'] 
Can use wild cards

//input[text()='abc']                      
Select element with tag input and text=abc

//td/a/strong[contains(text(),'abc')]
Find all elements containing 'abc'

.//input[position()=1]   
Select Input of First Position

//div[@class='cmnts']/descendant::div[position()=2]
Select 2nd div of the div node One thing keep in mind that descendant means child, child of child etc

//div[@class='cmnts']/ancestor::div[position()=2] 

//div[@class='GCUXF0KCICB']/ancestor-or-self::div[position()=2]
ancestor-or-self means traversing starts from current node.

//input[last()]

.//div[@class='GCUXF0KCO3B']/span[text()='Labels']
Select span text

.//div[count(*)=0]
Select div that does not contain any child node

Sunday, July 27, 2014

Log4J JDBC Configuration For DataBase Log

Some time we need to use DataBase for automation where we can try to validate UI(FrontEnd) with DataBase(BackEnd). So there are lots of database communication is needed and we need to track this what happened with the database.

Log4J JDBC is use for this reason by which we can track the all database communication.

Log4J JDBC use the SLF4J for logging but it does not have the capacity for writing the log into the file so we use Log4J with this.

Now we will go for the configuration for this.

Step 1:

a.Download Log4 JDBC form here
b.Download SLF4J from here
c.Download Log4j from here

Step 2:

Put this jars into the class path of our project.

slf4j-api-1.7.7.jar
slf4j-log4j12-1.7.7.jar
log4jdbc4-1.2.jar
log4j-1.2.17.jar

Step 3:

Put this Log4J configuration file into the project directory. The File looks like that


# Logging levels are:
# DEBUG < INFO < WARN < ERROR < FATAL


# turn on the internal log4j debugging flag so we can see what it is doing
log4j.debug=true

# JDBC API layer call logging :
# INFO shows logging, DEBUG also shows where in code the jdbc calls were made,
# setting DEBUG to true might cause minor slow-down in some environments.
# If you experience too much slowness, use INFO instead.


# Log all JDBC calls except for ResultSet calls
log4j.logger.jdbc.audit=INFO,jdbc
log4j.additivity.jdbc.audit=false

# Log only JDBC calls to ResultSet objects

log4j.logger.jdbc.resultset=INFO,jdbc
log4j.additivity.jdbc.resultset=false

# Log only the SQL that is executed.
log4j.logger.jdbc.sqlonly=DEBUG,sql
log4j.additivity.jdbc.sqlonly=false

# Log timing information about the SQL that is executed.
log4j.logger.jdbc.sqltiming=DEBUG,sqltiming
log4j.additivity.jdbc.sqltiming=false

# Log connection open/close events and connection number dump
log4j.logger.jdbc.connection=FATAL,connection
log4j.additivity.jdbc.connection=false


# the appender used for the JDBC API layer call logging above, sql only
log4j.appender.sql=org.apache.log4j.FileAppender
log4j.appender.sql.File=./logs/sql.log
log4j.appender.sql.Append=false
log4j.appender.sql.layout=org.apache.log4j.PatternLayout
log4j.appender.sql.layout.ConversionPattern=-----> %d{yyyy-MM-dd HH:mm:ss.SSS} %m%n%n

# the appender used for the JDBC API layer call logging above, sql timing
log4j.appender.sqltiming=org.apache.log4j.FileAppender
log4j.appender.sqltiming.File=./logs/sqltiming.log
log4j.appender.sqltiming.Append=false
log4j.appender.sqltiming.layout=org.apache.log4j.PatternLayout
log4j.appender.sqltiming.layout.ConversionPattern=-----> %d{yyyy-MM-dd HH:mm:ss.SSS} %m%n%n

# the appender used for the JDBC API layer call logging above
log4j.appender.jdbc=org.apache.log4j.FileAppender
log4j.appender.jdbc.File=./logs/jdbc.log
log4j.appender.jdbc.Append=false
log4j.appender.jdbc.layout=org.apache.log4j.PatternLayout
log4j.appender.jdbc.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss.SSS} %m%n

# the appender used for the JDBC Connection open and close events
log4j.appender.connection=org.apache.log4j.FileAppender
log4j.appender.connection.File=./logs/connection.log
log4j.appender.connection.Append=false
log4j.appender.connection.layout=org.apache.log4j.PatternLayout
log4j.appender.connection.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss.SSS} %m%n

# Log levels
log4j.rootLogger=DEBUG,CONSOLE,R,HTML,TTCC
# Rolling File Appender
log4j.appender.TTCC=org.apache.log4j.RollingFileAppender
# Layout for Rolling File Appender
log4j.appender.TTCC.layout=org.apache.log4j.TTCCLayout
log4j.appender.TTCC.layout.DateFormat=ISO8601
# Path and file name to store the log file
log4j.appender.TTCC.File=./logs/testlog1.log
log4j.appender.TTCC.MaxFileSize=200KB
# Number of backup files
log4j.appender.TTCC.MaxBackupIndex=2
# Appender Configuration
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
# Pattern to output the caller's file name and line number
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n
# Rolling File Appender
log4j.appender.R=org.apache.log4j.RollingFileAppender
# Path and file name to store the log file
log4j.appender.R.File=./logs/testlog.log
log4j.appender.R.MaxFileSize=200KB
# Number of backup files
log4j.appender.R.MaxBackupIndex=2
# Layout for Rolling File Appender
log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=%d - %c - %p - %m%n
# Define the HTML file appender
log4j.appender.HTML=org.apache.log4j.FileAppender
# Path and file name to store the log file
log4j.appender.HTML.File=./logs/application.html
# Define the html layout for file appender
log4j.appender.HTML.layout=org.apache.log4j.HTMLLayout
#Define Title of the HTML page
log4j.appender.HTML.layout.Title=Application logs
#Define the log location of application class file
log4j.appender.HTML.layout.LocationInfo=true

 Step 4:

Now we write a database related code to test this, code looks like that

//STEP 1. Import required packages

import java.sql.*;
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;

public class DataBaseWork {
  
  private static final Logger logger = Logger.getLogger("Log4JSettings");
 
   // JDBC driver name and database URL
   // For Logging We need to change this as given below
  
   static final String DB_URL = "jdbc:log4jdbc:derby://localhost:1527/sample";

   //  Database credentials
   static final String USER = "app";
   static final String PASS = "app";
 
   public static void main(String[] args) {
     
   PropertyConfigurator.configure("log4j.properties");
   Connection conn = null;
   Statement stmt = null;
   try{
     
       //STEP 2: Register JDBC driver
      //For Logging we need to set the driver as below

      Class.forName("net.sf.log4jdbc.DriverSpy");
     
      //STEP 3: Open a connection
     
      System.out.println("Connecting to database...");
      conn = DriverManager.getConnection(DB_URL,USER,PASS);

      //STEP 4: Execute a query
     
      System.out.println("Creating statement...");
      stmt = conn.createStatement();
      String sql;
      sql = "select CUSTOMER_ID from APP.CUSTOMER";
      ResultSet rs = stmt.executeQuery(sql);

      //STEP 5: Extract data from result set
     
        while(rs.next()){
       
        //Retrieve by column name
        
         int id  = rs.getInt("CUSTOMER_ID");
        String first = rs.getString("CUSTOMER_ID");


         //Display values
        
          System.out.print("ID: " + id);
          System.out.print("\n");
      }
     
      //STEP 6: Clean-up environment
    
       rs.close();
      stmt.close();
      conn.close();
   }catch(SQLException se){      
    //Handle errors for JDBC
   
     se.printStackTrace();
   }catch(Exception e){
    //Handle errors for Class.forName
    
       e.printStackTrace();
   }finally{
      //finally block used to close resources
     
      try{
         if(stmt!=null)
            stmt.close();
         logger.debug("Test Debug");
      }catch(SQLException se2){
      }// nothing we can do
      try{
         if(conn!=null)
            conn.close();
      }catch(SQLException se){
         se.printStackTrace();
      }//end finally try
   }//end try
   System.out.println("Goodbye!");
}//end main
}//end FirstExample


Now we see the log about the database activity.

Saturday, July 12, 2014

Zip File Handling with Java And Selenium WebDriver

Some time we need to compress files for sending it.Here we learn how we can handle this programmatically.

We can handle this in two ways
1. Java SDK
2. Selenium WebDriver

1.Zip Using Java SDK:

public class Compress {

static List<String> fileList=new ArrayList<String>();

public static void main(String args[]) throws IOException {
        sendToZip(new File("Our Source To Zip"), new File("Our Destination To Zip\\ZipFile.ZIP"));
}

##########################################
#This Method is Created for List down Of All Files
# within the Source Path and put the Absolute Path 
#into the List
##########################################
    private static List<String> addFiletoList(File inputDir)
    {
        File[] listOfFile=inputDir.listFiles();
        for (File file : listOfFile) {
        if(file.isFile())
            fileList.add(file.getAbsolutePath());
        else
            addFiletoList(file);
        }
    return fileList;    
    }


##########################################
#This Method is Created to Zip the all File and 
#Save it to the Destination Path
###########################################
    private  static void sendToZip(File zipInput,File zipOutPut) throws FileNotFoundException, IOException
    {  
        List<String> fileList=new ArrayList<String>();
        fileList=addFiletoList(zipInput);
        FileOutputStream fos=new FileOutputStream(zipOutPut);
        ZipOutputStream zos=new ZipOutputStream(fos);
        for(String filePath:fileList){
            FileInputStream fis = new FileInputStream(filePath);

           
            //String name is required for showing the file name after zip same as before zip
 
            String name = filePath.substring(zipInput.getAbsolutePath().length()+1, filePath.length());
            ZipEntry entry = new ZipEntry(name);
            zos.putNextEntry(entry);

            int len;
            byte[] buffer = new byte[4096];
            while ((len = fis.read(buffer)) != -1) {
                zos.write(buffer, 0, len);
            }

            fis.close();
            zos.closeEntry();
        }
        zos.close();
        fos.close();
    }



 1.Zip Using Selenium WebDriver:

Zip compress=new Zip();compress.zip(new File("Our Source To Zip"), new File("Our Destination To Zip"));





Now we can see that Zip using Selenium is more compact and easy coding but there is a problem if source and destination zip folder path is same then it creates a corrupted zip folder with in our zip folder.

So always keep in mind if we use selenium provided zip functionality then Zip folder Source and Zip folder Destination should be different. 

Sunday, June 22, 2014

Running Script on Selenium Grid

On previous post we learn how to configure Selenium grid and Node.Now we will try to learn how we can access Selenium Grid from our code.

Actually we do not need to change lots of things we just need to change the driver initialize part it should be looks like that
        
       DesiredCapabilities cap =new DesiredCapabilities();
       cap.setBrowserName("firefox");
       WebDriver driver = new RemoteWebDriver(new URL("http://Machine IP or localhost:PortNumber in which port hub is running/wd/hub"), cap); 
this is the main thing for the Selenium Grid script code rest of the part is same as the normal script.

If firefox is installed in other than default location then we need to specify the location of the firefox binary when we configure the node,node setup command should be looks like that

java -jar "path of selenium-server-standalone-2.41.0.jar" -role node -hub "http://Machine IP or localhost:PortNumber in which port hub is running/grid/register" -browser "firefox_binary=firefox binary path, browserName=firefox"

 If we need to run the script on IE then it is little bit tricky,we need to register the IE diver to the node, the command looks like that


java -jar "path of selenium-server-standalone-2.41.0.jar" -role node -hub "http://Machine IP or localhost:PortNumber in which port hub is running/grid/register" -Dwebdriver.ie.driver="path of 32 bit 64 bit IEDriverServer.exe"

 and need to set this into the code

cap.setBrowserName("internet explorer");




Thursday, June 5, 2014

Configuration of Selenium Grid And Node

Still now our main aim or goal to execute test script on the same machine where our script developed.But if we need to run the same test script on different environment(mainly the different version of browser we may also consider the different operating system) at the same time what we do? The answer is Selenium Grid.


Q1:Where we can find the Selenium Grid?
Ans: Selenium Grid is basically a jar file we can download this jar from here.

Q2:Which jar we need to run Selenium Grid?
Ans: After going to the above mentioned link we can find Download Version(Some version number) link under the Selenium Server(formerly the Selenium RC Server). After clicking to this link we can download the
selenium-server-standalone-2.41.0.jar file.The page looks like that

Q3:How many part we need to configure for Selenium Grid setup
Ans: Basically 2 part we need to configure for Selenium Grid set up
              A.Hub
                  Hub will receive all requests and distribute them to the right nodes.basically it play the Server role.
              B.Node
                  Node is playing as a client role

Q3:How to install or run this jar for hub role?
Ans: Just execute this command
                java -jar "our selenium Grid directory\selenium-server-standalone-2.41.0.jar" -role hub
After executing this command command screen shows the details it looks like below

Some common problems to start the Hub and solutions

Problem1: java -jar not executed
Solution: Go to the installed location of the java bin folder from the command prompt and then execute the above mentioned command.

 Problem2: Exception to bind the port


Solution:If we drill down the exception it clearly shows that Selenium Grid got this exception because default port (4444) is used by another process.To jump over this hurdle we just mention the free port with the command so it should be looks like that 
                   java -jar "our selenium Grid directory\selenium-server-standalone-2.41.0.jar" -role hub -port FreePortNumber 

How we know that which ports are using currently?
Ans: Execute the below command from the command prompt by which we can get the details of the all process and port
                   netstat -a -n -o
So we take any port except those ports are listed into the command prompt.

 Problem 3: FireWall block this port which we try to open?
Ans: Allow or unblock the port from FireWall ,if there is no security problem then off the FireWall.


After successfully start the hub we can find the webpage which looks like below if we hit the url:
http://localhost:portnumber(this is for local machine from where we execute the command to start the hub) or http://hubmachineIP:portnumber

In the below example we hit the url from the local machine

Q4:How to run or install the jar for the client role?
Ans:  Execute this command
                 java -jar "our selenium Grid directory\selenium-server-standalone-2.41.0.jar" -role node -hub http://our hub machine ip or localhost:portnumber/grid/register 

After successfully executing the command, command line screen should be looks like that 



Some common problems to start the Node and solutions

Problem1: Exception to bind the port means that it is already in use
Solution:If we drill down the exception it clearly shows that Selenium Grid got this exception because default port (5555) is used by another process.To avoid this problem we just mention the free port with the command so command should be looks like that 

  java -jar "our selenium Grid directory\selenium-server-standalone-2.41.0.jar" -role node -hub http://hub machine IP or localhost:portnumber/grid/register -port FreePortNumber

 There are lots of  optional parameter we can pass to the node when we required it like

borwsername:          -browser browserName=firefox
plantform:                 platform=WINDOWS
maxInstances:          maxInstances=5
version:                     version=29.0.1
firefox_binary           firefox_binary=our firefox binary path
port                           -port 4444

e.g:
  java -jar "our selenium Grid directory\selenium-server-standalone-2.41.0.jar" -role node -hub http://hub machine IP or localhost:portnumber/grid/register -port FreePortNumber -browser browserName=firefox platform=WINDOWS

Friday, May 16, 2014

File Downloading With AutoIt


Sometime we need to download file from AUT(Application Under Test) but there are several debates on it.We do not want to go for this but we learn how to download file from Firefox,IE and Chrome using AutoIt.There are several ways to automate download file form browser we learn later.

Using AuoIt have some Pros and Cons

Pros:
1. Make an exe file and call it from our code
2. Easy to use.

Cons:
1. It's main problem is platform dependent means it run on only windows. 

Now we go for the steps where we learn how to use AutoIt and configuration:

Steps:
1.Download AutoIt from here .Download both AutoIt Full Installation and AutoIt Script Editor.
2.Install both AutoIt Full Installation and AutoIt Script Editor in our desired directory as normal software installed.

3.Open the AutoIt Script Editor and write down this code for downloading file from IE(Tested on IE 6) and Firefox.

#include <file.au3>

_Log("----new session----")

if $CmdLine[0] <> 3 then
; Arguments are not enough
 msgbox(0,"Error","Supply all the Arguments, Browser name and path to upload")
_Log("Arguments are wrong")
Exit
EndIf

;Activate firefox/IE browser
If (StringCompare($CmdLine[1],"firefox",0) = 0) Then
    $waitTime=$CmdLine[3]
    if (WinWait("[Class:MozillaDialogClass]","",$waitTime)==0) Then
        _Log("Window Not Found From FireFox")
    Else
    _Log("Waiting For Download Window From FireFox")
    _FFDownload()
    EndIf

ElseIf (StringCompare($CmdLine[1],"ie",0) = 0) Then
    WinWait("File Download - Security Warning")
    _Log("Waiting For Download Window From IE")
    _IEDownload()
Else
    Exit
EndIf
;Used For IE and Tested on IE6
Func _IEDownload()

    $hResult = WinActivate("File Download - Security Warning")
    If($hResult == 0) Then
        _Log("Unable to find Download Window from IE")
    Else
        $IETitle=WinGetTitle("File Download - Security Warning")
        _Log("Download Window activated"&$IETitle)
        WinActivate($IETitle)
        ControlClick($IETitle, "","[CLASS:Button; INSTANCE:2]")
        _Log("FileChooser Window opend")
        _Log("CommandLine Parameter Found and Value is:"&$CmdLine[2])
        WinActivate("Save As")
        _Log("FileChooser Window opend"&WinGetTitle("Save As"))
        ControlSetText(WinGetTitle("Save As"),"","Edit1",$CmdLine[2])
        Send("!s")
    EndIf
EndFunc

;Used for FireFox Browser
Func _FFDownload()
    $hResult = WinActivate("[Class:MozillaDialogClass]");

    If($hResult == 0) Then
        _Log("Unable to find Download Window From FireFox")
    Else
        ; If firefox is set the save the file on some specif location without asking to user.
        ; It will be save after this point.
        ;If not A new Dialog will appear prompting for Path to save

        _Log("Download Window activated")
        ;To change the focus on save button
        Send("{TAB}")
        Sleep(400)
        Send("{TAB}")
        _Log("Change Focus to Save Button")
        ;This is use for if dialoguebox have save and openwith option
        Send("!s")
        ;Click on Enter to Save
        Sleep(400)
        Send("{ENTER}")
        _Log("Press Enter")
        Sleep(400)

        If(WinExists(WinGetTitle("[active]"))) Then
            WinActivate("Enter name of file to save to…")
            $title = WinGetTitle("[active]")
            if($title=="Enter name of file to save to…")Then
            _Log("Active Window Title Is:"&WinGetTitle("[active]") )
            _Log("EnterName Window Opened And Tiltle is:"&$title)
            ControlSetText($title,"","Edit1",$CmdLine[2])
            ; Save File
            _Log("CommandLine Parameter Found For FilePath and Value is:"&$CmdLine[2])
            Send("!s")
            EndIf
        EndIf

    EndIf
EndFunc
;used for logging
Func _Log($sLogMsg)
_FileWriteLog(@ScriptDir & "\AutoItLog.log",$sLogMsg)
EndFunc


4.Save the File from File->Save option.
  
5.Now we go to Tools->Build option from AutoIt Script Editor.After build this it creates a exe file with samename in the same directory where Script file saved.

6.Now we just call this from selenium Java code.

    WebDriver driver=new FirefoxDriver();
    driver.get("File Download URL");
    //driver.findElement(By.partialLinkText("click here")).click();

    
    //This the code to call exe and pass the command line argument
    Process pb=new ProcessBuilder("AutoIt Script exe Path","BrowserName","File download Location","10").start();


7. Using this AutoIt Script we can handle Open with and Save window or Save file using File chooser window cab be handled from firefox.This AutoIt script have also a log file writing mechanism it should be generated where exe file exists and name Should be AutoItLog.log .


Friday, April 11, 2014

Temp File Management Using WebDriver

Here we try to handle Temp file which is generated by the WebDriver.

Q. Why we need to handle this temp file?
Ans:- It is not necessary it should be deleted automatically,but some time it may not be deleted on      different version of WebDriver, sometime it may be deleted when we quit the driver(using this line driver.quit() to quit the driver) or need to close the driver (using this line driver.close()). If we go to the User Temp(Windows +R then type %temp% to open the user temp.It is a default location to create the temp file for WebDriver) folder we see this two folder should be there after some time unzip60898411...... folder deleted and anonymous folder contains the driver files.



Q. Is there any way to change the temp folder location for WebDriver?

Ans:- Yes,we can change the temp folder location for WebDriver using this line in our code,
        TemporaryFilesystem.setTemporaryDirectory(new File("C:/xyz"));

Example:
        if(!new File("C:/XYZ").isDirectory())
        FileUtils.forceMkdir(new File("C:/XYZ"));
        TemporaryFilesystem.setTemporaryDirectory(new File("C:/xyz"));


Q. How to delete this files?

Ans:-Use this line to delete the files.

FileUtils.deleteDirectory(new File("C:/XYZ"));

Q. When we delete this files?

Ans:-We preferred to delete files at @AfterTest or @AfterClass annotation.

Saturday, April 5, 2014

Firefox profile and DesiredCapabilities


Every testing scenario should be executed on some specific testing environment.WebDiver give us this opportunity using Firefox profile and Desired capability.

FireFox Profile

Firefox profile help the tester to execute the test on the particular profile which may be configured previously or may be it configured on run time using Desired Capabilities.

DesiredCapabilities

Desired Capability is a series of key/value pairs that encapsulate aspects of a browser means we can set the behavior of the browser on the run time. Basically, the DesiredCapabilities help to set properties for the WebDriver. A typical usecase would be to set the path for the FireFoxDriver if our local installation doesn't correspond to the default settings.

 How to create Profile on FireFox?

Ans:
          1.Open windows run mode(Windows+R) then type "firefox -p -no-remote"
 -no-remote parameter is optional it is required if we open multiple instance of firefox(it means if we open a firefox and using it then open another one for test purpose).

          2.Click on  Create Profile then click on next

     
          3.Give a name of the profile and choose the directory path where it will be saved or we can choose the default path.

         
Now we learn how WebDriver use this Profiles.

Procedure 1:
 
        ProfilesIni allProfiles = new ProfilesIni();
        FirefoxProfile profile=allProfiles.getProfile("ExTest");

        WebDriver driver = new FirefoxDriver(profile);


FirefoxProfile profile=allProfiles.getProfile("ExTest") here "ExTest" is test profile. 

Here one thing one mind ProfilesIni class load all profiles, this profiles may or may not be saved on default location.

 Procedure 2:

        FirefoxProfile profile=new FirefoxProfile(new File("C:\\Test"));
        WebDriver driver = new FirefoxDriver(profile);



 FirefoxProfile profile=new FirefoxProfile(new File("C:\\Test")); here "C:\\Test" is the path where profile is created.

Now we learn how to use DesiredCapabilities.

        DesiredCapabilities cap=new DesiredCapabilities();
        cap.setCapability("firefox_binary", "G:\\Program Files\\Mozilla Firefox\\firefox.exe");
        WebDriver driver = new FirefoxDriver(cap);


  cap.setCapability("firefox_binary", "G:\\Program Files\\Mozilla Firefox\\firefox.exe");
 
  We know previously that desired capability is a key value paired, here we can observed that we set the
  Key as "firefox_binary" and value as "G:\\Program Files\\Mozilla Firefox\\firefox.exe".


Keep in mind that we can not create any profile on Internet Explorer but Chrome or Opera browser have the facility to create user profile. We can get more information regarding this from here .










Sunday, March 30, 2014

Reporting With ReportNG

ReportNG is a plug-In for TestNG, using this we can generate HTML based report for our test.Here we learn how to setup ReportNG and how to build using ANT script.
  •  ReportNg SetUP
               Step 1:

                     Dowload  ReportNG from here .

               Step 2:

                      Extract the downloaded folder after that it looks like that


                      The reportng-1.1.4.jar and velocity-dep-1.4.jar.jar files must be included into our project lib folder.

                Step 3:

       Write the Ant script as given below

<project name="TestNGTest" default="test" basedir=".">
    <!-- Define <testng> task -->

    <property name="testdir" location="test" />
    <property name="libdir" location="lib" />
    <property name="full-compile" value="true" />
    <path id="classpath.test">
        <fileset dir="${libdir}">
            <include name="**/*.jar" />
        </fileset>
        <pathelement location="${testdir}\class" />
    </path>

    <taskdef resource="testngtasks" classpathref="classpath.test"/>
    <target name="reportng" depends="testng">
        <mkdir  dir="${testdir}\ReportNgReport" />
        <testng outputdir="${testdir}\ReportNgReport" classpathref="classpath.test" useDefaultListeners="false" 
             haltonfailure="false"   listeners="org.uncommons.reportng.HTMLReporter,org.uncommons.reportng.JUnitXMLReporter">
        <xmlfileset dir="${testdir}\javaapplication3" includes="NewTestNGSuite.xml"/>
        <sysproperty key="org.uncommons.reportng.escape-output" value="false" />
        <sysproperty key="org.uncommons.reportng.velocity-log" value="true"/>
        <sysproperty key="org.uncommons.reportng.title" value="My Test Report"/>   
        <sysproperty key="org.uncommons.reportng.frames" value="true"/>   
        <sysproperty key="org.uncommons.reportng.failures-only" value="true"/>   
        <sysproperty key="org.uncommons.reportng.show-expected-exceptions" value="false"/>


  
        </testng>
    </target> 

</project> 

                 If we useDefaultListeners="false" then TestNg reporting files should not be created.


                 We need to set listner for HTML reporting
                    org.uncommons.reportng.HTMLReporter
    
                 We need to set listner for JUnit reporting (optional)
                     org.uncommons.reportng.JUnitXMLReporter

                  We can also set the various system property of the ReportNg like rendering screenshot for test failure,change the default title, logging,only failure test shown on the html report etc......

  •    Some Error handling in ReportNG SetUP
                    Problem 1:   Exception in thread "main" java.lang.NoClassDefFoundError: com/google/inject/Module


                    Solution:Download guice-3.0 from here ,extract the files and add guice-3.0.jar in our project lib.

                    Problem 2: Velocity Log not created
            
                    Solution : Actually  if we set this <sysproperty key="org.uncommons.reportng.velocity-log" value="true"/>then log is created in system environment directory.So we need to set the working directory from TestNg.We can do this using workingdir attribute in <testng> tag like:                                         


<testng workingdir="${basedir}/ReportNG" outputdir="${basedir}/ReportNG" classpathref="masterclasspath"
                useDefaultListeners="false" listeners="org.uncommons.reportng.HTMLReporter,org.uncommons.reportng.JUnitXMLReporter">

Thursday, March 27, 2014

Some Error and Solution For TestNG-XSLT


On our previous post we learn how to configure and generate different type of repot using TestNG XSLT. Now here we discuss some configuration related problem and how can we overcome this.

Problem 1:

Error! Syntax error in 'if ($testNgXslt.testDetailsFilter) then $testNgXslt.testDetailsFilter else 'FAIL,PASS,SKIP''

Solution: This error occur because we forget to add SaxonLiaison jar into our project or we forget to add processor="SaxonLiaison" as an attribute on <xslt> tag. Proper tag is given below.

<xslt in="${basedir}/build/test/results/testng-results.xml" style="${basedir}/testng-results.xsl" out="${basedir}/testng-xslt/index.html" processor="SaxonLiaison">

Problem 2:

Fatal Error! Failed to create output file file://///style.css Cause: java.io.IOException: The filename, directory name, or volume label syntax is incorrect

Solution: This error happen if we for get to mentioned <param expression="${basedir}/testng-xslt/" name="testNgXslt.outputDir" /> this is mandatory and must be an absolute path.This is mandatory and must be an absolute path.
 

Different Reporting Style With TestNG-XSLT

Before this we learn how to configure TestNG from eclipcs(By default TestNG framework comes with NetBeans) and if we run our tests TestNG report generated into the default location. Here we learn how we make more user friendly reporting using TestNG-XSLT.

We follow this Steps: 
     
       Step 1:
       
             Download TestNG-XSLT from here and going to File -> Download option

       Step 2:
         
             Extract all files from zip folder, after the unzipping it looks like
      Step 3:

              Just copy the testng-results.xsl from the testng-xslt folder(\testng-xslt-1.1.2-master\src\main\resources) to our own project folder.

      Step 4:

              Now copy the saxon library from (testng-xslt-1.1.2-master\lib\saxon-8.7.jar) to our own project lib folder.

      Step 5:

            Now we are do the main thing that is modify build.xml of ant and add the following target to it.
   

<project name="test" basedir=".">
    <property name="LIB" value="${basedir}/lib" />
    <property name="BIN" value="${basedir}/bin" />
    <path id="master-classpath">
        <pathelement location="${BIN}" />
        <fileset dir="${LIB}">
            <include name="**/*.jar" />
        </fileset>
    </path>
    
    <target name="testng-xslt-report">
        <delete dir="${basedir}/testng-xslt">
        </delete>
        <mkdir dir="${basedir}/testng-xslt">
        </mkdir>
        <xslt in="${basedir}/build/test/results/testng-results.xml" style="${basedir}/testng-results.xsl" out="${basedir}/testng-xslt/index.html" processor="SaxonLiaison">
            <param expression="${basedir}/testng-xslt/" name="testNgXslt.outputDir" />

            <param expression="true" name="testNgXslt.sortTestCaseLinks" />

            <param expression="FAIL,SKIP,PASS,CONF,BY_CLASS" name="testNgXslt.testDetailsFilter" />

            <param expression="true" name="testNgXslt.showRuntimeTotals" />
      
            <classpath refid="master-classpath">
            </classpath>
        </xslt>
    </target>
</project> 

**Please change the path which is marked Red as per directory structure.

Note:

1. testNgXslt.outputDir - Sets the target output directory for the HTML content. This is mandatory and must be an absolute path. 

    e.g :
<param expression="${basedir}/testng-xslt/" name="testNgXslt.outputDir" />


2. testNgXslt.showRuntimeTotals - Boolean flag indicating if the report should display the aggregated information about the methods durations. The information is displayed for each test case and aggregated for the whole suite. Non-mandatory parameter, defaults to false. 

    e.g : <param expression="true" name="testNgXslt.showRuntimeTotals" />

3. testNgXslt.testDetailsFilter - Specified the default settings for the checkbox filters at the top of the test details page. Can be any combination (comma-separated) of: FAIL,PASS,SKIP,CONF,BY_CLASS 

   e.g : <param expression="FAIL,SKIP,PASS,CONF,BY_CLASS" name="testNgXslt.testDetailsFilter" />

4. testNgXslt.sortTestCaseLinks - Indicates whether the test case links (buttons) in the left frame should be sorted alphabetically. By default they are rendered in the order they are generated by TestNG so you should set this to true to change this behavior

   e.g : <param expression="true" name="testNgXslt.sortTestCaseLinks" />


5. testNgXslt.reportTitle - Use this setting to specify a title for your HTML reports. This is not a mandatory parameter and defaults to "TestNG Results".

   e.g : <param expression="TestName" name="testNgXslt.reportTitle" />

 
We need to provide the testng-xslt stylesheet the testng-results.xml , the path to the style sheet testng-results.xsl and the output index.html ( Those are here <xslt in="${basedir}/build/test/results/testng-results.xml" style="${basedir}/testng-results.xsl" out="${basedir}/testng-xslt/index.html" processor="SaxonLiaison"> ) path.

We also add the saxon library to our target classpath else we will get an error. In our case it is the master-classpath.

Now we run the ant target for report generation (in my case "testng-xslt-report
") and check the ouput folder configured by us for testng-xslt report.