Dashboard > Selenium Remote Control > Home > Testing Flash with Selenium RC
Selenium Remote Control Log In View a printable version of the current page.
Testing Flash with Selenium RC
Added by Tarek, last edited by Tarek on Apr 30, 2007  (view change) show comment
Labels: 
(None)

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!

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?

Posted by Parv at May 18, 2007 09:34

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.

Posted by Parv at May 21, 2007 11:38

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

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

Posted by Tarek at Jul 05, 2007 10:24

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.

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

Site running on a free Atlassian Confluence Community License granted to OpenQA. Evaluate Confluence today.
Powered by Atlassian Confluence, the Enterprise Wiki. (Version: 2.5.6 Build:#812 Aug 06, 2007) - Bug/feature request - Contact Administrators