Testing Flash with Selenium RC

A lot of websites use Flash to improve the user interface. The ability to pimp up a web page with flash is great, it looks excellent and often better than simple HTML pages. But the ability to test Flash pages is poor. In this tutorial I try to explain a way to test flash objects with javascript and selenium.

Preconditions:
The steps described in this tutorial were done with selenium-core 0.8.2-SNAPSHOT and selenium-rc 0.9.1-SNAPSHOT and executed on an IE6.
To test Flash Objects it is necessary to know the "internals" of the flash object and you must have the ability to add some code to the flash object. You cannot test any flash you find in the net, it must be yours!

Flash and Javascript:
Flash objects on a webpage are accessable by some javascript functions. We will use only three of them:

  • GetVariable(varName)
  • SetVariable(varName, varValue)
  • TCallLabel(target, label)

A full list is found on the adobe site

First I explain how Flash variables are accessed by javascript:

Assume you have embedded a flash object on the webpage with

  <object name="flashTest" codebase="..."></object>

To get the value of a variable inside the flash object, you have to call a javascript function like this

  function getFlashVariable(varName) {
    flashObj = window.document.getElementById( 'flashTest' );
    return flashObj.GetVariable(varName);
  }

To set a value:

  function setFlashVariable(varName,varValue) {
    flashObj = window.document.getElementById( 'flashTest' );
    return flashObj.SetVariable(varName,varValue);
  }

To call a flash function, e.g. to simulate the click on a button, a flash function like button.onRelease must be called. Our Flash developer added a label to all Flash objects, which calls a function via reflection ( see below ) . To call this label - and execute the designated function - use this javascript function:

  function execFlashMethod( methodName, paramList) {
    flashObj = window.document.getElementById( 'flashTest' );
    flashObj.SetVariable("buttonClickFunction", methodName);
    flashObj.SetVariable("buttonClickTarget",paramList);
    flashObj.TCallLabel("/", "clickIt");
  };

Add the following code to your flash. The code must reside on the label clickIt.

buttonClickTarget = buttonClickTarget.split(",");
for (var x = 0; x<buttonClickTarget.length; x++) {
	if (buttonClickTarget[x] == "true") {
		buttonClickTarget[x] = true;
	} else if (buttonClickTarget[x] == "false") {
		buttonClickTarget[x] = false;
	} else if (Number(buttonClickTarget[x])) {
		buttonClickTarget[x] = Number(buttonClickTarget[x]);
	}
}
eval(buttonClickFunction).apply(null, buttonClickTarget);

Now we are able to set and get values of variables and to execute functions inside a flash object via javascript.

Adding the stuff to selenium:
The next step explains how to inject the 3 javascript functions to selenium.( selenium-core 0.8.1 and selenium-rc 0.9.1)

Add the javascript to selenium core
As these functions are not builtin functions of selenium core, we have to add them manually. In the selenium-core project the folder javascript/core/scripts contains the js file selenium-api.js. Find a apropiate location for the new functions ( add them after the last Selenium.prototype function) and put them there.
Note: Before we start, I have to mention that selenium-rc has problems calling javascrip functions with more than two parameters. As we need three parameters for the setVariable and executeMethod function, I assume the name of the flash object is flashTest. Then we can reduce the number of parameters to 2.

 Selenium.prototype.getFlashVariable = function(locator,varName ) {
 
   /**
    * Returns the value of  a variable inside the flash object.
    *
    * @param locator the locator of the flash object
    * @param varName the name of the variable
    * @return string the value of the variable
    */
   var flashObj = this.page().findElement(locator);
   return flashObj.GetVariable(varName);
 }

 Selenium.prototype.doSetFlashTestVariable= function(flashVarName,varValue) {
   /**
    * Sets a variable inside the flash object.
    *
    * @param flashVarName the name of the variable
    * @param varValue the value of the variable
    */
  var flashObj = this.page().findElement("flashTest")
  flashObj.SetVariable(varName, varValue );
 }

 Selenium.prototype.doExecuteFlashMethod = function(methodName,paramList ) {
   /**
    * Executes a method in the flash object identified by the locator. This
    * is NOT a standard flash function. The flash must be contain function clickIt
    * which reads the parameter buttonClickFunction and buttonClickTarget and calls the
    * named function via reflection.
    *
    * @param methodName the name of the method to call
    * @param paramList a comma separated list of parameters
    */
    var flashObj = this.page().findElement("flashTest");
    flashObj.SetVariable("buttonClickFunction", methodName);
    flashObj.SetVariable("buttonClickTarget",paramList);
    flashObj.TCallLabel("/", "clickIt");
 }

That's all for selenium.core, so build it now.

After that a full build of the selenium-rc server and client (in this example the java client) generates additional functions.
The Java Client should contain three extra methods:

 void setFlashVariable(String flashVarName,String varValue);

 String getFlashVariable(String locator,String varName);

 void executeFlashTestMethod(String methodName,String paramList);

Now you are able to write a test with the java client which accesses variables in the flash object and executes some methods. E.g. to click on a button named buttonTest call the function buttonTest.onRelease with

  executeFlashTestMethod("buttonTest.onRelease","");

The click on the button will be simulated by the javascript stuff.

One tip to read arrays: if you have an array in your flash object like

var result:Array = [];

You can read the 5.th element of the result array with:

getFlashVariable("flashTest","result:5");

Start the new flash enabled selenium server and try it out!

Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.
  1. May 18, 2007

    Parv says:

    Hi, I'm using selenium rc and i need to test flash. In step Adding the stuff to...

    Hi,
    I'm using selenium rc and i need to test flash. In step Adding the stuff to Selenium (adding the 3 javascript functions to selenium) do i need install selenium core? if not, where in selenium rc do i add these three methods?
    Just need some help getting started?

  2. May 21, 2007

    Parv says:

    After i do all of the above i get an error "in `do_command': ERROR: Unknown comm...

    After i do all of the above i get an error "in `do_command': ERROR: Unknown command: 'doExecuteFlashMethod' (SeleniumCommandError)" when i try to run my tests.

    I didn't build the selenium-server, but i did build the client.

    For the server, i simply made the suggested changes to jar file.

  3. May 25, 2007

    Ryan Greenwood says:

    This looks very interesting, however as per the above post I am having problems ...

    This looks very interesting, however as per the above post I am having problems understanding the content specifically as pasted below:

    "That's all for selenium.core, so build it now.

    After that a full build of the selenium-rc server and client (in this example the java client) generates additional functions."

    The selenium specific changes that have been made up to this point have been made to selenium-api.js in the selenium-core. Presumably functions found in this file are interpreted within the browser. The confusion arises from "build" part. What does "build" mean in terms of the selenium-core, and then further removed, in terms of the seleniumrc and java client (maybe DefaultSelenium.java?)

    Is there javac, or perhaps Ant, activity to be performed somewhere?

    Interested

  4. Jul 05, 2007

    Tarek says:

    Hi, as i can see there are some confusions of the "build selenium" part. So i t...

    Hi,

    as i can see there are some confusions of the "build selenium" part. So i try to explain.

    The 3 functions ( getFlashVariable, setFlashVariable and doExecuteFlashMethod) are build into the selenium-api.js, so a build of selenium-core is necessary.
    To use these functions from a client (e.g.the java client) you have to build the selenium-server and the client.
    While building the server the selenium-js.api is parsed and a Selenium Interface is generated. This interface is used by the server and the client to access the fucntions of selenium-api.js.

    So after a change of the selenium-api.js a "full" rebuild is necessary!

    Hope that helps.

    Tarek

  5. Jul 24, 2008

    Yogesh Bhole says:

    I am using flash selenium. Just want to ask do Getvariable function works with F...

    I am using flash selenium. Just want to ask do Getvariable function works with Flash 9 movie with action script when flash movie is played in IE? I have problem getting flash variables using GetVaribale function.

  6. Aug 07, 2008

    Larry Hamel says:

    This project appears to offer some help with the integration: http://code.google...

    This project appears to offer some help with the integration: http://code.google.com/p/flash-selenium/

  7. Apr 29, 2010

    Oksana says:

    Hi, I'm using selenium rc and i need to test flash.  I need to click Allow...

    Hi,

    I'm using selenium rc and i need to test flash.  I need to click Allow button on player .I just need some help getting started?

    Thanks

  8. Jun 13, 2010

    Eusebiu Blindu says:

    Hi,    I am a little bit familiar with your tools, selenium and pywin...

    Hi,

       I am a little bit familiar with your tools, selenium and pywinauto was very nice to play with. But I wouldn't recommend them in a real testing environment. I also wrote about selenium flash here:

       http://www.testalways.com/?p=63

       You can contradict me or give your opinion but for now I would avoid using selenium.

    Thanks,

    Sebi

  9. Mar 08, 2011

    Ripal Parikh says:

    Hi All, I have read this article and all comments.After reading them  i do...

    Hi All,

    I have read this article and all comments.After reading them  i do have following droughts.

    1) Where should i put methods getFlashVariable,setFlashVariable and execFlashMethod in java class

    2)After putting getFlashVariable, setFlashVariable and doExecuteFlashMethod in selenium-api.js file how to build them ??

    3)It would be good if u put some sample code here.