Alternate Way for sendKeys


One of my friend called me yesterday, he had an interview on Selenium WebDriver and got confused on 1 Question.

What is an alternative for sendKeys Method in WebDriver?

I also got stammered on this and thought in mind

Why the hell do we need this?

There are below possible reason that I could find, When we need any alternative to sendKeys.
  1. When the Text element is disabled or locked, sendKeys can not set the value in text field.
    (in my opinion, this is not the correct way of Automation, because the element is locked or disabled by intend to not allow any text insertion)
  2. When we want to write huge text as input... that time the way WebDriver work, by sending Series of characters from String one by one, and Which is Very time consuming. so to minimize that time we can use this alternate method
So now we have above two problems with sendKeys ......

Solution!!!

The best alternative I found is JavaScript

Way 1 to Execute Script

        WebDriver driver = new FirefoxDriver();
        driver.get("http://www.google.com");
        JavascriptExecutor myExecutor = ((JavascriptExecutor) driver);
        myExecutor.executeScript("document.getElementsByName('q')[0].value='Kirtesh';");
        driver.quit();
in above example we have used javaScript to locate the Search Textbox and set the "Kirtesh" value in it.
lets look at another approach.

Way 2

        WebDriver driver = new FirefoxDriver();
        driver.get("http://www.google.com");
        WebElement searchbox = driver.findElement(By.xpath("//input[@name='q']"));
        JavascriptExecutor myExecutor = ((JavascriptExecutor) driver);
        myExecutor.executeScript("arguments[0].value='Kirtesh';", searchbox);
        driver.quit();
second example is very controlled approach, Here we are passing WebElement as a argument to the javaScript
There is still many more remained from JavascriptExecutor ......
Keep Exploring...

Keep Automating..................

Rerun Failed JUnit Tests

Hello Friends,
Many times Selenium tests are getting failed due to no reason... as UI tests are fragile in nature.
There are many uncertainties like slow response, browser issues... and many more.

Generally we use readily available Test frameworks like JUnit & TestNG to write test cases. TestNG framework has lot off cool features like rerun test, dependency test and many more... but still many of us have JUnit as first choice.

Problem!!!!

JUnit frame work does not provide any direct feature to rerun the failed tests. So problem is

How we can rerun Failed test in JUnit?


Solution

JUnit provides a Interface TestRule, by implementing this we can apply rule for running the test. We have used same class to solve our problem, Please have a look below code snippet in which have created Class Retry which implements the TestRule interface.
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;

/**
 * Created by Kirtesh on 20-02-2015.
 */
public class Retry implements TestRule {
    private int retryCount;

    public Retry(int retryCount) {
        this.retryCount = retryCount;
    }

    public Statement apply(Statement base, Description description) {
        return statement(base, description);
    }
    private Statement statement(final Statement base, final Description description) {
        return new Statement() {
            @Override
            public void evaluate() throws Throwable {
                Throwable caughtThrowable = null;

                // implement retry logic here
                for (int i = 0; i < retryCount; i++) {
                    try {
                        base.evaluate();
                        return;
                    } catch (Throwable t) {
                        caughtThrowable = t;

                        //  System.out.println(": run " + (i+1) + " failed");
                        System.err.println(description.getDisplayName() + ": run " + (i + 1) + " failed");
                    }
                }
                System.err.println(description.getDisplayName() + ": giving up after " + retryCount + " failures");
                throw caughtThrowable;
            }
        };
    }
}

That's it.. you can directly copy above class & use this rule in your junit test... look in to below test
    @Rule public Retry retry = new Retry(3);
    @Test
    public void myWebDriverTest(){
 driver.get(htmlPath);
 driver.findElement(By.id("user")).sendKeys("MyUser");
 driver.findElement(By.id("password")).sendKeys("myPassword");
 driver.findElement(By.id("login")).click();
 Assert.assertTrue(driver.findElements(By.linkText("Logout")).size()>0);
        driver.quit();
    }
above test will get rerun if it get fails for 3 time, 3 is the number which you can set in @Rule Retry...

Hope this may hep you.....

Keep exploring... Keep automating....

Find Broken Images in Web-Page

Broken Images

Hello Friends....
While testing the web-page, It always happen when page renders properly but Image/Images are not displayed due to incorrect path
Technically images which are not having correct path are called as Broken Images.
Basically Selenium help us to mimic human actions (e.g. clicking, typing, dragging, dropping, etc.)
So how do we use it to test for broken images?

Solution!!!

Selenium WebDriver is not directly equipped with this... but there are several way to do this..
We will use HttpURLConnection Object with selenium to do this.We will need to go through the below steps.

  1. Find all images on the page
  2. Iterate through each image, and find the src attribute and validate with a 404 status code
  3. Store / Notify / Log the broken images path in a collection

HttpURLConnection Example

Please look into below code snippet
import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.URL;
import java.util.ArrayList;
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;

public class ImageUtills {
 
 public static List<WebElement> getBrokenLinks(String Weburl) {
  WebDriver driver = new FirefoxDriver();
  driver.get(Weburl);
  List<WebElement> Images = driver.findElements(By.xpath("//img"));
  List<WebElement> brokenImages = new ArrayList<WebElement>();
  
  //Use Proxy if your network is under any proxy server
  Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("Your Proxy Server", 80));
  for(WebElement image:Images){
   String url= image.getAttribute("src");
   try 
   {
    //You can keep empty if there is no proxy.
    HttpURLConnection http = (HttpURLConnection)new URL(url).openConnection(proxy);
    if(http.getResponseCode()!=200){
     brokenImages.add(image);
    }
   
   } 
   catch (Exception e) {
    brokenImages.add(image);
    e.printStackTrace();
   } 
  }
  
  /// You can further use brokenImages List for display or notify or assert
  return brokenImages;
  
 }

}

Below is Different Response codes and there meanings.. it may help you some where

1xx: Information

Message: Description:
100 Continue The server has received the request headers, and the client should proceed to send the request body
101 Switching Protocols The requester has asked the server to switch protocols
103 Checkpoint Used in the resumable requests proposal to resume aborted PUT or POST requests

2xx: Successful

Message: Description:
200 OK The request is OK (this is the standard response for successful HTTP requests)
201 Created The request has been fulfilled, and a new resource is created
202 Accepted The request has been accepted for processing, but the processing has not been completed
203 Non-Authoritative Information The request has been successfully processed, but is returning information that may be from another source
204 No Content The request has been successfully processed, but is not returning any content
205 Reset Content The request has been successfully processed, but is not returning any content, and requires that the requester reset the document view
206 Partial Content The server is delivering only part of the resource due to a range header sent by the client

3xx: Redirection

Message: Description:
300 Multiple Choices A link list. The user can select a link and go to that location. Maximum five addresses
301 Moved Permanently The requested page has moved to a new URL
302 Found The requested page has moved temporarily to a new URL
303 See Other The requested page can be found under a different URL
304 Not Modified Indicates the requested page has not been modified since last requested
306 Switch Proxy No longer used
307 Temporary Redirect The requested page has moved temporarily to a new URL
308 Resume Incomplete Used in the resumable requests proposal to resume aborted PUT or POST requests

4xx: Client Error

Message: Description:
400 Bad Request The request cannot be fulfilled due to bad syntax
401 Unauthorized The request was a legal request, but the server is refusing to respond to it. For use when authentication is possible but has failed or not yet been provided
402 Payment Required Reserved for future use
403 Forbidden The request was a legal request, but the server is refusing to respond to it
404 Not Found The requested page could not be found but may be available again in the future
405 Method Not Allowed A request was made of a page using a request method not supported by that page
406 Not Acceptable The server can only generate a response that is not accepted by the client
407 Proxy Authentication Required The client must first authenticate itself with the proxy
408 Request Timeout The server timed out waiting for the request
409 Conflict The request could not be completed because of a conflict in the request
410 Gone The requested page is no longer available
411 Length Required The "Content-Length" is not defined. The server will not accept the request without it
412 Precondition Failed The precondition given in the request evaluated to false by the server
413 Request Entity Too Large The server will not accept the request, because the request entity is too large
414 Request-URI Too Long The server will not accept the request, because the URL is too long. Occurs when you convert a POST request to a GET request with a long query information
415 Unsupported Media Type The server will not accept the request, because the media type is not supported
416 Requested Range Not Satisfiable The client has asked for a portion of the file, but the server cannot supply that portion
417 Expectation Failed The server cannot meet the requirements of the Expect request-header field

5xx: Server Error

Message: Description:
500 Internal Server Error A generic error message, given when no more specific message is suitable
501 Not Implemented The server either does not recognize the request method, or it lacks the ability to fulfill the request
502 Bad Gateway The server was acting as a gateway or proxy and received an invalid response from the upstream server
503 Service Unavailable The server is currently unavailable (overloaded or down)
504 Gateway Timeout The server was acting as a gateway or proxy and did not receive a timely response from the upstream server
505 HTTP Version Not Supported The server does not support the HTTP protocol version used in the request
511 Network Authentication Required The client needs to authenticate to gain network access

Hope you learn something from this post...


Keep Automating........

Running Tests with Apache Ant

Hello friends,

Today we will see, how we can run our unit tests with Apache Ant.

before that.... Why we need this?

It's Very bulky to run your test from various Java class within various packages through IDE (Eclipse, Intellij-Idea), specially when it is daily activity. Its also become very important when you want to integrate your tests in CI process (Continuous Integration). it means your test will get trigged after each build.

Here Ant helps us to run the test in a single click or one command

ANT is software build automating tool for Java code. It uses XML file named build.xml as the input, and run accordingly.

We can configure different Unit test framework like J-UNIT & Test-NG in Apache Ant

Lets get started step by step

  1. The very first step is to Download and install Apache Ant. You can download latest Apache Ant form here

    Its very simple to install, just uncompress it on hard drive and add the System Variable as "ANT_HOME" to the directory you uncompressed Ant. also add %ANT_HOME%/bin to your PATH variable.

    Please check this to learn how to set System variable

  2. As I mentioned build.xml file is input for Ant, Lets see how we can create this file

    Very basic duild.xml file template is as below. We will start with this

    <?xml version="1.0"?>
      <project name="Services Automation" default="test">
        <target name="test">
            <echo>Hello Ant</echo>
        </target>
    </project>
    

    Create new build.xml file at root level of your test project. below is my project structure

    There are two source folders in my Project(src, testsrc), you may have different project structure

  3. build.xml has project tag on root level which consist of target nodes, these are one or many as per requirement. each target has unique name attribute, in our case it is "test".

    Project tag has default attribute having value from any of the target name attribute. by this we can set the default target to execute

    Lets get in to detail.. Which steps we need to take for executing unit test?

    1. Create the folder structure we needed
    2. Compile the Java code which we have written for build the tests
    3. Create jar file from compiled code, which will used for executing tests
    4. Run the desired test
    5. Create the test Report

    Lets Implement all above steps in build.xml file

  4. First Step is to create/Initialize the folder structure, we need to add target named init in project and create required folders, please look below target

    <target name="clean" >
     <mkdir dir="out"/>
     <mkdir dir="reports"/>
     <mkdir dir="out"/>
     <mkdir dir="build"/>
     <delete verbose="true">
      <fileset dir="out" includes="**/*.class" />
      <fileset dir="build" includes="**/*.*" />
      <fileset dir="reports" includes="**/*.*" />
     </delete>
    </target>
    

    Here mkdir used for creating the directory at relative path & delete used for deleting the existing files

  5. Now our next target will be, Compile the code.

    to compile the code, all dependency jars should available in lib folder, and used as reference for compile

    in ant we use javac tag to compile the source to make binary class files. We use path tag to store dependency class-paths

    Please have a look in below target of javac

    <path id="classpath.test">
     <pathelement location="lib/junit-4.11.jar" />
     <pathelement location="lib/hamcrest-core-1.3.jar" />
     <pathelement location="src" />
    </path>
    <target name="compile" depends="clean">
     <javac srcdir="src" destdir="out" verbose="true">
      <classpath refid="classpath.test"/>
     </javac>
     <jar destfile="build/myJar.jar" basedir="out">
     </jar>
    </target>
    

    We use jar tag to make the jar from compiled binaries.

  6. Now we have jar file ready in build folder & we are all set to run the tests, we use junit tag to run the test please have a look in to below bit of xml

    <path id="junitTest">
     <pathelement location="build/myJar.jar"/>
     <pathelement location="lib/junit-4.11.jar" />
     <pathelement location="lib/hamcrest-core-1.3.jar" />
    </path>
    <target name="test" depends="compile">
     <junit showoutput="true">
      <classpath refid="junitTest" />
      <formatter type="xml" usefile="true"/>
      <batchtest todir="reports">
       <fileset dir="source">
        <include name="**/*Test*" />
       </fileset>
      </batchtest>
     </junit>
    </target>
    
  7. We are done with test execution target. and time is to build reports. in above junit target we have already stored our raw xml out put in reports folder through formatter.

    to generate HTML report we use junitreport tag with inputs. please look into below xml snippet

    <target name="report" depends="test">
     <mkdir dir="reports/html" />
     <junitreport todir="reports">
      <fileset dir="reports">
       <include name="TEST-*.xml" />
      </fileset>
      <report todir="reports/html" />
     </junitreport>
    </target>
    
  8. Finally we done with all target and ready to run the test through command prompt or integrate the test to CI environment. before that just look at whole build.xml file

<?xml version="1.0"?>
<project name="Services Automation" default="test">

 <target name="clean" >
  <mkdir dir="out"/>
  <mkdir dir="reports"/>
  <mkdir dir="out"/>
  <mkdir dir="build"/>
  <delete verbose="true">
   <fileset dir="out" includes="**/*.class" />
   <fileset dir="build" includes="**/*.*" />
   <fileset dir="reports" includes="**/*.*" />
  </delete>
 </target>


 <path id="classpath.test">
  <pathelement location="lib/junit-4.11.jar" />
  <pathelement location="lib/hamcrest-core-1.3.jar" />
  <pathelement location="src" />
 </path>
 <target name="compile" depends="clean">
  <javac srcdir="src" destdir="out" verbose="true">
   <classpath refid="classpath.test"/>
  </javac>
  <jar destfile="build/myJar.jar" basedir="out">
  </jar>
 </target>

 <path id="junitTest">
  <pathelement location="build/myJar.jar"/>
  <pathelement location="lib/junit-4.11.jar" />
  <pathelement location="lib/hamcrest-core-1.3.jar" />
 </path>
 <target name="test" depends="compile">
  <junit showoutput="true">
   <classpath refid="junitTest" />
   <formatter type="xml" usefile="true"/>
   <batchtest todir="reports">
    <fileset dir="source">
     <include name="**/*Test*" />
    </fileset>
   </batchtest>
  </junit>
 </target>

 <target name="report" depends="test">
  <mkdir dir="reports/html" />
  <junitreport todir="reports">
   <fileset dir="reports">
    <include name="TEST-*.xml" />
   </fileset>
   <report todir="reports/html" />
  </junitreport>
 </target>

</project>

Here we Go...............
To run the test... open command prompt to the root folder of your project where build.xml is saved and just type command ant and you are done.......

Note above build.xml file is written as per shown project structure. it may vary as if on different project and structures.


Keep Automating.............