Tuesday, March 02, 2010
RIATest: Automating Custom Components
RIATest is a GUI test automation tool for Adobe Flex applications. RIATest does for your GUI what FlexUnit does for your code, and it is available on Windows and Mac OS X. RIATest has number of useful features which can be very helpful, such as component inspector, script debugger, and synchronization capabilities. You can find the full list of features here.
When you specify actions that must be performed on your application the first thing you specify is what component you want to be located by RIATest so that an action can be performed on it. RIATest has few ways of locating components. One of the ways is locating component by label e.g. button with "Save" label can be located following way:
Component can be located in a same manner using components automatationName. You can also locate component using its automationIndex:
Let's discuss one exact example. Here we have a CustomPanel with a button added in its title bar. You will notice that the button which you just added is not visible in the inspector:
So what we can do? We need to implement automation delegate class for our custom component. Exposing child components is done by implementing numAutomationChildren/getAutomationChildAt pair of functions. numAutomationChildren function must return the number of children component for your custom class, getAutomationChildAt must return the child at the specified index. This means we need to implement automatation delegate class for our custom component to make Switch button accessible from RIATest.
numAutomationChildren
In our case we will need to return the number of children which are implementing IAutomationObject plus Switch button:
getAutomationChildAt
getAutomationChildAt will need to return the child with a given index in case of index < numChildren and return Switch button in case of index == numChildren
We will also need to implement init method in order to register our delegate class:
The only thing left to do is to include our delegate into build, include your delegate class using additional compiler arguments:
As you can see from the screenshot now Switch button is getting displayed in the inspector, so you can easily locate it:
You can download source code of this project from here.
When you specify actions that must be performed on your application the first thing you specify is what component you want to be located by RIATest so that an action can be performed on it. RIATest has few ways of locating components. One of the ways is locating component by label e.g. button with "Save" label can be located following way:
FlexButton("Save")
Component can be located in a same manner using components automatationName. You can also locate component using its automationIndex:
FlexButton("index:0")
In most of the cases you are getting every component which you need in the inspector, so you can easily locate those components. In case you derive a custom class from built-in container-type classes you usually do not need to do anything special to make children of your custom component available for automation since this is done by the automation delegate of base class.
However sometimes you implement a custom component that contains other components but your custom component is not derived from Container built-in class. If that is the case you need to expose components contained in your custom class. You will need to perform some additional steps to access them.
Let's discuss one exact example. Here we have a CustomPanel with a button added in its title bar. You will notice that the button which you just added is not visible in the inspector:
So what we can do? We need to implement automation delegate class for our custom component. Exposing child components is done by implementing numAutomationChildren/getAutomationChildAt pair of functions. numAutomationChildren function must return the number of children component for your custom class, getAutomationChildAt must return the child at the specified index. This means we need to implement automatation delegate class for our custom component to make Switch button accessible from RIATest.
numAutomationChildren
In our case we will need to return the number of children which are implementing IAutomationObject plus Switch button:
override public function get numAutomationChildren() : int { var count:int = 0; for(var i:int=0; i < comp.numChildren; i++) { if (comp.getChildAt(i) is IAutomationObject) count++; } return ++count; }
getAutomationChildAt
getAutomationChildAt will need to return the child with a given index in case of index < numChildren and return Switch button in case of index == numChildren
override public function getAutomationChildAt( index : int ) : IAutomationObject { if (index >= 0 && index < comp.numChildren ) return comp.getChildAt(index) as IAutomationObject; if(index == comp.numChildren) return comp.button; return null; }
We will also need to implement init method in order to register our delegate class:
public static function init( root : DisplayObject ) : void { Automation.registerDelegateClass( CustomPanel, CustomPanelAutomationImpl); }
The only thing left to do is to include our delegate into build, include your delegate class using additional compiler arguments:
-includes CustomPanelAutomationImpl
As you can see from the screenshot now Switch button is getting displayed in the inspector, so you can easily locate it:
FlexPanel("index:0")->FlexButton("Switch")=>click();
You can download source code of this project from here.