Flex Automation of Composite Component

Just posting a quick code snippet for anyone banging their head against the wall trying to setup Flex automation testing on a composite component. Adobe's documentation for automation-enabling composite components assumes a fixed set of items, using a simple switch statement to return the known object.

But what if you have a dynamic composite object, such as a Panel that lets you dynamically add Buttons to the TitleBar? In that case you can't use a switch statement because you don't know what objects are there. The following code example should clear that up:

  override public function get numAutomationChildren():int {
    return this.numChildren + (this.titleBar == null ? 0 : this.titleBar.numChildren);
  }
  
  override public function getAutomationChildAt(index:int):IAutomationObject {
    var obj:DisplayObject = null;
    if (this.titleBar != null && index < titleBar.numChildren)
    {
      obj = titleBar.getChildAt(index);
      if (obj is IAutomationObject)
        return obj as IAutomationObject;
    }
    else
    {
      var realIndex:int = index - titleBar.numChildren;
      obj = getChildAt(realIndex);
      if (obj is IAutomationObject)
        return obj as IAutomationObject;
      }
      return obj as IAutomationObject;;
  }

The overridden methods allow your class to control how Automation testing tools can identify objects on your component. The testing tool will attempt to 'grab' those objects via getAutomationChildAt using an index calculated via our numAutomationChildren. By modifying the number returned via get numAutomationChildren you can 'hide' or 'show' more items to the automation tools (hiding by returning less items than you actually have, or showing more by adding items from other collections, such as the titleBar on a Panel).

In the example above, if the index is less than the total numChildren of our titleBar (or any other UIComponent) that means we can assume the tool simulated a click on something within that item's collection, so we retrieve the object and cast it as an IAutomationObject. If the index is higher than the numChildren on our titleBar, we can assume it clicked elsewhere and return the right object.

You can also set this up with an Automation Delegate, in case you don't want to modify your base code for automation testing. This blog post for automation delegates is a good start.