Monday 29 September 2014

Creating Log file Using Log4j in WebDriver Framework

Tired of sysouts in your scripts !! Well, it makes your Test Scripts execution hell slow.
But you don't even want to omit sysouts from your classes.

Here, log4j (Apache Logging Services) provides you logging library for Java.

Steps to create a Logging Utility in your existing framework :

Step 1 :

Install log4j jar from here and put in lib folder of your project.

Step 2 :

Create a "log4j.properties" file in your config folder.

And write the following code in it :


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

# 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/LogFile.log
log4j.appender.R.MaxFileSize=1000KB

# 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


For all the detailed configuration explanation of log 4j, refer this.

Here,

log4j.appender.R.File=../logs/LogFile.log
log4j.appender.R.MaxFileSize=1000KB

is the location where log file would be created and the maximum size of that log file.

Step 3 :

Now in your test script class, and call the getLogger of Logger class that log4j jar provides.
Here is the sample code :

public class OpenGoogle
 { 

  private static Logger logger=Logger.getLogger("OpenGoogle.class"); // write this line 

  public void testOpenGoogle() throws InterruptedException{

   driver.get("https://www.google.co.in/");
   assertTrue(driver.getTitle().contains("Google"));
   logger.info("You have opened Google.com"); // use info for printing in log file

  }

Create the logger class object and call the logger which writes in the log file.

Now, replace all the "sysout" statements in your script with "logger.info" or any other log 4j configuration according to your requirement.

Doing this, all your sysouts which used to slow down the test execution will reduce and also you will be able to see the full log file once you complete your execution.

And you are done with adding Logging Services in your framework !

Happy Logging !

Customized Explicit Waits in WebDriver

When is the need for Customized Explicit Waits ?

There are situations at times when we need to explicitly write a custom condition which are not present in ExpectedCondition class of WebDriverWait class.

Example of a Customized Explicit Wait Condition:

Lets take an example where we need to wait for a URL to change,

So we will do Anonymous class Instantiation of Expected Condition. In these types, wait is applied on Boolean Condition. Here we have our own Boolean Condition on which wait needs to be applied.

Here is the code for it:


//customized Explicit Wait Condition
  ExpectedCondition e = new ExpectedCondition<Boolean>() {
           public Boolean apply(WebDriver d) {
            String previousURL = driver.getCurrentUrl();
            logger.info("Waiting...");
             return (d.getCurrentUrl() != previousURL);
           }
         };

In this example,
it will wait for sometime and then again check until a URL change is there.

So, this is how customized explicit waits works.

Say Hello to 'Agile Testing'

Agile and Software testing go hand in hand

Agile has revolutionized the IT world. Agile is not only a process but a methodology. It's about understanding the human behavior and changing the mindset as per agile principles and values.

Scrum is the most common methodology which is being followed in majorly all the organizations now a days. Scrum is a time-boxed process which motivates the team members to complete the stories in that time frame and increases the productivity of the Agile Teams.

The key values of Agile Testing are :

"The whole Team concept i.e. the whole Team is responsible for the Quality Work (including Developers and Testers)"

 Agile Testing involves following :


  • Get the insights of the Business Requirement in Planning meeting while start of the Sprint together with the whole Team.
  • testing will be an on - going process throughout the Sprint as soon as developers gives a working code.
  • Acceptance Criteria will be added in the story after the Planning only.
  • The developers have the responsibility to unit test their code and after Unit Test only it should be ready for Testing.
  • Testing should involve Manual as well as Automated Test Cases.

Agile testing involves open communication with the developers, business analysts and other stake holders. 


Be more communicative and open to new ideas.

Happy Agile Testing !!


Sunday 28 September 2014

Difference between Implicit Waits and Explicit Waits

Implicit Waits :

Set implicit wait once and it apply for whole life of WebDriver object.
eg.

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



Explicit Waits : 

- Custom code for a particular element to wait for particular time of period before executing next steps in your test.
-  Webdriver provide “WebDriverWait”, “ExpectedCondition” classes to implement this.

eg.
//explicit wait for search field
    WebDriverWait wait = new WebDriverWait(driver, 10);
    wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("search")));

This is the basic difference between Explicit and Implicit Waits with an example.

Explicit Waits are good to use as it waits for a particular web page element on which you can apply wait.

Sending e-mail notification using TestNG , ANT and WebDriver

Sending e-mail notifications for daily report of our Test Suite Execution has become an important business requirements in majorly all the on-going projects.

Email notification can be send easily without any typical Java code but via TestNG and WebDriver only.

We will send the notification using one of the features of TestNG and the code for that is :


<!-- @ Purpose: This function is for sending an auto email after sanity & regression
   run is complete. -->

<target name="send-email">
<mail
    tolist="abc@xyz.com"
    cclist="pqr@tuv.com"
    from="efg@hij.com" subject="Sanity & Regression Suite Automation Report"
    mailhost="smtp.gmail.com" mailport="465" ssl="true"
    user="efg@hij.com" password="*****">
   
    <message>Hi,

 PFA the HTML Report of Automation Sanity & Regression Suite Execution.

 Environment : ${baseURL}

 Regards,
 Automation Team

 *** This is an automatically generated email, please do not reply to this email id. ***
    </message>
<attachments>
 <fileset dir="${outputDir}">
      <include name="index.html" />
      <include name="emailable-report.html" />
 </fileset>
</attachments>
</mail>

<tstamp>
   <format property="send.time" pattern="MM/dd/yyyy hh:mm aa" unit="hour" />
</tstamp>

<echo message="Mail successfully sent at ${send.time}" />
</target>


Create a new target for sending e-mail in your build.xml and call that target name to send notification.

Also you need Java Mail API Jar. Download it from here and Activation Jar from here. Put these jars in the lib folder of ANT.

The Email send notification is configured using TestNG, ANT and WebDriver.

Happy E-mailing..!

Handling Multiple PopUp Browser Windows in WebDriver

There are situations when clicking on a link/button in a web page (from parent window) opens a new browser (called child window).
And the user wants to perform some operation on child window and gets back to parent window.

In the below example, we are clicking on FB share button which opens a new browser and after it opens we are verifying and coming back to parent window

Here is the code for that :


String parentWindowHandle = driver.getWindowHandle(); // save the current window handle.

  // FB Share Verification
  driver.findElement(fbShare).click();

  for(String winHandle :driver.getWindowHandles()){
   driver.switchTo().window(winHandle);
   if(driver.getTitle().equals("Facebook")){
    logger.info("Title of the new popUp window: " + driver.getTitle());
    logger.info("You are in FaceBook window");
    break;
   } else{
    logger.info("Title of the page after - switchingTo: " + driver.getTitle());
   }
  }
  driver.close();
  driver.switchTo().window(parentWindowHandle);  // switch back to parent window
}

Here,

- getWindowHandle() is a method in WebDriver class is used to get the target locator of the window or frame.

- getWindowHandles() is again a method in WebDriver class which helps in switching to a different window.

driver.switchTo().window(parentWindowHandle) is used to switch to a specific window handle.

Just embed this code snippet wherever switching to a different window condition comes to you and you can easily switch back.

Taking Screen Shots in WebDriver

Taking ScreenShots in WebDriver becomes quite easy by using one of its class known as "TakesScreenshot".

A small code snippet in your framework adds this functionality of taking screenshots using WebDriver:


public takesSnapshot (String suffix){
File scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
// Storing the screenshot in the testsuite-output folder
try {
FileUtils.copyFile(scrFile, new File("..\\testsuite-output\\VedioScreenshot_"+suffix+".png"));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return this;
}


Add the above method of taking ScreenShot in @AfterSuite and now your tests are well accustomed to take screenshots after each test case finishes.


Re-Run the failed Test Scripts in WebDriver using TestNG

Re-running the failed Test Cases in WebDriver has become  a Business Requirement now a days.
Because some times a test case fails at first due to network latency, or any other reason.

So, if we want to re-run the failed test cases automatically we need to write some Java code as follows:



public class RerunFailedTestScripts implements IRetryAnalyzer{

 private int count = 0;
   private int maxCount = 1; // Currently Failed Test Cases will run 1 time after failure

   @Override
   public boolean retry(ITestResult result) {
     if (!result.isSuccess()) {
       if (count < maxCount) {
         count++;
         result.setStatus(ITestResult.SUCCESS);
         String message = Thread.currentThread().getName() + ": Error in Method Name: " + result.getName() + " ."+" Hence, Retrying "
             + (maxCount + 1 - count) + " more time";
         System.out.println(message);
         Reporter.log(message);
         return true;
       } else {
         result.setStatus(ITestResult.FAILURE);
       }
     }
     return false;
   }
}


Here, we are using IRetryAnalyzer , Interface of TestNG to implement to be able to have a chance to retry a failed test. Also, you can configure in 'maxCount' that how many times to run the failed Test Cases.

Then, to re-run the test cases which you want to write the following in the Test Script class :


  @Test(groups={"sanity"},alwaysRun=true,priority = 1, retryAnalyzer=RerunFailedTestScripts.class)
 public class OpenGoogle
 {
  public void testOpenGoogle() throws InterruptedException{
   driver.get("https://www.google.co.in/");
   assertTrue(driver.getTitle().contains("Google"));

  }


Here, we are calling the above class that we made in @Test Annotation in the Test Script Class.

And You are done with the Re-Run Failed Test Cases Framework.

Handling Windows Browser Authentication PopUps using AutoIt Tool

Handling Browsers Authenttication PopUp can be easily done by one of the open sources available known as "AutoIt"

You can download AutoIt from here. AutoIt has a basic and simple Scripting language and can automate the windows desktop features.

Here we will talk about how to automatically handle the windows browser authentication popups as follows :


To handle this, we need to send the username and password in the popup and click Ok button.

Step 1:
So, to do this, we need to create a small '.au3' file which has the AutoIt Scripting Program in it as follows:


While 1
WinWait("Authentication Required")
If WinExists("Authentication Required") Then
 WinWaitActive("Authentication Required","",20)
 Send("username")
 Send("{TAB}")
 Send("password")
 Send("{ENTER}")
EndIf
Wend


Step 2:
Save the file above, right click on it click on the option "Compile Script(x86)". This will compile the script and create a ".exe" of the ".au3" file that you made.

This convert your AutoIt script to an executable.

Step 3:
Now to use it with WebDriver. Following is the Java Code :


/**
 * Code for Handling Windows Authentication PopUps
 */
 public static void authenticationHandler(){

  String execFilePath = null;

  // Handled only in case of Windows
  if(Platform.WINDOWS.is(currentOS)) {
   execFilePath = "../resources/drivers/autoItDriver/autoItExecutable/AuthenticationHandler.exe";
  }
  try {
   logger.info("AutoIt executable Path"+execFilePath);
   if(execFilePath != null) {
    authenticationProcess = Runtime.getRuntime().exec(execFilePath);
    logger.info("Windows Browser Authentication PopUp Handled");
   }
  } catch (Exception e) {
   e.printStackTrace();
   throw new RuntimeException("Authentication Failed");
  }

 }

Also , in @AfterSuite you can write the following code to destroy the .exe :

private static Process authenticationProcess;
 @AfterSuite(alwaysRun=true)
 public void quitWebDriver()
 {
  logger.info("Inside After Suite");

  if(authenticationProcess != null) {
   authenticationProcess.destroy();
  }
  driver.quit();
 }


That's it !

You are done with handling windows Authentication Browser PopUps.

Note: This only works on Windows Machine, For Linux & IOS there are other tools available in the market.

How to Create Relative Xpaths of a Web Page Element ?

To start with the basic coding of WebDriver, one needs to know how to write Xpaths of a web element in a web page.

Xpath of an element is used to access a particular web element in a web page and perform various operations on that web element.

Absolute Xpath starts with root path (/). Thus, its very slow.
eg.
/html/body/div[3]/div[2]/div[2]/div[2]/div[2]/div[2]/div[2]/div/div[4]/div[1]/div/div[@id='main']/div[@id='Blog1']/div[1]/div[1]/div/div[1]/div/h3/a


Relative Xpath starts with current path (//). Thus, its quite faster than the above one.
eg.
//h3/a[text()='Working on New Window']

An easy way to find,

How to Create a Relative Xpath?


1. Open a web Page (lets say Facebook.com) in Firefox/Chrome Browser.
2. Press F12 and click on the console.
3. Type: $x("<xpath>") in the console.
4. You will get the result there itself as soon as you hit enter after writing the xpath. And thus, now you are sure that your xpath will never fail in your webdriver code.

Tip :  If you have an ID available then its best way to access the element since its very fast. Else for other you can use many locator strategies out of which here we will talk about creating Relative Xpaths.

Lets , take an example of Facebook website:



The above snapshot depicts 4 kind of Xpaths which we use majorly while accessing the web page elements.
Hence, writing xpaths directly in the console of a web browser helps you in getting the result as the web element and you can directly use that xpath in the code making sure it will never fail.

Explanation of each xpaths in the picture is as follows :

1) Using a class : You can use contains in case there are more than one classes used in a HTML tag. Give a logical class name in contains.

2) Usind ID : If the ID of an element is present in the HTML then no need to write xpath of that element. You can directly use By.id("email") in the code. But in console you can use it to see the output as shown.

3) Using child : If you want to get inside a child node then use "/" to access it. Refer the pic above.

4) Using following-sibling : If you want to access the sibling node of a parent node  then use this as shown in the pic.

There are also various other keywords available to access the web page elements.

One of the Xpath Cheatsheet that I personally found descriptive and useful is : Xpath CheatSheet

Hope this is a useful blog to start with creating relative Xpaths.

Happy Xpathing :)