Selenium RC uses JavaScript to communicate with the browser. Flash ExternalInterface provides a mechanism for which you can use JavaScript to call an ActionScript function in a SWF file embedded in an HTML page. Therefore, we created FlashSelenium, a Selenium RC client extension that uses JavaScript as the conduit between Selenium RC and the Flash application (see Figure 2).

Figure 2. FlashSelenium with JavaScript connecting to Flash ExternalInterface
FlashSelenium is the component that adds Flash communication capabilities to the Selenium framework. Basically, it is a Selenium RC client driver extension for helping execute the tests against the Flash component. The FlashSelenium constructor takes a Selenium instance and a Flash object ID as parameters.
An instance of FlashSelenium is used to invoke the functions on the
Flash component. You can invoke functions that were externalized by the
ExternalInterface, as well as the default
functions of any Flash SWF (for example, isPlaying, PercentLoaded and TotalFrames).
FlashSelenium is currently available for Java, .NET, Ruby, and Python. Analogous components are
being created for PHP.
Next we will show you a complete example of a Flash-based web application and its corresponding Selenium RC tests.
The sample web application is very simple. It consists of a web page with an embedded Flash SWF object. The title of the page is "Clicking Colors." The Flash SWF object presents a clickable rectangle that repaints itself (rotating colors green, blue and red) for every click. Try it out on our demonstration page.
Below is the source code for colors.html, the web application containing a Flash SWF object:
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> <title>Clicking Colors</title> <body> <object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0" width="100" height="100" id="clickcolors" align="middle"> <param name="allowScriptAccess" value="sameDomain" /> <param name="movie" value="ColoredSquare.swf" /> <param name="quality" value="high" /> <param name="bgcolor" value="#ffffff" /> <embed src="ColoredSquare.swf" quality="high" bgcolor="#ffffff" width="500" height="500" name="clickcolors" align="middle" allowscriptaccess="*" type="application/x-shockwave-flash" pluginspage="/go/getflashplayer" /> </object> </body> </html>
Note that the Flash SWF object ID, clickcolors, will be
used by the Selenium RC test.
Below is ColoredSquare.as, the source code for the Flash SWF component embedded in the web application:
package {
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.external.ExternalInterface;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.text.TextFormat;
public class ColoredSquare extends Sprite {
private const COLOR_HEX_VALUES:Array = [0×00ff00, 0×0000ff, 0xff0000];
private const COLORS:Array = ["GREEN", "BLUE", "RED"];
private const SQUARE_SIDE:uint = 500;
private var currentColor:uint;
private var currentColorIndex:uint = 0;
private var buttonSprite:Sprite = new Sprite();
private var squareLabel:String = "(Click here)";
private var label:TextField = new TextField();
public function ColoredSquare() {
currentColor = COLOR_HEX_VALUES[currentColorIndex % 3];
updateButtonLabel();
drawButton();
addEventListener(MouseEvent.CLICK, buttonClicked);
// functions available for JavaSript calls
ExternalInterface.addCallback("getColor", getColor);
ExternalInterface.addCallback("click", changeColor);
ExternalInterface.addCallback("getSquareLabel", getSquareLabel);
ExternalInterface.addCallback("setSquareLabel", setSquareLabel);
}
private function buttonClicked(event:MouseEvent):void {
changeColor();
}
private function changeColor():void {
currentColorIndex++;
currentColor = COLOR_HEX_VALUES[currentColorIndex % 3];
this.squareLabel = COLORS[currentColorIndex % 3];
updateButtonLabel();
drawButton();
}
private function updateButtonLabel():void {
var format:TextFormat = new TextFormat();
format.size = SQUARE_SIDE / 10;
var label:TextField = new TextField();
label.autoSize = TextFieldAutoSize.LEFT;
label.selectable = false;
label.defaultTextFormat = format;
label.text = squareLabel;
label.x = SQUARE_SIDE / 5;
label.y = SQUARE_SIDE / 2.5;
if (buttonSprite.contains(this.label)) {
buttonSprite.removeChild(this.label);
}
this.label = label;
buttonSprite.addChild(this.label);
}
private function drawButton():void {
buttonSprite.graphics.beginFill(currentColor);
buttonSprite.graphics.drawRect(0, 0, SQUARE_SIDE, SQUARE_SIDE);
buttonSprite.graphics.endFill();
addChild(buttonSprite);
}
public function setSquareLabel(squareLabel:String):void {
this.squareLabel = squareLabel;
updateButtonLabel();
drawButton();
}
public function getColor():String {
return COLORS[currentColorIndex % 3];
}
public function getSquareLabel():String {
return this.squareLabel;
}
}
}
The following ChangeColor functions are made available for
JavaScript invocation by means of the ExternalInterface: getColor, changeColor, getSquareLabel,
and setSquareLabel:
// functions available for JavaSript call
ExternalInterface.addCallback("getColor", getColor);
ExternalInterface.addCallback("click", changeColor);
ExternalInterface.addCallback("getSquareLabel",
getSquareLabel);
ExternalInterface.addCallback("setSquareLabel",
setSquareLabel);