diff --git a/src/org/flex_pilot/FPAssert.as b/src/org/flex_pilot/FPAssert.as index d166b76..3c01c5e 100644 --- a/src/org/flex_pilot/FPAssert.as +++ b/src/org/flex_pilot/FPAssert.as @@ -250,25 +250,9 @@ package org.flex_pilot { } attrName = validatorArr[0]; expectedVal = validatorArr[1]; - // Attribute may be chained, so loop through any and - // look up the attr we want to check the value on - var attrArr:Array = attrName.split('.'); - var attrVal:Object; - var key:String; - while (attrArr.length) { - if (!attrVal) { - attrVal = obj; - } - key = attrArr.shift(); - if (key in attrVal) { - attrName = key; - attrVal = attrVal[attrName]; - } - else { - throw new Error('"' + key + - '" attribute does not exist on this object.'); - } - } + + var attrVal:Object = doLookUpAttr(attrName,obj); + } // Do any preprocessing of the value to check @@ -304,5 +288,36 @@ package org.flex_pilot { throw new Error(errMsg); } } - } + public static function doLookUpAttr(attrName:String,obj:Object):Object { + // Attribute may be chained, so loop through any and + // look up the attr we want to check the value on + var attrArr:Array = attrName.split('.'); + var attrVal:Object; + var key:String; + while (attrArr.length) { + if (!attrVal) { + attrVal = obj; + } + key = attrArr.shift(); + var arrayItemPat:RegExp = new RegExp("\\[.*\\]", "g"); + var arrayIndex:String = arrayItemPat.exec(key); + if (arrayIndex != null) { + key = key.replace(arrayIndex,""); + arrayIndex = arrayIndex.replace("[",""); + arrayIndex = arrayIndex.replace("]",""); + attrArr.unshift(parseInt(arrayIndex)); + } + // + if (key in attrVal) { + attrName = key; + attrVal = attrVal[attrName]; + } + else { + throw new Error('"' + key + + '" attribute does not exist on this object.'); + } + } + return attrVal; + } + } } diff --git a/src/org/flex_pilot/FPController.as b/src/org/flex_pilot/FPController.as index 2399a42..fea754d 100644 --- a/src/org/flex_pilot/FPController.as +++ b/src/org/flex_pilot/FPController.as @@ -15,15 +15,20 @@ Copyright 2009, Matthew Eernisse (mde@fleegix.org) and Slide, Inc. */ package org.flex_pilot { - import org.flex_pilot.events.*; - import org.flex_pilot.FPLocator; - import flash.events.* - import flash.utils.*; - import flash.geom.Point; + import com.adobe.serialization.json.JSON; + import flash.display.DisplayObject; import flash.display.DisplayObjectContainer; - import mx.events.* + import flash.events.*; + import flash.geom.Point; + import flash.system.ApplicationDomain; + import flash.utils.*; + import mx.controls.DateField; + import mx.events.*; + + import org.flex_pilot.FPLocator; + import org.flex_pilot.events.*; public class FPController { public function FPController():void {} @@ -43,7 +48,6 @@ package org.flex_pilot { Events.triggerMouseEvent(obj, MouseEvent.MOUSE_OUT); Events.triggerMouseEvent(obj, MouseEvent.ROLL_OUT); } - public static function click(params:Object):void { var obj:* = FPLocator.lookupDisplayObject(params); @@ -110,7 +114,7 @@ package org.flex_pilot { destCoords.y = destCoords.y + Number(params.offsety); } - params.coords = '(' + destCoords.x + ',' + destCoords.y + ')'; + params.coords = '(' + destCoords.x + '|' + destCoords.y + ')'; dragDropToCoords(params); } @@ -189,10 +193,10 @@ package org.flex_pilot { // Ensure coords are in the right format and are numbers private static function parseCoords(coordsStr:String):Point { var coords:Array = coordsStr.replace( - /\(|\)| /g, '').split(','); + /\(|\)| /g, '').split('|'); var point:Point; if (isNaN(coords[0]) || isNaN(coords[1])) { - throw new Error('Coordinates must be in format "(x, y)"'); + throw new Error('Coordinates must be in format "(x|y)"'); } else { coords[0] = parseInt(coords[0], 10); @@ -283,7 +287,10 @@ package org.flex_pilot { charCode: currCode }); } } - + public static function focusOut(params:Object):void { + var obj:* = FPLocator.lookupDisplayObject(params); + Events.triggerFocusEvent(obj, FocusEvent.FOCUS_OUT); + } public static function select(params:Object):void { // Look up the item to write to var obj:* = FPLocator.lookupDisplayObject(params); @@ -291,21 +298,12 @@ package org.flex_pilot { var item:*; // Give the item focus Events.triggerFocusEvent(obj, FocusEvent.FOCUS_IN); - function selectByIndex(idx:*):void { - obj.selectedIndex = idx; - } - function selectByItem(item:*):void { - obj.selectedItem = item; - } - function setComboboxSelection(setter:Function, newValue:*):void { - setter(newValue); - Events.triggerListEvent(obj, ListEvent.CHANGE); - } // Set by index switch (true) { case ('index' in params): if (obj.selectedIndex != params.index) { - setComboboxSelection(selectByIndex, params.index); + obj.selectedIndex = params.index; + Events.triggerListEvent(obj, ListEvent.CHANGE); } break; case ('label' in params): @@ -317,9 +315,10 @@ package org.flex_pilot { if (sel[labelField] != targetLabel) { for each (item in obj.dataProvider) { if (item[labelField] == targetLabel) { - setComboboxSelection(selectByItem, item); + obj.selectedItem = item; } } + Events.triggerListEvent(obj, ListEvent.CHANGE); } break; case ('data' in params): @@ -328,16 +327,22 @@ package org.flex_pilot { if (sel.data != targetData) { for each (item in obj.dataProvider) { if (item.data == targetData) { - setComboboxSelection(selectByItem, item); + obj.selectedItem = item; } } + Events.triggerListEvent(obj, ListEvent.CHANGE); } break; default: // Do nothing } } - + public static function listSelect(params:Object):void { + var obj:* = FPLocator.lookupDisplayObject(params); + var owner:* = obj.owner; + owner.selectedIndex = obj.listData.rowIndex; + Events.triggerListEvent(owner, ListEvent.ITEM_CLICK, {itemRenderer: obj}); + } public static function date(params:Object):void { // Look up the item to write to var obj:* = FPLocator.lookupDisplayObject(params); @@ -379,7 +384,50 @@ package org.flex_pilot { } return String(attrVal); } - + + public static function getObjectToJSON(params:Object):String { + var obj:* = FPLocator.lookupDisplayObject(params); + var compositeObj:Object; + if ( params["property"] ) { + var propObj:* = FPAssert.doLookUpAttr(params.property,obj); + var jsonObj:String = JSON.encode(propObj); + return jsonObj; + } + return null; + } + + public static function delegateCommand(params:Object):void { + var obj:* = FPLocator.lookupDisplayObject(params); + // Get the delegate class name from the object + var delegate:* = obj['automationDelegateClass']; + try { + delegate.init(obj,params); + } + catch(e:Error) { + throw new Error('automationDelegateClass is not defined'); + } + //Find the command (method) that we want to call by looking it up + //in the class and seeing if there is a match + if (params["command"]) { + var command:String = params["command"]; + var descr:XML = flash.utils.describeType(delegate); + var meth:*; + var methods:Object = {}; + for each (meth in descr..method) { + var methodName:String = meth.@name.toXMLString(); + if (methodName == params["command"]) { + var funct:Function = delegate[methodName] as Function; + try { + funct.apply(); + } + catch(e:Error) { + throw new Error("command method on delegate was not properly defined"); + } + break; + } + } + } + } public static function getObjectCoords(params:Object):String { // Look up the item which coords we want to get var obj:* = FPLocator.lookupDisplayObject(params); @@ -388,6 +436,10 @@ package org.flex_pilot { var coords:String = '(' + String(destCoords.x) + ',' + String(destCoords.y) + ')'; return coords; } + public static function getObjectSize(params:Object):String { + var obj:* = FPLocator.lookupDisplayObject(params); + return 'width:' + obj.width + ',height:' + obj.height; + } //Dumping the child structure of node and traversing //for child test building purposes diff --git a/src/org/flex_pilot/FPExplorer.as b/src/org/flex_pilot/FPExplorer.as index fd8ba20..49f32ee 100644 --- a/src/org/flex_pilot/FPExplorer.as +++ b/src/org/flex_pilot/FPExplorer.as @@ -15,16 +15,17 @@ Copyright 2009, Matthew Eernisse (mde@fleegix.org) and Slide, Inc. */ package org.flex_pilot { - import org.flex_pilot.FlexPilot; - import org.flex_pilot.FPLocator; - import org.flex_pilot.FPLogger; - import org.flex_pilot.FPRecorder; - import flash.display.Stage; import flash.display.Sprite; + import flash.display.Stage; import flash.events.MouseEvent; + import flash.external.ExternalInterface; import flash.geom.Point; import flash.geom.Rectangle; - import flash.external.ExternalInterface; + + import org.flex_pilot.FPLocator; + import org.flex_pilot.FPLogger; + import org.flex_pilot.FPRecorder; + import org.flex_pilot.FlexPilot; public class FPExplorer { // Sprite which gets superimposed on the moused-over element @@ -88,8 +89,14 @@ package org.flex_pilot { public static function select(e:MouseEvent):void { var targ:* = e.target; if ('name' in targ && targ.name == 'flex_pilotBorderSprite') { - return; + //trace("return on name = 'flex_pilotBorderSprite"); + return; } + //This is to minimize the number of automation borders that are shown in the app. + if ('showInAutomationHierarchy' in targ && targ["showInAutomationHierarchy"] == false) { + //trace("return on 'showInAutomationHierarchy"); + return; + } // Bordered sprite for highlighting var spr:Sprite = borderSprite; // Get the global coords of the moused-over elem @@ -118,7 +125,8 @@ package org.flex_pilot { } } else { - throw new Error('Could not find any usable attributes for locator.'); + //throw new Error('Could not find any usable attributes for locator.'); + //trace("Couldn't find any usuable attributes for locator"); } } diff --git a/src/org/flex_pilot/FPLocator.as b/src/org/flex_pilot/FPLocator.as index 440dca5..ccaa508 100644 --- a/src/org/flex_pilot/FPLocator.as +++ b/src/org/flex_pilot/FPLocator.as @@ -15,12 +15,18 @@ Copyright 2009, Matthew Eernisse (mde@fleegix.org) and Slide, Inc. */ package org.flex_pilot { - import org.flex_pilot.FlexPilot; - import org.flex_pilot.FPLogger; + import com.adobe.net.URI; + import flash.display.DisplayObject; import flash.display.DisplayObjectContainer; - import mx.core.IRawChildrenContainer; import flash.utils.*; + + import mx.core.IRawChildrenContainer; + + import org.flex_pilot.FPLogger; + import org.flex_pilot.FlexPilot; + import mx.managers.SystemManager; + import mx.core.IChildList; public class FPLocator { // Stupid AS3 doesn't iterate over Object keys @@ -63,7 +69,7 @@ package org.flex_pilot { params:Object):Boolean { var res:DisplayObject; - res = FPLocator.lookupDisplayObject(params, false); + res = FPLocator.lookupDisplayObject(params); if (res){ return true; } @@ -71,16 +77,12 @@ package org.flex_pilot { } public static function lookupDisplayObject( - params:Object, throwIfNotFound:Boolean = true):DisplayObject { + params:Object):DisplayObject { var res:DisplayObject; res = lookupDisplayObjectForContext(params, FlexPilot.getContext()); if (!res && FlexPilot.contextIsApplication()) { res = lookupDisplayObjectForContext(params, FlexPilot.getStage()); } - if (!res && throwIfNotFound) { - const chain:String = normalizeFPLocator(params); - throw new Error("The chain '" + chain +"' was not found."); - } return res; } @@ -94,7 +96,7 @@ package org.flex_pilot { item:*, pos:int):DisplayObject { var map:Object = FPLocator.locatorMapObj; var loc:Object = locators[pos]; - // If nothing specific exists for that attr, use the basic one + // If nothing specific exists for that attr, use the basic one var finder:Function = map[loc.attr] || FPLocator.findBySimpleAttr; var next:int = pos + 1; if (!!finder(item, loc.attr, loc.val)) { @@ -106,19 +108,22 @@ package org.flex_pilot { // Otherwise recursively check the next link in // the locator chain var count:int = 0; + var isRawChildContainer:Boolean = false; + //trace("-2-\\\\\\\\\checkFPLocatorChain\\\\\\\\\\\\\\\\\\\\\ -- item: " + item); if (item is DisplayObjectContainer) { - if (item is IRawChildrenContainer) { + count = item.numChildren; + //trace("\t\t -2- item is DisplayObjectContainer -- count: " + count); + if (count == 0 && item is IRawChildrenContainer) { count = item.rawChildren.numChildren; - } - else { - count = item.numChildren; + isRawChildContainer = true; + //trace("\t\t =2= item is IRawChildrenContainer -- count: " + count); } } if (count > 0) { var index:int = 0; while (index < count) { var kid:DisplayObject; - if (item is IRawChildrenContainer) { + if (isRawChildContainer && item is IRawChildrenContainer) { kid = item.rawChildren.getChildAt(index); } else { @@ -126,7 +131,8 @@ package org.flex_pilot { } var res:DisplayObject = checkFPLocatorChain(kid, next); if (res) { - return res; + //trace(":::::::: return res: " + res); + return res; } index++; } @@ -137,28 +143,42 @@ package org.flex_pilot { var str:String = normalizeFPLocator(params); locators = parseFPLocatorChainExpresson(str); + queue.push(obj); while (queue.length) { // Otherwise grab the next item in the queue var item:* = queue.shift(); + if (item is SystemManager) { + var popupList:IChildList = SystemManager(item).popUpChildren; + var numChildren:int = popupList.numChildren; + var child:Object; + for (var i:int=0; i