Sunday 17 August 2014

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.

1 comment:

  1. This is gr8:-)
    It's becoming more and more important to stay up to date on the facts and to learn as much as possible.
    If anyone needs a refresher on automation. This is good article.
    Thanks for the blog:-)

    ReplyDelete