Thursday, October 17, 2013

Speedup Your Selenium Test with PhantomJS

I was searching some way to speedup my WebDriver tests and this is what I came across, PhantomJS. It took awhile to understand how it works but it's worth spending time as I can say it's more than 50% faster when your run your test with PhantomJS. So,

What is PhantomJS?

PhantomJS is a headless WebKit scriptable with a JavaScript API. It's okay if you didn't understand it by this single line. Let me explain it to you.
Webkit is a browser engine which allows web browser to render pages, and it is used by many streamline browser (I guess Firefox and Google chrome both uses this). Now what is this headless then? Headless mean you won't be able to see any GUI component of the browser.

So Why PhantomJS is faster ?

This is the second question you might come up with. That if it is the same engine that many browser uses then how my test cases will execute faster if I will run them on PhantomJS.
The reason is, it just process data (request and response) it doesn't draw canvas.

We have had enough talk, now let's compare the result.

import java.util.List;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.phantomjs.PhantomJSDriver;
import org.testng.annotations.Test;

public class TestPhantoJS {

 /**
  * @author Gaurang_Shah
  * Following test will search the keyword on google 
  * and will print all websites on first page.
  */
 @Test
 public void GoogleSearch(){
  WebDriver driver = new PhantomJSDriver();
//  WebDriver driver = new FirefoxDriver();
  driver.get("http://google.com");
  driver.findElement(By.name("q")).sendKeys("phantomjs");
  driver.findElement(By.name("q")).submit();
  List<WebElement> sites = driver.findElements(By.xpath("//cite"));
  System.out.println(driver.getTitle());
  int index=1;
  for(WebElement site: sites){
   String siteName=site.getText();
   if(!siteName.equalsIgnoreCase(""))
    System.out.println(index+++":--"+site.getText());
  }
  driver.close();
 }
}
On my machine when I am running above test with PhantomJSdriver and FirefoxDriver following is the result.
FirefoxDriver - ~28 seconds
PhantomJSDriver - ~13 seconds
Pretty Fast. Right ??

Let Me Move My all Tests to PhantomJSDriver 

this is the first thought that my come up in your mind after this result. Right ???, however I wouldn't advice you to do that. And there are reason to this as well as mention below.
PhantomJS is just a headless WebKit which uses JavaScript, however it uses GhostDriver to run your test cases used webdriver. And it's in intermediate stage and you might feel bit trouble with someone the WebDriver API.

What is GhostDriver?? 

I am sure you must have this question in mind. Let me try to explain it to you. It's a Webdriver wire protocol in simple javascript for PhantomJS. (what the hell ??? ) ohh. let me make it more simple. GhostDriver is not but some kind of communicator between your Webdriver Bidning and PhantomJS. PhantomJS comes with the GhostDriver inbuilt, however it's available separately as well.

Tuesday, October 8, 2013

Webdriver: RobotFramework with Java - Part 1

There are so many posts available which states how to install/setup and configure robotframwork in python, however i didn't find any good posts which states how to configure robotframework in Java. So decided to write a blog.

Install/Setup Robot Framework 

To run webdriver test with RoboFramework in java you require following two jar files. 

Download the above two files and put that into some directory. 

Sample Test Case

Create the testcase.txt as mention below into the same directory in which you downloaded JARs
***Setting***
Library    Selenium2Library

*** Test Cases ***
Get Current Browser Test
    Open Browser  http://google.com

Run Test Case

To run the RobotFramework test case you need to set the CLASSPATH. Please add above jar files into your classapth and run the following command 
java org.robotframework.RobotFramework run testcase.txt

Verify Results

Results will be located into same directory in which you have created test case. 

Tuesday, October 1, 2013

WebDriver: TestNG with ANT

Few posts back I explained how to use Maven with Webdriver and TestNG. Now let's see how to use ANT with WebDriver and TestNG.
<project name="WebDriverAntTestNG" default="run" basedir=".">
 
 <path id="libs">
  <!-- Include all the external Jar files -->
  <fileset dir="${basedir}\src\jars">
   <include name="*.jar"/>
  </fileset>
  <!-- Include all the compile classes -->
  <fileset dir="bin">
   <include name = "**/*.class"/>
  </fileset>
  <pathelement path="${basedir}\bin"/>
  </path>
 
 <target name="run">
    <antcall target="init"/>
    <antcall target="compile"/>
    <antcall target="runTests"/>
  </target>
 
   <!-- Delete old data and create new directories -->
  <target name="init" >
   <echo>Initlizing...</echo>
   <delete dir="bin" />
    <mkdir dir="bin"/>
    <delete dir="report" />
    <mkdir dir="report"/>
    
  </target>
 
 <!-- Complies the java files -->
 <target name="compile">
    <echo>Compiling...</echo>
    <javac includeantruntime="false" debug="true" srcdir="src" destdir="bin"   classpathref="libs" />
  </target>

 <!-- Runs the file and generates Reportng report -->
 <target name="runTests" description="Running tests" >
  <echo>Running Tests...</echo>
    <taskdef resource="testngtasks" classpathref="libs"/>
    <testng outputDir="report"
    haltonfailure="true"
    classpathref="libs"
      >
   <classfileset dir="bin" includes="**/*.class" />
    </testng>
  </target>

</project>

Targets Explained:


Run: This is main target, which will call all the below target in order.
Init: This target will delete the Bin an Report directory and will crate again in order to clean. 
Compile: This target will compile all the java classes. 
runTests: This target contain the TestNGTask which will all the testng tests. 


Tuesday, September 3, 2013

Jenkins: Static Analysis with CheckStyle

In the last post I mention how to configure your Maven Webdriver project on Jenkins, today let's see how to configure checkStyle plugin for static analysis with jenkins.

Configure Check Style with Maven

Mention the following plugin in pom.xml, make sure you mention it inside build block 
pom.xml

<plugin>
 <groupId>org.apache.maven.plugins</groupId>
 <artifactId>maven-checkstyle-plugin</artifactId>
 <version>2.10</version>
 <configuration>
  <sourceDirectory>src</sourceDirectory>
 </configuration>
</plugin>

Configure Check Style with Jenkins
follow the steps mention below to configure and generate checkStyle Report in jenkins
Install checkStyle plugin Navigate to Manage Jenkins->Manage Plugin and install checkStyle plugin and then restart the jenkins 

Configure checkStyle for project
 Following is how to configure checkStyle for Maven project, it might vary if you are using ANT. 
  • Append checkstyle:checkstyle to your build goal
  • check Publish Checkstyle analysis results
    Configure Checkstyle for project
    Configure checkStyle for Project
Configure checkStyle Reports
 Now you need to configure which reports you want to see for this project, follow the steps to configure reports
  • Navigate to Jenkins home page and create new view
    Add New Dashboard for checkStyle
    Add new dashboard for checkstyle
  • Select the project you want to include for checkStyle Report
    Add Projects for checkStyle Report
    choose jenkins jobs for checkstyle
  • Include the graphs/reports you want
    Select Graphs for checkStyle report
    configure checkstyle report in jenkins

Monday, September 2, 2013

WebDriver with Jenkins

In the last post we see how to create Maven Project for WebDriver from eclipse. Now let's configure same Webdriver Maven Project on Jenkins.

Setup Jenkins on Windows 

download the jenkins from following location
http://jenkins-ci.org/
Running Jenkins as War file 
You can run jenkins using war file, if you are doing it you don't need any slave to start on machine. Running Jenkins as Windows Service 
If you have installed Jenkins as Windows Services then you need to Start Slave and Bind you project to that slave.

Create/Run Slave Node 

If Jenkins is installed as Windows Services you need to start the JNLP slave node on machine where you need to execute your test cases. Follow the process to create node.
  • Go to Manage Jenkins->Manage Nodes and Click on New Node
  • Enter the Node Name and choose Dumb Slave
    Create Jenkins Slave node for WebDriver Execution
    Create Jenkins Slave node for WebDriver Execution


  • Enter the information as mention in the screenshot
    Configure Node for WebDriver
    Configure Node for WebDriver
  • After saving node will be listed under Nodes 
    All Available Nodes in Jenkins
    All Available Nodes in Jenkins
  • Start the node by Running displayed command in CMD
    Start JNLP node in Jenkins
    Starting JNLP Node in Jenkins
  • if everything has been done correctly if you will able to see small java program running
    Connected JNLP Node
    Connected JNLP Node


Configure Maven in Jenkins

Before you create a new Job for Maven WebDriver Project, let's configure Maven in jenkins
Go to Manage Jenkins->Configure System and Provide Installation directory for JDK and Maven as mention in screenshot below
Configure JDK and Maven in Jenkins
Configure JDK and Maven in Jenkins

Create New Job on Jenkins

Now let's create the new Job for Project
  • Go to Home page and click on New Job
    Create Jenkins Job for Maven WebDriver Project
    Create Jenkins Job for Maven WebDriver Project
  • Restrict the job to run on the Slave Node we created
    Configure WebDriver Project to run on Specific Node
    Configure WebDriver Project to run on Specific Node
  • Click on Use custom workspace and Mention your workspace location und Directory
  • Provide the path of pom.xml in Root POM and provide Test in Goals and Options
    Provide Maven in Goal in Jenkins
    Provide Maven Goal in Jenkins

Sunday, September 1, 2013

WebDriver with Maven

Maven is a build Automation Tool somewhat like ANT. Having use ANT for the previous project wanted to try Maven this time. I thought it would be easy as I know ANT, however it took a while for me to figure out as i didn't find any proper tutorial on net. And this is the reason I am writing new Blogpost.

I have just started, So if someone knows the better way to do few things mention here please let me know in comment.

Now let's try setting up new Maven Project for Webdriver using Eclipse. However before you do, you need to download and setup Maven on you local machine.

Setup up Maven
  • download the appropriate maven from the following site.
    http://maven.apache.org/download.cgi Extract it to some location and setup the PATH variable. 
  • If you have done everything correctly, Following command on CMD will let you know the Maven Version.
    mvn --version 


Install Maven Plug-in in Eclipse 
Install the m2Eclipse plugin in you eclipse

Setup Maven Project for WebDriver.

  • In Eclipse choose New Maven Project and check the "Create Simple Project" 
  • Fill the Group id and Artifact id 
  • Create New Class named "GoogleTest" under "src/test/java" Copy Following code in it.
  • GoogleTest.java 

    import org.openqa.selenium.WebDriver;
    import org.openqa.selenium.firefox.FirefoxDriver;
    import org.testng.annotations.Test;
    
    /**
     * @author Gaurang_Shah
     */
    public class GoogleTest {
     private WebDriver driver;
    
     @Test
     public void verifySearch() {
      driver = new FirefoxDriver();
      driver.get("http://www.google.com/");
      driver.quit();
     }
    }


  • It will show you some compile time error as we haven't added the dependencies yet.
  • Maven mention all the dependencies in pom.xml file. Please copy and replace the following pom.xml with your project pom.xml file.
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     <modelVersion>4.0.0</modelVersion>
     <groupId>MavenWebDriverDemo</groupId>
     <artifactId>MavenWebDriverDemo</artifactId>
     <version>0.0.1-SNAPSHOT</version>
    
     <dependencies>
      <dependency>
       <groupId>org.seleniumhq.selenium</groupId>
       <artifactId>selenium-java</artifactId>
       <version>2.33.0</version>
      </dependency>
      <dependency>
       <groupId>org.seleniumhq.selenium</groupId>
       <artifactId>selenium-server</artifactId>
       <version>2.33.0</version>
      </dependency>
      <dependency>
       <groupId>org.testng</groupId>
       <artifactId>testng</artifactId>
       <version>6.8.5</version>
      </dependency>
     </dependencies>
    </project>
  • Running Project
    • To run from Eclipse, Right click on pom.xml and choose Run as --> Maven Test 
    • To run from command line, Go to project directory and enter following command
       mvn test

    Monday, July 22, 2013

    webdriver - handle untrusted ssl certificate

    While doing automation of https site there are chances when you get the following error.
    This Connection is Untrusted. 



    Reason: This certificate is not issued by some valid authority, it's a self signed certificate.

    Solution:

    • Create a new profile and add this certificate in that profile by using following steps.
    • Make sure you are accessing site though the domain for which certificate has issued.
    •  If you get the above screen after accessible the site, You need to add certificate in Exception so next time it doesn't give you error.
    • However while adding certificate make sure "Permanently store this exception" check box is selected. 
    • If  "Permanently store this exception" is enable the history.

    • Now you need to give path of this newly created profile while creating the object of WebDriver.

    Wednesday, July 17, 2013

    PyTest - Quick Reference

    What is PyTest?
    PyTest is just like any other unit test framework for Python. It generates JUnit XML report as well which makes easy to integrate it's report with Jenkins

    How to Install PyTest: 
    pip install -U pytest or
    easy_install pytest

    How it Identifies: 
    Every unit testing framework has some pattern though which identifies which is Test Class, which is Test Method, Which is Setup and TearDown method and so do PyTest.
    Test Class - Any Class name which starts with Test is indentified as Test Class (i.e. TestMathFunc) Test- Any function which starts with test_ is identified as test method (i.e. test_devision)
    Apart from this there are few setup and teardown methods as well, as mention below
    setup_module:- Called before the first test of the module
    teardown_module:- Called after the last test of the module
    setup_class:- Called before the first test of the class
    teardown_class:- Called after the last test of the class 
    setup_method:- Called before each and every test inside class
    teardown_method:- Called after each and every test inside class
    setup_function:- Called before each and every test outside class 
    teardown_function:- Called after each and every test outside class 

    Sample Code:
    PyTestDemo.py
    class TestPyTestDemo():
        """
        This class demonstrates who to write simple test using pytest framework
        @author: Gaurang Shah
        @contact: gaurangnshah@gmail.com
        
        """
        def add(self,arg1,arg2):
            return arg1+arg2
    
        def test_pass(self):
            print "test_pass"
            assert self.add(2, 3) == 5
            
        def test_fail(self):
            print "test_fail"
            assert self.add(0, 2) == 1
    
        def setup_method(self,method):
            "This method will be called before each and every method inside class"
            print "setup_method"
            
        def teardown_method(self,method):
            "This method will be called after each and every method inside class"
            print "teardown_method" 
                    
        @classmethod
        def setup_class(cls):
            "This method will be called before first method of classe"
            print "setup_class"
             
        @classmethod
        def teardown_class(cls):
            "This method will be called after last method of class"
            print "teardown_class"
    
    def setup_module(module):
        "This method will be called before first method of module"
        print "setup_module"
    
    def teardown_module(module):
        "This method will be called after last method of module"
        print "teardown_module"  
       
    def setup_function(function):
        "This method will be called before each and every function outside class"
        print "setup function"
        
    def teardown_function(function):
        "This method will be called before each and every function outside class"
        print "teardown function"
        
    def test_function():
        print "test_function"
    How to Execute :
    py.test PyTestDemo.py

    Monday, January 28, 2013

    WebDriver: isTextPresent

    WebDriver is way far better in many ways than selenium RC, However if you have migrated from Selenium RC, you will miss few functions. And two on the top lists are isTextPresent and isElementPresent. Though it's not available in webdriver, it's not complicated to implement, there are various ways to the same thing. I will discuss few ways in following post.

    1. Using in in-build PageSource API
    2. public boolean isTextPresent(String text){
       if (driver.getPageSource().contains(text)) {
        return true;
       }
       else 
        return false;
      }
      Disadvantages:
      • It is too slow as compared other two options as it checks in whole page source.
      • Result might be wrong as it doesn't verify only visible text on webpage but whole source code (script + html tags)
    3. Using XPath
    4. public boolean isTextPresent(String text){
       try {
        driver.findElement(By.xpath("//*[contains(.,'"+text+"')]"));
        return true;
       }catch(NoSuchElementException e){
        return false;
       }
      }
      Disadvantages:
      As it is using XPath, it might be slow on IE than on Firefox and Chrome Browsers.
    1. Using Selenium RC Function.
    2. public boolean isTextPresent(String text){
       try{
        WebDriverBackedSelenium selenium = new WebDriverBackedSelenium(driver, "");
        if(selenium.isTextPresent(text)){
         return true;
        }else{
         return false;
        }
       }catch(Exception e){
        return false;
       }
      }
      Disadvantages:
      It is using Selenium RC code.