Automating Flex Applications Using Selenium

Author : Kushal Bhalaik
March, 2017



Introduction

This tutorial will help user understand how Flex Applications can be automated using Selenium with. It is helpful for all those users who are looking to automate Flex applications without having to employ commercial automation tools.

What is a flex application?

Flex is a powerful open-source application framework that allows developers to easily build mobile applications for iOS, Android, and BlackBerry Tablet OS, as well as traditional applications for the browser and the desktop using the same programming model, the same tool, and the same code base.
Flex application is deployed as SWF file(s) plus an HTML wrapper, the CSS file(s) and any server-side script files (i.e. Java, .CFM, .PHP, etc) to the server. Like traditional web applications.

Challenges in automating Flex application:

•             Hard to identify flex applications, even though if an application is running on web there isn’t a simple way to identify objects using id, xpath, name or css selectors.
•             Interacting with flex objects is difficult as it is not possible to interact with standard
Selenium commands directly.


Pre-requisites:

This application makes use of open-source third party projects named as below:
1.            Selenium
2.            SeleniumFlexAPI
3.            Flex-Spy

Dependency: SeleniumFlexAPI and Flex-spy are required to be compiled along with the flex application.


Understanding how Selenium can interact with Flex applications:-

As it has already been mentioned that it’s not possible to locate objects of a flex application using Selenium’s standard locators and in order to expose those objects to selenium there is a dependency to compile sfapi.swc (shockwave control file) which comes with SeleniumFlexAPI, which in turn exposes flex objects to selenium using JavaScript.





Steps To automate a Flex Application:

1.            SeleniumFlexAPI : Download SeleniumFlexAPI from Google code repository
                              https://code.google.com/archive/p/sfapi/
2.            Flex Spy :                             Download Flex Spy from Google code repository
                              https://code.google.com/archive/p/fxspy/

3.            Include sfapi.swc from SeleniumFlexAPI in your Flex Project in Eclipse IDE or Flash Builder

Project Directory > lib > sfapi.swc
Copy -include-libraries "..\lib\sfapi.swc" in

Project Properties > Flex Compiler > Additional compiler arguments







4.            Include FlexSpy.swc  in your project

Project Properties > Flex Build Path > Add SWC > FlexSpy.swc




5.            Add a button somewhere in your Flex application to show the Flex-Spy window:

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"> ... <mx:Script> <![CDATA[ import com.flexspy.FlexSpy; ]]> </mx:Script> ... <mx:Button id="btnFlexSpy" label="FlexSpy" click="FlexSpy.show()" /> ... </mx:Application>

6.            Create a FlexWebDriver Class in your Selenium Framework as :


 package package1;

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

public class FlexWebDriver {

       private final WebDriver webDriver;
       private final String flashObjectId;

       public FlexWebDriver(final WebDriver webDriverfinal String flashObjectId) {  
              this.webDriver = webDriver;
              this.flashObjectId = flashObjectId;
       }

       public String click(final String objectIdfinal String optionalButtonLabel) {  
              return call("doFlexClick"objectIdoptionalButtonLabel);
       }
       public String click(final String objectId) {
              return click(objectId"");
       }


       public String getFlexText(String objectId ){

              return call("getFlexText"objectId,"");
       }


 //... Rest omitted for clarity ...

       private String call(final String functionNamefinal String... args) {

              final Object result =
                           ((JavascriptExecutor)webDriver).executeScript(
                                         makeJsFunction(functionNameargs),
                                         new Object[0]);


              System.out.println("Action result : " + result );

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

       private String makeJsFunction(final String functionNamefinal String... args) {
              final StringBuffer functionArgs = new StringBuffer();

              if (args.length > 0) {
                     for (int i = 0; i < args.lengthi++) {
                           if (i > 0) {
                                  functionArgs.append(",");
                           }
                           functionArgs.append(String.format("'%1$s'"args[i]));
                     }
              }

              System.out.println("Executing : " + String.format(
                           "document.%1$s.%2$s(%3$s);",
                           flashObjectId,
                           functionName,
                           functionArgs));
              return String.format(
                           "return document.%1$s.%2$s(%3$s);",
                           flashObjectId,
                           functionName,
                           functionArgs);
       }


}




7.            Now we can call all these Flex Methods from our Selenium class as following:


 package package1;

import java.util.concurrent.TimeUnit;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;

import FlexMethods.FlexWebDriver;

public class FlexTest {

       public static void main(String[] argsthrows InterruptedException {
        
              System.setProperty("webdriver.gecko.driver"
                                               "C:\\Eclipse\\Selenium\\geckodriver.exe");

              WebDriver driver = new FirefoxDriver();

              driver.manage().window().maximize();

              driver.get("file:///C:/Eclipse/workspace/SelFlexDemoApp/bin/selben.html");


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

             
              FlexWebDriver flashApp = new FlexWebDriver(driver,"selben");
             
             
              flashApp.selectTreeItem("tree""data");

              flashApp.click("ButtonBarButton19");

             
              flashApp.alertResponse("OK");

              flashApp.click("LinkButton61");


              flashApp.getFlexDataGridCellElement("dataGrid","3","2","1","1");

              flashApp.FlexType("TextInput97","10/03/2017");

              flashApp.getFlexDataGridCell("dataGrid""1""1");


              flashApp.FlexSelectComboByLabel("combo","grape");

              //.......
}
}





Summary

  • What is a Flex Application?
  • Challenges in identifying and interacting with flex object.
  • Understanding the interfacing between Selenium and Flex Application using Selenium-FlexAPI.  
  • Steps to automate Flex Application.



Reference(s)

https://github.com/hirsivaja/sfapi
https://code.google.com/archive/p/fxspy/wikis/InstallationInstructions.wiki
https://code.google.com/archive/p/sfapi/







No comments: