Thursday 28 August 2014

Magic with JExcel

            Most of the automation Frameworks deal with generating reports for various situations. Usually such documents should be designed for reviewing by people who are not closely familiar with different technologies and prefer to obtain reports in a usual format. For Microsoft Windows users, the most common office solution is Microsoft Office, and when talking about electronic worksheets, it is undoubtedly Microsoft Excel.

           The JExcel library allows Java programmers for Windows to easily create, modify or display Microsoft Excel files. Using this library, you can work with workbook files, print a workbook, worksheet or even a specific range of cells, and modify cell values, cell number formats, etc. Also, there is an ability to customize cell appearance, including text font, cell background and border, text alignment and orientation, etc.

           JExcel can be used for solving different tasks from simple display of a workbook in a standalone Excel application to handling Excel events and embedding a workbook into Java Swing applications. The use of the library is very simple and doesn't require from a Java programmer specific knowledge of Microsoft Office programming.

           Many of us knows that JExcel can be used to read and write the excel sheets. But, in this post we will explore various options available for customizing cells in Excel Sheets.

1. Changing a Number Format:
            The range number format reflects the way of displaying numeric data. For instance, a double value can be represented as an integer or as a date. A number format  in Excel is set by a string pattern in a specific locale-dependent format. For detailed specification of the number format, please refer to appropriate articles  on Excel.
         //Getting a range number format
         Range range = worksheet.getRange("A1:A3");
         String numberFormat = range.getNumberFormat();

         System.out.println("A1:A3 number format is " + numberFormat);
  The Range.setNumberFormat(String) method changes the number format of a range:
         
//Setting a custom number format
         String newNumberFormat = "0,00%";
         range.setNumberFormat(newNumberFormat);
         System.out.println("A1:A3 new number format is " + range.getNumberFormat());

2. Changing Text Alignment:            
               JExcel provides the TextAlignment class, which is an enumeration of all alignment types supported by Excel. The Range (Cell) class enables you to obtain and modify both horizontal and vertical text alignment.

             The Range.getHorizontalAlignment() method returns the current horizontal text alignment as an instance of the TextAlignment class. The possible values are TextAlignment.CENTER,TextAlignment.DISTRIBUTED, TextAlignment.FILL,TextAlignment.GENERAL,TextAlignment.JUSTIFY, TextAlignment.LEFT and TextAlignment.RIGHT. If the range cells have mixed horizontal alignment, the return value is null. To change horizontal alignment of a range, call the Range.setHorizontalAlignment() method:
       //Setting custom horizontal text alignment
        range.setHorizontalAlignment(TextAlignment.RIGHT);
        //Checking horizontal text alignment
        if (range.getHorizontalAlignment().equals(TextAlignment.RIGHT))
        {
            System.out.println("A1:A3 range: new horizontal text alignment was applied successfully.");
        }
        else
        {
            System.out.println("Horizontal text alignment failed to be applied.");
        }

3. Changing the Font Size:              
                 The Font class from the com.jniwrapper.win32.jexcel package provides the ability to customize fonts in Excel.
 The following font attributes can be obtained or modified:
 
Font name  
       Call the Font.getName() method to get the font name, and the Font.setName(String) method to specify the font name.
   
Font size
     Call the Font.getSize() method to get the font size, and the Font.setSize() method to specify the font size.
 
General font styles
    The Font class allows you to specify whether the font is bold, italic or strike-through.
 
Font underline style
    The Font.UnderlineStyle class is an enumeration of five underline styles supported by Excel: UnderlineStyle.NONE, UnderlineStyle.SINGLE, 
UnderlineStyle.SINGLEACCOUNTING,UnderlineStyle.DOUBLE,and UnderlineStyle.DOUBLEACCOUNTING.The Font.getUnderlineStyle() method returns the current   underline style as an instance of the Font.UnderlineStyle class. The return value can be one of the predefined values listed above. To change an   underline style, call the Font.setUnderlineStyle() method.
 
Font color
    Call the Font.getColor() method to get the currently set font color, and the Font.setColor() method to specify the font color. A color value in both   functions is an instance of the java.awt.Color class.
 
Font alignment style
    The Font class allows you to specify whether the text is normally aligned, subscript or superscript using the Font.setAlignment() method. This method 
takes one of the three predefined instances of the Font.Alignment class: Alingment.NORMAL, Alignment.SUBSCRIPT or Alignment.SUPERSCRIPT. To obtain the   current font alignment, call the Font.getAlignment() method.

 The following sample demonstrates the technique of changing text font:
       
   //Creating a new instance of the  om.jniwrapper.win32.jexcel.Font class
        Font font = new Font();
        //Changing font name
        font.setName("Courier New");
        //Changing font styles
        font.setBold(true);
        font.setStrikethrough(true);
        font.setUnderlineStyle(Font.UnderlineStyle.DOUBLE);
        //Changing font color
        font.setColor(Color.ORANGE);
        //Applying new font setting
        range.setFont(font);


4. Customizing cell borders:
            To customize a range or cell border, you need to specify the kind of border to work with. There are several standard kinds of borders which are provided in  JExcel as instances of the Border.Kind class. For example, Border.Kind.EDGELEFT or Border.Kind.EDGETOP.
 
         The Range.getBorder() method allows you to obtain an instance of the Border class that corresponds to some border kind. The Border class resides in the  com.jniwrapper.win32.jexcel package.

       The Border class provides functionality for working with border color, line style and line weight. The line style is set using the constants from the  Border.LineStyle class, such as LineStyle.CONTINUOUS, LineStyle.DASHDOT, etc. The line weight is set using the constants from the Border.LineWeight class:  LineWeight.HAIRLINE, LineWeight.MEDIUM, etc.

The following sample demonstrates the technique of customizing the range border:
         
//Getting the top border
         Border topBorder = range.getBorder(Border.Kind.EDGETOP);
         //Getting the border style
         java.awt.Color borderColor = topBorder.getColor();
         Border.LineStyle lineStyle = topBorder.getLineStyle();
         Border.LineWeight lineWeight = topBorder.getWeight();
         //Setting new border style
         Border border = new Border();
         border.setColor(Color.CYAN);
         border.setLineStyle(Border.LineStyle.DASHDOT);
         border.setWeight(Border.LineWeight.MEDIUM);
         //Applying the border settings to the top border
         range.setBorder(Border.Kind.EDGETOP, border);

Below is the consolidated example to coustomize the cells:

  public static void updateExcel(String strFilePath, ArrayList arrValues) throws IOException, BiffException, WriteException {
   try {
    jxl.Workbook workbook = jxl.Workbook.getWorkbook(new File(strFilePath));
    WritableWorkbook writableWorkbook = jxl.Workbook.createWorkbook(new File(strFilePath), workbook);
    WritableSheet writableSheet = writableWorkbook.getSheet(strGlobalSheetName);
    WritableCellFormat cfwithColor = new WritableCellFormat(getCellFormat(Colour.RED, Pattern.SOLID,Border.ALL,BorderLineStyle.THIN));
    WritableCellFormat cfwithoutColor = new WritableCellFormat(getCellFormat(Colour.RED, Pattern.NONE,Border.ALL,BorderLineStyle.THIN));
    // Creates Label and writes data to one cell of sheet
    Label label;
    CellView cellView;
    intOutputRowCntr = intOutputRowCntr + 1;
    for (int intColHdrCntr = 0; intColHdrCntr < arrValues.size(); intColHdrCntr++) {
     if(arrValues.get(intColHdrCntr).toString().contains("~")){
      String strTemp=arrValues.get(intColHdrCntr).toString();
      strTemp=strTemp.substring(0, strTemp.length()-1);
      label = new Label(intColHdrCntr, intOutputRowCntr, strTemp, cfwithColor);
     }
     else
      label = new Label(intColHdrCntr, intOutputRowCntr, arrValues.get(intColHdrCntr).toString(), cfwithoutColor);
     writableSheet.addCell(label);
     cellView = writableSheet.getColumnView(intColHdrCntr);
     cellView.setSize(arrValues.get(intColHdrCntr).toString().length()*256+100);
     writableSheet.setColumnView(intColHdrCntr, cellView);
    }
    writableWorkbook.write();
    writableWorkbook.close();
    workbook.close();
   } catch (Exception e) {
    //gulp the exception
   }
  }
private static WritableCellFormat getCellFormat(Colour colour, Pattern pattern,Border border, BorderLineStyle borderLineStyle) throws WriteException {
                         WritableFont cellFont = new WritableFont(WritableFont.ARIAL, 9, WritableFont.NO_BOLD);
                         WritableCellFormat cellFormat = new WritableCellFormat(cellFont);
                         cellFormat.setBackground(colour, pattern);
                         cellFormat.setBorder(border, borderLineStyle);
                         return cellFormat;
  }


Below is the example display with the above code

 

 

Sunday 17 August 2014

Sikuli integration with Selenium

Sikuli – An introduction
SikuliX automates anything you see on the screen of your desktop computer running on Windows/ Mac/Unix. It uses images patterns to identify and control GUI components.

This is useful when we try to automate a page developed using Flex, Adobe or Flash where the html DOM Structure is not defined easily.
That is why it is called as WYSIWYC – “what you see is what you script”

After reading the above introduction, my first impression as a selenium automation engg was “ May be sikuli is something very complex to learn and use in our day to day automation. Unless we spend some good amount of time in it, we can’t think of using Sikuli”
If your thoughts are similar to these, then you are the one to who is supposed to read this..

Let me give you quick step by step start on using sikuli with selenium.
First let us look at the initial installation and set-up procedures.

 1.       Download and Install Sikuli
·         Download sikuli from the following location.
§  Follow the steps provided in the link for installation guide. 

·         Once sikuli is installed successfully, one can see the changes in the following environment variables.

·         PATH and SIKULI_HOME 

·         The variable PATH would be appended with “ ~/Sikuli X/Sikuli-IDE/libs”

·         The new Variable SIKULI_HOME is assigned with the value  “~/Sikuli X/Sikuli-IDE”

       This indicates the successful installation of sikuli in the system.

2.       Sikuli Integration with selenium

·         Create a normal java project in eclipse as shown below. Let us name it as SikuliSample.

 

·         Next step is to add the required jars in the build path. To do this, select “ConfigureBuildPath” option as shown below


 

·         Add the selenium jars to the build path.

·         Add “Sikuli-script.jar” which is available in ~/Sikuli X/Sikuli-IDE/libs folder.

·         Add “external class folder” in build path and select the “Sikuli-IDE” folder located at ~/Sikuli X/

The final project created in eclipse would like this as shown here.

With this sikuli selenium integration is done seamlessly. You will now be able to start working on it.
Now that installation and set-up is done… Our next step is to create a sample application.

Problem statement: Verify the Google Logo in google.com webpage.
Prerequisite – sample google logo image file. Let’s assume we have this file located at

C:\Temp\google_logo.jpg
Create a new Class called Sample in the project (SikuliSample) we created above.

Add the following code to this class
public static void main(String[] args){
WebDriver driver = new FirefoxDriver();
driver.get(http://www.google.com);
Pattern image = new Pattern("C:\\Temp\\google_logo.jpg");
Screen s = new Screen();
Match m = s.exists(image);
if(m != null){
       s.click(image);
}else{
  System.out.println("Image not found”);
}
}

In this program, we are trying to verify for the presence of google logo in the Google page and click on the logo if present.

In line #1, which is a normal Selenium webdriver code, initializes a firefox driver.

In line #2, driver opens firefox browser to load the google web page.

In line #3, a Pattern object is created for the image with which we want to compare and verify the webpage.

In line #4, a new Screen object is created. This denotes the screen which is being displayed in the monitor of the system.

In line #5, verify if the image pattern is present in the current screen.

If a Match is present, then go ahead and click on the image.

Otherwise, throw a message on the console screen saying “Image nor found”.
 
Run this program and execute it….

Yes you are done..!!!!

Introduction to Behavior Driven Development

 Behavior Driven Development
Behavior Driven Development is an Agile software development technique focused on improving a key factor in the successful development of any software product: Communication. It is a technique devised by Dan North as a response to the issues he encountered whilst teaching Test Driven Development. Eric Evans describes it this way in his book Domain Driven Design: “A project faces serious problems when its language is fractured. Domain experts use their jargon while technical team members have their own language tuned for discussing the domain in terms of design… Across this linguistic divide, the domain experts vaguely describe what they want. Developers, struggling to understand a domain new to them, vaguely understand.”
He goes on to describe the concept of modeling a system using a ubiquitous language based on the business domain, so that the business vocabulary permeates right into the codebase. BDD seeks collaboration amongst the delivery team and business participants in a software project. On the “Agile specifications, BDD and Testing eXchange” in November 2009 in London, Dan North gave the following definition of BDD: “BDD is a second-generation, outside–in, pull-based, multiple-stakeholder, multiple-scale, high-automation, agile methodology. It describes a cycle of interactions with well-defined outputs, resulting in the delivery of working, tested software that matters.”
It is a framework based on three Core Principles:
1. It’s All Behavior: Business and Technology should refer to the same system in the same way
2. Whereas The Business Value: Any system should have an identified, verifiable value to the business
3. Enough Is Enough: Up-front analysis; design and planning all have a diminishing return
Behavior Driven Development centers on obtaining a clear understanding of desired software behavior through discussion with stakeholders. From this initial discussion between the stakeholder or users and the business analyst comes a list of features of the system to be developed, features also known as “User Stories” in our Agile environment. They describe the behavior from the perspective of those interested in the product.
The format is:
As a [X], I want [Y], so that [Z]
Where X is the person (or role) who will benefit , Y is some feature , and Z is the benefit or value of the feature. Its strength is that it forces you to identify the value of delivering a story when you first define it. This can make it easier to descope some of the more esoteric requirements.
The next step is writing test cases in a natural language that non-programmers can read, specifying scenarios of system behavior. A scenario describes the feature acceptance criteria. We call scenarios “acceptance tests;” they express what the software needs to do in order for the stakeholder to find it acceptable. So, everyone on the team, including stakeholders, writes these tests collaboratively, because they not only decide the system behavior, but they learn how to describe that behavior in a common language that everyone understands. If the system fulfills all the acceptance criteria, it’s behaving correctly; if it doesn’t, it isn’t. So a template can be created to capture a story’s acceptance criteria.
The template had to be loose enough that it wouldn’t feel artificial or constraining to analysts but structured enough that we could break the story into its constituent fragments and automate them.
The next step is to automate these scenarios as examples, taking the following form:
Given – some initial context (the givens)
When an event occurs,
Then ensure some outcomes.
Acceptance tests written in this style become more than just tests: they are executable specifications and living documentation. When the software system is continuously validated against a set of executable specifications, the team ensures that the system will do what the specifications say. Or, to put it differently, the specifications will continue to describe what the system does.
They have the following benefits:
  • Living documentation replaces all the artifacts that teams need for delivering the right product.
  • We can continue defining specifications as the system grows up, in an incremental way.
  • They are cheap to write.
To illustrate, a classic ATM can be used as an example:
Title: Customer wants to withdraw cash.
As a customer, I want to withdraw cash from an ATM so that I don’t have to wait in line at the bank
There are many scenarios that we can consider: the account may be in credit, the account may be overdrawn but within the overdraft limit, the account may be overdrawn beyond the overdraft limit. Of course, there will be other scenarios, but let’s use the given-when-then template for an example.
Scenario 1: Account is in credit
Given the account is in credit
And the card is valid
And the dispenser contains cash
When the customer requests cash
Then ensure the account is debited
And ensure cash is dispensed
And ensure card is returned
Scenario 2: Account is overdrawn past the overdraft limit
Given the account is overdrawn
And the card is valid
When the customer requests cash
Then ensure a rejection message is displayed
And ensure cash is not dispensed
And ensure the card is returned
Both scenarios are based on the same event and even have some givens and outcomes in common. We want to capitalize on this by reusing givens, events, and outcomes.
Tools Used:
There are many tools available to in the market to implement the procedure. Following are tools which we use for BDD.
1. JBehave
2. Cucumber
3. SpecFlow
4. Watin
More Details about Tools are on the way. Keep look in the same space for more details. :-)

Enrich Your ReportNG Report with Screenshots and more…

          In the projects where we have a vast number of regression tests it became obvious to our QA team that a good reporting tool for reporting the execution results was of great essence. In the search, a simple HTML plugin for TestNG, called as “ReportNG” was the obvious way to go just because of its simplicity and easiness in integration with TestNG which is our testing framework. ReportNG provided us with a html report presenting each @Test with a pass / fail state. Although many projects are already using this option, here I am going to discuss about enrichment of your ReportNG Reports with some advanced features.

In this journey, we will first discuss about adding screenshot to the ReportNG Report.

Although ReportNG presented an excellent solution to our reporting problems it became apparent that for debugging purposes as well as for defect evidence purposes an extension to include screenshots was needed. These screenshots should be attached to every @Test annotation which fails along with the assertion failure.

Adding Screenshot is a three step procedure:

1. Disable the Default TestNG Listeners:
     For disabling the TestNG Listeners Go to Project –> Right click on the project in which we need to add ReportNG with screenshot. Select “Properties” from the menu displayed. In the displayed window, search for “TestNG” option on the left side tree menu. Up on clicking on the “TestNG” option, you will see check box with the text “Disable default listeners”. Check that check box and click on “Apply”.

    Well done! Now you disabled your default TestNG Listeners. Our next task is assigning the proper listener in the TestNG xml.

2. Adding ReportNG Listeners to TestNG XML:
Add the following lines of XML tags for your existing TestNG XML under “<suite” tag.

<listeners>
< listener class-name=”org.uncommons.reportng.HTMLReporter”/>
<listener class-name=”org.uncommons.reportng.JUnitXMLReporter”/>
< /listeners>
Good work! You are almost there. The next step is to write a code for appending screenshot to your existing ReportNG Report.

3. Write code for appending Screenshot:
Add the following code for test class for doing this task. Let’s discuss about the code now. The first method with the annotation “@AfterMethod” will run after every method . In this method we are calling the “catchExceptions” method which takes care of taking screenshot and appending it to your default ReportNG reports.


@AfterMethod(alwaysRun = true)
public void afterMethod(ITestResult result) throws Exception {
if (!result.isSuccess())
catchExceptions(result);
// Quit environment.
Thread.sleep(1000);
driver.quit();
}
public void catchExceptions(ITestResult result) {
BufferedWriter writer = null;
String methodName = result.getName();
System.setProperty(“org.uncommons.reportng.escape-output”, “false”);
if (!result.isSuccess()) {
try {
String failureImageFileName = “sample1″;
String failureImageFileName1;
scrFile = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(scrFile, new File(failureImageFileName));
String userDirector = System.getProperty(“user.dir”) + “/”;
String s1 = “<table><tr><td><font style=\”text-decoration: underline;\” size=\”3\” face=\”Comic sans MS\” color=\”green\”><b>Screenshot</b></font></td></tr> “;
Reporter.log(s1);
Reporter.log(“<tr><td><a href=\””+ userDirector + failureImageFileName +”\”><img src=\”file:///” + userDirector+ failureImageFileName + “\” alt=\”\””+ “height=’120′ width=’120′/></td></tr> “);
Reporter.setCurrentTestResult(null);
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
 
Fine!! Now you have successfully added the screenshot to your ReportNG Report.

Let’s discuss about another advanced feature “Webpage”. Webpage is nothing but the source code of the corresponding page. While working with selenium, the most probable and simple issues are object locations. As we have page source appended with the report, it is easy for identifying such issues. It also minimizes the debugging time, because while debugging the test case, we don’t want to go to that particular page. WebDriver itself is providing us an option to have that page source.

driver.getPageSource()” will fetch the page source. Now the following will be used to add such page source to our Report. Also see the Screenshots of the ReportNG report after adding these features.

String s2 = “<tr style=\”height:20px\”><td></td></tr>”;
Reporter.log(s2);
String s3 = “<tr><td><font style=\”text-decoration: underline;\” size=\”3\” face=\”Comic sans MS\” color=\”green\”><b>Webpage</b></font></td></tr> “;
Reporter.log(s3);
failureImageFileName1 = userDirector + “sample2″;
scrFile = new File(failureImageFileName1);
writer = new BufferedWriter(new FileWriter(scrFile));
writer.write(driver.getPageSource());
writer.close();
Reporter.log(“<tr><td><a href=\””+ scrFile +”\”><img src=\”file:///” + scrFile + “\” alt=\”\””+ “height=’120′ width=’120′/></td></tr></table> “+”<br />”);
Sample ReportNG Report: (Click for zoom)

Flash App ?? Now you can automate this too :-)

Flash testing is not normal automation testing.
Flash is not part of HTML webpage. Its embed object on HTML webpage.
So its not possible to get xpath of element on the flash movie / flash. As we all know that Webdriver works with the object properties, it is always impossible to automate the flash apps using webdriver.

Then How to automate Flash Applications using webdriver?
      While responding to the same question, the developer of selenium, Jason Huggins has suggested two ways. One way is navigate to the page where the flash object is located using webdriver and get x,y coordinates of the object. Now we can use Java’s Robot library to send an OS-level clicking and typing to an absolute screen coordinate that lines up with the fields and buttons in your flash app. Second way is First, you modify the source code of you the flash application, exposing internal methods using the ActionScript’s ExternalInterface API. Once exposed, these methods will be callable by JavaScript in the browser.Now that JavaScript can call internal methods in your flash app, you use WebDriver to make a JavaScript call in the web page, which will then call into your flash app.

Well!! We are going to see some other techniques apart from Jason’s suggestions .

In the current trends we can handle it based on two factors.
The first one is, when we don’t have any object ids and any Java Script methods exposed by the developer, we can use a tool called “Sikuli”. This is image based recognition tool and can be very well integrated with selenium. You can get the details about sikuli+Selenium from the below path:


The other approach is when you have object ID and Javascript methods exposed by the develeoper. For doing this Selenium RC has extension FlexUISelenium that enables the Selenium RC client drivers to interact (and test) the Flex UI components and methods of the Flex application.
you can download jar and include them into project and get functions to communicate with Flash.

You can get that jar from the below path

https://code.google.com/p/flash-selenium/downloads/detail?name=flash-selenium.jar&can=2&q=

But there is no extension available for Selenium Webdriver.
So we do smart work here. We rewrite FlashSelenium.java for selenium Webdriver.


import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;

public class FlexDriver {
   private final WebDriver webDriver;
   private final String flshObjectId;

   public FlexDriver(final WebDriver webDriver, final String flshObjectId) {
   this.webDriver = webDriver;
   this.flshObjectId = flshObjectId;
}


public String click(final String objectId, final String optionalButtonLabel) {
   return call(“doFlexClick”, objectId, optionalButtonLabel);
}

public String click(final String objectId) {
    return click(objectId, “”);
}


public String call(final String functionName, final String… args) {
    final Object result =
    ((JavascriptExecutor)webDriver).executeScript(
    makeJsFunction(functionName, args),
    new Object[0]);

    return result != null ? result.toString() : null;
}

private String makeJsFunction(final String functionName, final String… args) {
    final StringBuffer functionArgs = new StringBuffer();

       if (args.length > 0) {
         for (int j = 0; j < args.length;j++) {
            if (j > 0) {
                functionArgs.append(“,”);
             }
           functionArgs.append(String.format(“‘%1$s’”, args[j]));
          }
       }
        return String.format(
        “return document.%1$s.%2$s(%3$s);”,
           flshObjectId,functionName,functionArgs);
       }
}


Now we can use the above class for automating with the help of methods exposed by the developer. Just create a class and paste this code.
Here Iam going to demonstrate the use of above class for a website which has flash Object. Create another class and paste the below code and have the fun of automating Flash app.

import org.openqa.selenium.firefox.FirefoxDriver;
public class MainSetting {
    public static void main(String[] args) throws InterruptedException {
         FirefoxDriver driver = new FirefoxDriver();
         driver.get(“http://www.permadi.com/tutorial/flashjscommand/“);
         driver.manage().window().maximize();
         Thread.sleep(5000);
          FlexDriver flashApp = new FlexDriver(driver, “myFlashMovie”);
          flashApp.call(“Play”); // first number
          Thread.sleep(3000L);
          flashApp.call(“StopPlay”); // operation  
          Thread.sleep(3000L);
          flashApp.call(“Rewind”);
            System.out.println(flashApp.call(“GetVariable”,”/:message”));
         flashApp.call(“SetVariable”,”/:message”,”Learn Flash testing with Webdriver”);
          System.out.println(flashApp.call(“GetVariable”,”/:message”));
       }
}

In the above example Iam passing the object’s ID to the “FlexDriver” class along with driver object. Now Iam calling the methods which were exposed by the developer.

Let us see one more example with Youtube.

public class MainSetting {
public static void main(String[] args) throws InterruptedException {
      System.setProperty   (“webdriver.ie.driver”,”D:\\Backup\\Project\\OwnWorkspace\\AutomationJars\\chromedriver.exe”);
        WebDriver driver = new ChromeDriver();
       FlexDriver flashApp = new FlexDriver(driver, “movie_player”);
        //driver.manage().window().maximize();
       driver.get(“http://www.permadi.com/tutorial/flashjscommand/“);
System.out.println(” Page Opened is: “+driver.getCurrentUrl()+driver.getTitle());
        Thread.sleep(5000L);
      //Wait for video to load
     while (Integer.parseInt(flashApp.call(“getPlayerState”)) == 3){
            Thread.sleep(1000);
      }
      // Play the video for 10 seconds
       Thread.sleep(5000);
       flashApp.call(“Play”);
       System.out.println(” Executing pauseVideo function “);  
       Thread.sleep(10000);
       flashApp.call(“StopPlay”);
       System.out.println(” Executing playVideo function “);
       Thread.sleep(5000);
       flashApp.call(“seekTo”,”140″,”true”);
       System.out.println(” Executing seekTo 140 function “);
       Thread.sleep(5000);
       flashApp.call(“mute”);
      System.out.println(” Executing mute audio function “);
      Thread.sleep(5000);
      flashApp.call(“setVolume”,”50″);
      System.out.println(” Executing setVolume to 50 function “);
      Thread.sleep(5000);
      System.out.println(” Closing Browser”);
      driver.close();
     }

}
In the above example, the methods like “Play”, “stopplay” etc were exposed by the google for youtube.
So, Finally we are out of a illusion that flash apps/flash cannot be automated.
Happy Testing . Do reach me @ illi.nainappa@gmail.com for any queries and assistance.

“Event Firing WebDriver” – It hears whatever you do!

WebDriver is an interface to begin with.
All browser implementations, implement this interface and provide concrete implementations for the specific browser and that is how you have InternetExplorerDriver, FirefoxDriver, ChromeDriver etc.,
EventFiringWebDriver is also a concrete implementation of the WebDriver, but what it does is, it doesn’t implement the WebDriver directly, but binds itself to an existing object of any of the webdrivers listed above, and then when used, it triggers events.
So using EventFiringWebDriver you can listen to events such as before text is changed, after text is changed, before url is loaded etc., and choose to do something with the EventFiringWebDriver.
Webdriver has a WebDriverEventListener interface which you can implement and override the particular listener you want. We use this Listener Interface to capture the events generated by EventFiringWebDriver.
Methods available in webdrivereventlistener:
  • afterChangeValueOf(WebElement element, WebDriver driver)
  • Called after WebElement.clear(), WebElement.sendKeys(…)}.
  • afterClickOn(WebElement element, WebDriver driver)
  • Called after WebElement.click().
  • afterFindBy(By by, WebElement element, WebDriver driver)
  • Called after WebDriver.findElement(…), or WebDriver.findElements(…), or WebElement.findElement(…), or WebElement.findElements(…).
  • afterNavigateBack(WebDriver driver)
  • Called after navigate().back().
  • afterNavigateForward(WebDriver driver)
  • Called after navigate().forward().
  • afterNavigateTo(java.lang.String url, WebDriver driver)
  • Called after get(String url) respectively navigate().to(String url).
  • afterScript(java.lang.String script, WebDriver driver)
  • Called after RemoteWebDriver.executeScript(java.lang.String, java.lang.Object[]).
  • beforeChangeValueOf(WebElement element, WebDriver driver)
  • Called before WebElement.clear(), WebElement.sendKeys(…).
  • beforeClickOn(WebElement element, WebDriver driver)
  • Called before WebElement.click().
  • beforeFindBy(By by, WebElement element, WebDriver driver)
  • Called before WebDriver.findElement(…), or WebDriver.findElements(…), or WebElement.findElement(…), or WebElement.findElements(…).
  • beforeNavigateBack(WebDriver driver)
  • Called before navigate().back().
  • beforeNavigateForward(WebDriver driver)
  • Called before navigate().forward().
  • beforeNavigateTo(java.lang.String url, WebDriver driver)
  • Called before get(String url) respectively navigate().to(String url).
  • beforeScript(java.lang.String script, WebDriver driver)
  • Called before RemoteWebDriver.executeScript(java.lang.String, java.lang.Object[])
  • onException(java.lang.Throwable throwable, WebDriver driver)
  • Called whenever an exception would be thrown.
Let us see how to implement this interface to capture our events. The following code snippet gives better idea of implementing it.
Below is the test code:
public class eventlistenerTest {
@Test
public void WedrivereventlistenerTest(){
FirefoxDriver d1 = new FirefoxDriver();
EventFiringWebDriver event = new EventFiringWebDriver(d1);
WebDriverListerners eventListener = new WebDriverListerners();
event.register(eventListener);
event.manage().window().maximize();
event.navigate().to(“https://www.esurance.com/”);
event.findElement(By.id(“V1AtxtZipCode”)).sendKeys(“90001″);
event.findElement(By.id(“V1AbtnGoZip”)).click();
event.findElement(By.id(“IBWC1Clickable_1″)).click();
event.findElement(By.id(“ODI1LastNameData”)).sendKeys(“gs”);
event.findElement(By.id(“ODI1StreetAddressData_1″)).sendKeys(“sdfgsdf”);
event.findElement(By.id(“IBWC2ValidateClickable”)).click();
event.quit();
}
}
Now we will implement the WebdriverEventListener Interface by overriding the existing methods.

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import org.apache.bcel.generic.LSTORE;
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.StaleElementReferenceException;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.support.events.AbstractWebDriverEventListener;
import org.openqa.selenium.support.ui.Select;
import org.testng.Reporter;
public class WebDriverListerners extends AbstractWebDriverEventListener {
private By lastFindBy;
private WebElement lastElement;
private String originalValue;
/*
* URL NAVIGATION | NAVIGATE() & GET()
*/
// Prints the URL before Navigating to specific URL “get(“http://www.esurance.com”);”
@Override
public void beforeNavigateTo(String url, WebDriver driver) {
commonReport(“Before Navigating To : ” + url + “, my url was: “+ driver.getCurrentUrl(),dateTimeStamp());
}
// Prints the current URL after Navigating to specific URL “get(“http://www.esurance.com”);”
@Override
public void afterNavigateTo(String url, WebDriver driver) {
commonReport(“After Navigating To: ” + url + “, my url is: “+ driver.getCurrentUrl(),dateTimeStamp());
}
// Prints the URL before Navigating back “navigate().back()”
@Override
public void beforeNavigateBack(WebDriver driver) {
commonReport(“Before Navigating Back. I was at ” + driver.getCurrentUrl(),dateTimeStamp());
}
// Prints the current URL after Navigating back “navigate().back()”
@Override
public void afterNavigateBack(WebDriver driver) {
commonReport(“After Navigating Back. I’m at ” + driver.getCurrentUrl(),dateTimeStamp());
}
// Prints the URL before Navigating forward “navigate().forward()”
@Override
public void beforeNavigateForward(WebDriver driver) {
commonReport(“Before Navigating Forward. I was at ” + driver.getCurrentUrl(),dateTimeStamp());
}
// Prints the current URL after Navigating forward “navigate().forward()”
@Override
public void afterNavigateForward(WebDriver driver) {
commonReport(“After Navigating Forward. I’m at ” + driver.getCurrentUrl(),dateTimeStamp());
}
/*
* ON EXCEPTION | SCREENSHOT, THROWING ERROR
*/
// Takes screenshot on any Exception thrown during test execution
@Override
public void onException(Throwable throwable, WebDriver webdriver) {
commonReport(“Exception Occured while performing operation on the above element.”,dateTimeStamp());
//You can write your own method to capture the screenshot upon failing
}
/*
* FINDING ELEMENTS | FINDELEMENT() & FINDELEMENTS()
*/
// Called before finding Element(s)
@Override
public void beforeFindBy(By by, WebElement element, WebDriver driver) {
lastFindBy = by;
commonReport(“Trying to find: ‘” + lastFindBy + “‘.”,dateTimeStamp());
}
// Called after finding Element(s)
@Override
public void afterFindBy(By by, WebElement element, WebDriver driver) {
lastFindBy = by;
commonReport(“Found: ‘” + lastFindBy + “‘.”,dateTimeStamp());
}
/*
* CLICK | CLICK()
*/
// Called before clicking an Element
@Override
public void beforeClickOn(WebElement element, WebDriver driver) {
String strlastElement=(element.toString().split(“->”)[1]);
strlastElement=strlastElement.substring(0,strlastElement.length()-1);
commonReport(“Trying to click: ‘” + strlastElement + “‘”,dateTimeStamp());
// Highlight Elements before clicking
for (int i = 0; i < 1; i++) {
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript(
“arguments[0].setAttribute(‘style’, arguments[1]);”,
element, “color: yellow; border: 3px solid black;”);
}
}
// Called after clicking an Element
@Override
public void afterClickOn(WebElement element, WebDriver driver) {
String strlastElement=(element.toString().split(“->”)[1]);
strlastElement=strlastElement.substring(0,strlastElement.length()-1);
commonReport(“Clicked Element with: ‘” + strlastElement + “‘”,dateTimeStamp());
}
/*
* CHANGING VALUES | CLEAR() & SENDKEYS()
*/
// Before Changing values
@Override
public void beforeChangeValueOf(WebElement element, WebDriver driver) {
lastElement = element;
if(element.getAttribute(“type”).equals(“text”)||element.getAttribute(“type”).equals(“text”)){
originalValue = element.getText();
// What if the element is not visible anymore?
if (originalValue.isEmpty()) {
originalValue = element.getAttribute(“value”);
}
}
else{
Select slct=new Select(element);
originalValue=slct.getFirstSelectedOption().toString();
}
}
// After Changing values
@Override
public void afterChangeValueOf(WebElement element, WebDriver driver) {
lastElement = element;
String strlastElement=(element.toString().split(“->”)[1]);
strlastElement=strlastElement.substring(0,strlastElement.length()-1);
String changedValue = “”;
if(element.getAttribute(“type”).equals(“text”)||element.getAttribute(“type”).equals(“text”)){
try {
changedValue = element.getText();
} catch (StaleElementReferenceException e) {
onException(e, driver);
return;
}
// What if the element is not visible anymore?
if (changedValue.isEmpty()) {
changedValue = element.getAttribute(“value”);
}
}
else{
Select slct=new Select(element);
changedValue=slct.getFirstSelectedOption().toString();
}
commonReport(“Changing value in element found ‘” + strlastElement
+ “‘ from ‘” + originalValue + “‘ to ‘” + changedValue + “‘”,dateTimeStamp());
}
/*
* SCRIPT – this section will be modified ASAP
*/
// Called before RemoteWebDriver.executeScript(java.lang.String, java.lang.Object[])
@Override
public void beforeScript(String script, WebDriver driver) {
//do nothing
}
// Called before RemoteWebDriver.executeScript(java.lang.String, java.lang.Object[])
@Override
public void afterScript(String script, WebDriver driver) {
//do nothing
}
public void commonReport(String strText,String strTimeStamp){
System.out.println(strTimeStamp+”: “+strText);
}
public String dateTimeStamp(){
String dateTime = new SimpleDateFormat(“yyyy-MM-dd HH:mm:ss”).format(Calendar.getInstance().getTime());
return dateTime;
}
}
This will generate the event description in eclipse console. We can customize this, to generate the events in ReportNG and report to your choice.
So, Happy Testing :-) .