Tuesday, January 21, 2014

Sikuli API with Selenium WebDriver


Some time we need to integrate different API with Selenium WebDriver  to automate our application.

Here we learn how to integrate Sikuli with Selenium Web Driver.Now question should arise

1.What is sikuli?

Ans:-It is an image based GUI Automation tool.

2.How to integrate Sikuli with Selenium Webdriver?

Ans:-There is 2 way to integrate sikuli with selenium webdriver

i. Install Sikuli and add this jar(which is on installation path) into our selenium webdriver project.
ii. Another way is add sikuli-api-1.0.2-standalone.jar from  Sikuli Java API download page.

We start with second one we may learn first one later.

Step1:

First of all we download sikuli-api-1.0.2-standalone.jar.

Step2:

Add this jar into our Selenium WebDriver project.

Step3:

We know that Sikuli is image based automation tool.So Sikuli understand only picture so on which element we want to click need to save as picture.

Step4:

Now we write the code as given below to automate the Google Search page. Here we type "abcd" on search box and click on search button then we click the link using sikuli.Here one thing should be considered that we should taken the screen shot of the link previously and screenshot text should be present on search.



    public static void main(String args[]) throws IOException {
        WebDriver driver = new FirefoxDriver();
        driver.get("https://www.google.com");
        driver.findElement(By.name("q")).sendKeys("abcd");
        driver.findElement(By.id("gbqfb")).click();
        WebDriverWait wait = new WebDriverWait(driver, 10);
        wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("//*[@id='rso']/li[1]/div/h3/a")));

        /*
         * We Define the Screen region
         * as Desktop Screen region.
         */

        ScreenRegion s = new DesktopScreenRegion();
        /*
         * We need to capture the Image
         * and save this as png file extention
         */

        ImageIO.write(s.capture(), "png", new File("E:\\Sikuli\\saved.png"));
        driver.manage().window().maximize();

        /*
         * We need to load the picture
         * on which we click for automation
         */

        Target tg=new ImageTarget(new File("E:\\Sikuli\\1.png"));
         /*
         * Again we Define the Screen region
         * as Desktop Screen region because we
         * maximize the screen.
         */

        ScreenRegion sr=new DesktopScreenRegion();
        /*
         * Initialize the mouse to click on element
         */

        Mouse mouse=new DesktopMouse();
        mouse.click(sr.wait(tg, 5000).getCenter());

    } 
 

Monday, January 13, 2014

Log4j Settings With Selenium WebDriver


Here we learn how to use and configure Log4j for Selenium Web Driver.

Log4j have 3 part
  1. Logger
  2. Appender
  3. Layout or Formatter
1.Logger
 
      This is basically logging the application status.It have 6 level

      a.TRACE
      b.DEBUG
      c.INFO
      d.WARN
      e.ERROR
      f.FATAL

and order of this level is DEBUG < INFO < WARN < ERROR < FATAL means if we set logger as WARN then we get ERROR and FATAL log also.

We set this in properties file like

 # Log levels
log4j.rootLogger=INFO,CONSOLE,R,HTML,TTCC


Here we set INFO as a level for logging.Console,R and HTML are appender we learn later about this.This names are arbitrary.

2.Appender 
    
    This means where it writes log.It may write log in console,text file etc.


We set this in properties file like

# Appender Configuration
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender


# Rolling File Appender
log4j.appender.R=org.apache.log4j.RollingFileAppender

log4j.appender.TTCC=org.apache.log4j.RollingFileAppender
# Path and file name to store the log file
log4j.appender.R.File=./logs/testlog.log

log4j.appender.TTCC.File=./logs/testlog1.log   
# 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


3.Layout or Formatter

   It's name clearly defines what it is.It is use to format the output file.This is used how we want to see the output it may be on Console,Text or even HTML.

We set this in properties file like

This is for console layout:

# 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



This is for text file layout:

# Layout for Rolling File Appender
log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=%d - %c - %p - %m%n

log4j.appender.TTCC.layout=org.apache.log4j.TTCCLayout
log4j.appender.TTCC.layout.DateFormat=ISO8601


This is for HTML layout:

# 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


How to Configure Log4j:

Step 1:
      Add a properties file in our project.


Step 2:
     Configure file Should be looks like
# Log levels
log4j.rootLogger=info,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=%d [%t] %-5p (%c:%L:%F) - %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 [%t] %-5p (%c:%L:%F) - %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 3:

        We need to pass the class name of the getLogger() method for  which we take this log.

It looks like :
        private static final Logger logger = Logger.getLogger("Log4JSettings"); 

Step 4:
        
         We need to locate confire file using code by this code

PropertyConfigurator.configure("Log4j.properties");

Step 5:
        
        Add different log in our application where we want in our application.
 
It looks like :

Sample Code is given below


package seleniumwebdriver;

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;

public class Log4JSettings {
   
    private static final Logger logger = Logger.getLogger("Log4JSettings");
   
    public static void main(String args[]) throws IOException {
        PropertyConfigurator.configure("Log4j.properties");
       
        try {


                 /**
                    * We try to read a File which is not present 
                    * in the path so it get exception which is shown 
                    * in Console Text File as well as HTML Format
                    * as  described in Log4j Properties File.                  */     
            FileInputStream fstream =
                    new FileInputStream("D:\\textfile.txt");
            DataInputStream in =
                    new DataInputStream(fstream);
            BufferedReader br =
                    new BufferedReader(new InputStreamReader(in));
            String strLine;
            while ((strLine = br.readLine()) != null) {
                System.out.println(strLine);
            }
            in.close();
        } catch (FileNotFoundException fe) {

            logger.error("File Not Found", fe);
            logger.warn("This is a warning message");
            logger.trace("This message will not be logged since log "
                    + "level is set as DEBUG");

        } catch (IOException e) {
            logger.error("IOEXception occured:", e);

        }
    }
}
 


  

 

Saturday, January 11, 2014

Taking Screen Shot Using Webdriver


We need to take screen shot of the application for capturing the state of the application.It may be required to store the state when application not behave as per requirement or to store the state after some operation properly happened.

There is two way to take the screen shot.

1.

a. TypeCast the driver object as TakesScreenshot class and use getScreenshotAs(OutputType.FILE) method.


b. Then copy this screen shot file in the desired directory using FileUtils.copyFile(scrFile, new File("src//google.jpg"));


Example Code is given below:

package seleniumwebdriver;

import java.io.File;
import java.io.IOException;
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;



public class ScreenShots{
        public static void main(String[] args) throws IOException {
        WebDriver myTestDriver = new FirefoxDriver();
        myTestDriver.get("http://www.google.com");
        File scrFile = ((TakesScreenshot)myTestDriver).getScreenshotAs(OutputType.FILE);
        FileUtils.copyFile(scrFile, new File("src//google.jpg"));

        myTestDriver.quit();
    }

}

2. On previous example we take the screen shot using Selenium Web Driver but there is no way to take screen shot when any event happen on webdriver.

Here we learn how to take screen shot when any event happen webdriver take the screenshot and store the Image file into the desired path. There is 15 abstract method into the WebDriverEventListener class so when we implement this it will generate 15 methods to overrride.

1.   public void beforeNavigateTo(String url, WebDriver driver) 
2.   public void afterNavigateTo(String url, WebDriver driver)
3.   public void beforeNavigateBack(WebDriver driver)
4.   public void afterNavigateBack(WebDriver driver)
5.   public void beforeNavigateForward(WebDriver driver)
6.   public void afterNavigateForward(WebDriver driver)
7.   public void beforeFindBy(By by, WebElement element, WebDriver driver)
8.   public void afterFindBy(By by, WebElement element, WebDriver driver)
9.   public void beforeClickOn(WebElement element, WebDriver driver)
10  public void afterClickOn(WebElement element, WebDriver driver)
11  public void beforeChangeValueOf(WebElement element, WebDriver driver)
12. public void afterChangeValueOf(WebElement element, WebDriver driver)
13. public void beforeScript(String script, WebDriver driver)
14. public void afterScript(String script, WebDriver driver)
15. public void onException(Throwable throwable, WebDriver driver) 


So we need to follow this septs:




a. Implement WebDriverEventListener class  
b. We also need to register the driver  like this way :

                   WebDriverEventListener evtlistner=new ScreenShots();
                   driver = new EventFiringWebDriver(new FirefoxDriver()).register(evtlistner);


Sample code is given below:


public class ScreenShots implements WebDriverEventListener{
        public static void main(String[] args) throws IOException {
                   WebDriver driver;

                  //WebDriverListner is assigned for the desired class
                  

                   WebDriverEventListener evtlistner=new ScreenShots();
                   
                  //Register Firefox driver with this event listner
                   

                   driver=new EventFiringWebDriver(new FirefoxDriver()).register(evtlistner);
                   driver.navigate().to("https://www.google.com");
                   driver.navigate().back();
                   driver.navigate().forward();
                   driver.navigate().refresh();
               driver.quit();
    }

    @Override
    public void beforeNavigateTo(String url, WebDriver driver) {
        File scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
        StringBuilder s= new StringBuilder();
        System.out.println(s.append(String.valueOf(Calendar.getInstance().get(Calendar.HOUR))).append(Calendar.getInstance().get(Calendar.HOUR)).append(Calendar.getInstance().get(Calendar.MILLISECOND)));

        try {
                    FileUtils.copyFile(scrFile, new File("src//"+s+".jpg"));
                } catch (IOException ex) {
                    Logger.getLogger(ScreenShots.class.getName()).log(Level.SEVERE, null, ex);
                }
    }

 

Thursday, January 9, 2014

Internet Explorer Configuration With Selenium WebDriver


Previously we execute all test on firefox but here we try to do something with Internet Explorer(IE).

IE driver does not come with Selenium webdriver package so we need to download separately and configure it to run the script properly.Now we learn how to configure IE driver :

Step1

Download IE Driver Server from here.We can download 32 bit 64 bit driver as per our test environment.



 Step 2

 Extract file from downloaded zip file.


Step 3

 Open the extracted folder and get "IEDriverServer.exe" file.

Step 4

Copy the directory path where IEDriverServer.exe file exists and put it into the environment variable under user variable.To open Environment variable path we just need to right click on My Computer -> Properties ->Advanced then click on Environment Variables.



 Step 5

If we use vista onwards machine then we check "Enable Protected Mode" from Security tab for all zone of IE settings.



If enable this option is not possible then put this code on our test script

DesiredCapabilities capabilitiesIE = DesiredCapabilities.internetExplorer();
            capabilitiesIE.setCapability(InternetExplorerDriver.INTRODUCE_FLAKINESS_BY_IGNORING_SECURITY_DOMAINS, true);


WebDriver driver = new InternetExplorerDriver(capabilitiesIE);

Step 6

Set the IE zoom 100% from view option.

After opening the IE it give an Warning in output view of our JAVA IDE like

Started InternetExplorerDriver server (32-bit)
2.39.0.0
Listening on port 54001
Jan 9, 2014 4:39:20 PM org.apache.http.impl.client.DefaultRequestDirector tryExecute
INFO: I/O exception (org.apache.http.NoHttpResponseException) caught when processing request: The target server failed to respond
Jan 9, 2014 4:39:21 PM org.apache.http.impl.client.DefaultRequestDirector tryExecute
INFO: Retrying request 

We can ignore this,actually this shows because IE driver is slow so it cannot communicate quickly with port 54001.

In below a sample code is there

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package seleniumwebdriver;

import java.io.File;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.remote.DesiredCapabilities;

/**
 *
 * @author Administrator
 */
public class IEDriverSetUp {

    public static void main(String args[]) {
        try {
            File ieExecutable = new File("C:/IEDriverServer_Win32_2.39.0/IEDriverServer.exe");
            System.setProperty("webdriver.ie.driver", ieExecutable.getAbsolutePath());
            DesiredCapabilities capabilitiesIE = DesiredCapabilities.internetExplorer();
            capabilitiesIE.setCapability(
                    InternetExplorerDriver.INTRODUCE_FLAKINESS_BY_IGNORING_SECURITY_DOMAINS, true);
            WebDriver driver = new InternetExplorerDriver(capabilitiesIE);

            driver.navigate().to("http://www.google.com");
        } catch (Exception ex) {
            Logger.getLogger(IEDriverSetUp.class.getName()).logp(Level.SEVERE, IEDriverSetUp.class.getName(), null, null, ex);
        }
    }
}

 




Monday, January 6, 2014

Scroll Page Using Java Script And Find Dynamically Loaded Element


Presently we can see that total webelement is not loaded at one moment rather element loaded when we scroll the pages.

So here we choose "Jabong" for an example page.Here more product list generated when we go down slowly .We stop scrolling when we find our desired product and click on this product.

To Scroll the page we need to fire the java script. For this we follow this steps:

Step1:
import org.openqa.selenium.JavascriptExecutor;

Step2:
((JavascriptExecutor) driver).executeScript("window.scrollBy(0,100)", "");


Now problem is how to find element which we want, because element loaded when page scrolled.
We get exception if element is not present on the page so we should catch this exception and scroll the page again to find the element until the page end.



Sample Code is given below:

import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.Wait;
import org.openqa.selenium.support.ui.WebDriverWait;

/**
 *
 * @author Administrator
 */
public class Scroll {

    public static void main(String args[]) {

        WebDriver driver = new FirefoxDriver();
        driver.manage().window().maximize();
        driver.navigate().to("http://www.jabong.com/men/clothing/"
                + "?source=topnav");
        driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
        System.out.println("Close the modal popup");
        driver.findElement(By.id("jab-vchr-cls")).click();
 /**
 * while(
!reachedbottom) loop is required to search the
 * element until page end .We put find
 * element within try-catch and if it get
 * exception it scroll the page and again
 * try to find the element.
 */


        boolean reachedbottom = Boolean.parseBoolean(js.executeScript("return $(document)"
                + ".height() == ($(window).height() + $(window).scrollTop());").toString());
        while (!reachedbottom) {
            ((JavascriptExecutor) driver).executeScript("window.scrollBy(0,600)", "");
            try {
                reachedbottom = Boolean.parseBoolean(js.executeScript("return $(document).height() "
                        + "== ($(window).height() + $(window).scrollTop());").toString());
                WebElement element = driver.findElement(By.xpath("//*[@id='http://static3.jassets.com/p/The-Indian-Garage-Co.-Checks-Red-Casual-Shirt-2889-679124-1-catalog.jpg']/img"));
                Wait<WebDriver> wait_element = new WebDriverWait(driver, 10);
                wait_element.until(ExpectedConditions.elementToBeClickable(element));
                element.click();
                System.out.println("!!!!!!!!!!!!!!At Last Get Success!!!!!!!!!!!!!!!!");
                break;
            } catch (Exception ex) {
                Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
                System.out.println(ex.getMessage());
            }
        }
    }
}






Handling Modal Pop Up Of an Web Page


We can see that some webpage show some banner, offer coupon or some registration form after page loaded and background page was disabled.

We choose "Jabong" for an example page to handle modal pop up.Some code is given below:

        WebDriver driver = new FirefoxDriver();
        driver.manage().window().maximize();
        driver.navigate().to("http://www.jabong.com/men/clothing/"
                + "?source=topnav");
        driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
        System.out.println("Close the modal popup");
        driver.findElement(By.id("jab-vchr-cls")).click();


 

Sunday, January 5, 2014

Open Link In New Tab Using Mouse Click


We can Open link in new tab pressing Control + Left mouse click in firefox.So here we take Google as an example page and open "About" and "+You" in new Tab.

 WebDriver driver = new FirefoxDriver();
 driver.navigate().to("http://www.google.com");

 WebElement oWE = driver.findElement(By.linkText("About"));
 WebElement oWE1 = driver.findElement(By.linkText("+You"));
Actions oAction=new Actions(driver);

oAction.moveToElement(oWE).keyDown(Keys.CONTROL).click(oWE)
                             .keyUp(Keys.CONTROL).perform();

Thread.sleep(1000);
Actions oAction1=new Actions(driver);

oAction1.moveToElement(oWE1).keyDown(Keys.CONTROL).click(oWE1)
                             .keyUp(Keys.CONTROL).perform();


Friday, January 3, 2014

Different Type Of Wait in Selenium Web Driver


Sometime our test fails due to page was not loaded with all element for slow internet connection or may be the poor response time.So now question is how to handle this problems?

There is 2 different way to handle this.

1.Implicit Waits
2.Explicit Waits


1.Implicit Waits

WebDriver to wait for an element if they are not immediately available. So, WebDriver does not throw NoSuchElementException immediately.This is known as implicitlyWait().This can be achieved using :

driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);


Keep in mind:
1.If the DOM is present within the wait time it should not wait for the remaining time it go for the next step,
for an example:

 driver.manage().timeouts().implicitlyWait(25, TimeUnit.SECONDS);

Here we wait for 25 seconds, after that it gives NoSuchElementException.If the element present in 10 second then it should not waiting for another 15 seconds.

Cons:
1. No Condition it blindly wait for given seconds.
2.Once set, the implicit wait is set for the life of the WebDriver object instance. 

 2.Explicit Waits

A.Thread.sleep() 

One way is that, wait the running program for sometime, this can be achieved using:

Thread.sleep().

Cons:
1. It is not a better way because if the the element is present within this wait time, program does not move further until the wait time finished.
2. Some computer are fast, and others are slow, in a slow computer, an element may not show up within the wait time.
3.It will sleep time for script, not good way to use in script as it's sleep without condition.

B.Expected Condition

Another way is that we define to wait for a certain condition to occur before proceeding further in the code like :
        
        Wait<WebDriver> waitforelement=new WebDriverWait(driver, 10);
       
waitforelement.until(ExpectedConditions.elementToBeClickable(By.name("q"))); 

What we do here in this code? Here we check that element is click able or not and we try to wait 10 sec for this condition.If this condition fulfill with in 10 sec then it should not wait for remaining time. 

If we want to customize the Expected condition then we write in this way

       waitforelement.until(new ExpectedCondition<Boolean>(){
       
       @Override
        public Boolean apply(WebDriver f) {
            return f.findElement(By.name("q")).isEnabled();
        }
          
       });

 Or
       waitforelement.until(new Function<WebDriver, Boolean>() {

        @Override
        public Boolean apply(WebDriver f) {
               
return f.findElement(By.name("q")).isEnabled();    
    });


Another thing that we can also use for explecit wait, which is Fluent wait .Using this  the maximum amount of time to wait for a condition, as well as the frequency with which to check the condition. Furthermore, the user may configure the wait to ignore specific types of exceptions whilst waiting, when searching for an element on the page.

It can be writen as:

       Wait<WebDriver> waitforelement=new FluentWait<WebDriver>(driver)
             .withTimeout(10, TimeUnit.SECONDS) 
             .pollingEvery(2, TimeUnit.SECONDS) 
             .ignoring(NoSuchElementException.class);
       waitforelement.until(ExpectedConditions.elementToBeClickable(By.name("q")));


Or
     waitforelement.until(new ExpectedCondition<Boolean>() {

        @Override
        public Boolean apply(WebDriver f) {
            return f.findElement(By.name("q")).isEnabled();
        }
    });


Or 
     waitforelement.until(new Function<WebDriver, Boolean>(){

        @Override
        public Boolean apply(WebDriver f) {
        return f.findElement(By.name("q")).isEnabled();
        }
    });