//////////////////////////////////////////////////////////////////////////////// // // Licensed to the Apache Software Foundation (ASF) under one or more // contributor license agreements. See the NOTICE file distributed with // this work for additional information regarding copyright ownership. // The ASF licenses this file to You under the Apache License, Version 2.0 // (the "License"); you may not use this file except in compliance with // the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // //////////////////////////////////////////////////////////////////////////////// package mx.automation { /** * The Flex automation framework uses the AutomationID class to build object identification * that Agents can use. AutomationID consists of many AutomationIDParts, where each part * identifies an object in the hierarchy. AutomationID defines a serialization format for * an Array of maps. You use this class to represent a hierarchy using segments that describe the properties of each object * within the hierarchy. * The serialize format of the id is: * *
property_1_name{property_1_value property_1_type}property_2_name{property_2_value property_2_type}|property_1_name{property_1_value property_1_type}property_2_name{property_2_value property_2_type}*
Consider a Flex application with following hierarchy: *
Application -- > Accordion -- > HBox -- > Button*
The AutomationID of the button would consist of four AutomationIDParts, one for application, * one for Accordion, one for HBox, and one for the Button. AutomationIDPart is a table of * property names and their values. The property-value pairs are different for different object types. * These property-value pairs should be usable to identify the object uniquely.
*AutomationID is created by walking the parent hierarchy of the leaf child object and creating
* the AutomationIDPart for each object encountered. Parents that have
* showInAutomationHierarchy
set to false
are skipped. Children of such
* parents are considered the children of the next higher
* parent whose showInAuto
flag is set to true
. During recording,
* this AutomationID can be saved by the agent.
During playback when Agent provides AutomationID for finding an object, the Display object
* hierarchy is walked from the top Application object downwards. At each level, a child that
* matches the AutomationIDPart closest is picked up from the list of all the children. If
* multiple children match the criteria, an error is thrown. Users are responsible to resolve
* such conflicts by providing a unique automationName
or identifying new properties on
* objects which make them unique.
Agents should save the object information if they desire persistence. AutomationID provides
* toString()
and parse()
methods to convert the object to a
* string representation and back.
You can use the IAutomationManager.createAutomationID()
and
* IAutomationManager.resolveAutomationID()
methods
* to create and resolve AutomationID objects, respectively.
You can use the IAutomationObjectHelper.helpCreateIDPart()
* and IAutomationObjectHelper.helpResolveIDPart()
methods
* to identify a child with in a parent which matches the AutomationIDPart.
toString()
method.
*
* @return Parsed id.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public static function parse(s:String):AutomationID
{
var result:AutomationID = new AutomationID();
var parts:Array = s.split("|");
for (var i:int = 0; i < parts.length; i++)
{
var part:AutomationIDPart = new AutomationIDPart();
result.addLast(part);
var x:Array = parts[i].split(/[\{\ \}]/);
for (var j:int = 0; (j+2) < x.length; j += 3)
{
part[decodeURI(x[j])] =
AutomationID.getValue(x[j + 2], decodeURI(x[j + 1]));
}
}
return result;
}
//--------------------------------------------------------------------------
//
// Constructor
//
//--------------------------------------------------------------------------
/**
* Constructor.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function AutomationID()
{
super();
}
//--------------------------------------------------------------------------
//
// Variables
//
//--------------------------------------------------------------------------
/**
* @private
*/
private var parts:Array = []; /* of AutomationIDPart */
//--------------------------------------------------------------------------
//
// Properties
//
//--------------------------------------------------------------------------
//----------------------------------
// length
//----------------------------------
/**
* The number of parts in this id.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function get length():int
{
return parts.length;
}
//--------------------------------------------------------------------------
//
// Methods
//
//--------------------------------------------------------------------------
/**
* Indicates if there are more parts of the id.
*
* @return true
if there are no more parts of the id,
* false
otherwise.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function isEmpty():Boolean
{
return parts.length == 0;
}
/**
* Returns the first object in the id
*
* @return First object in the id.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function peekFirst():AutomationIDPart
{
return parts[0] as AutomationIDPart;
}
/**
* Returns the last object in the id.
*
* @return Last object in the id.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function peekLast():AutomationIDPart
{
return parts[parts.length - 1] as AutomationIDPart;
}
/**
* Removes the first object from this id.
*
* @return First object in this id.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function removeFirst():AutomationIDPart
{
return parts.shift() as AutomationIDPart;
}
/**
* Removes the last object from this id.
*
* @return Last object in this id.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function removeLast():AutomationIDPart
{
return parts.pop() as AutomationIDPart;
}
/**
* Adds a parts to the end of the id.
*
* @param p Map of properties.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function addLast(p:AutomationIDPart):void
{
parts.push(p);
}
/**
* Adds a parts to the front of the id.
*
* @param p Map of properties.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function addFirst(p:AutomationIDPart):void
{
parts.unshift(p);
}
/**
* Concatenates another id to this id. Returns a new id,
* and does not mutate this instance.
*
* @param other id to concatenate.
*
* @return This id concatenated with the other id.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function concat(other:AutomationID):AutomationID
{
var newID:AutomationID = new AutomationID();
newID.parts = parts.concat(other.parts);
return newID;
}
/**
* @private
* Removes any properties from the maps within the id that
* match the names provided.
*/
public function stripProperties(names:Array):AutomationID
{
for (var i:int = 0; i < names.length; i++)
{
for (var j:int = 0; j < parts.length; j++)
{
if (names[i] in parts[j])
delete parts[j][names[i]];
}
}
return this;
}
/**
* Serializes the id to a string.
*
* @return The serialized id.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function toString():String
{
return parts.join("|");
}
/**
* @private
* Returns a duplicate object.
*/
public function clone():AutomationID
{
var result:AutomationID = new AutomationID();
for (var i:int = 0; i < parts.length; i++)
{
result.parts[i] = new AutomationIDPart();
for (var j:Object in parts[i])
{
result.parts[i][j] = parts[i][j];
}
}
return result;
}
/**
* Compares this object with the given AutomationID.
*
* @param other AutomationID object which needs to be compared.
*
* @return true
if they are equal, false
otherwise.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function equals(other:AutomationID):Boolean
{
if (parts.length != other.parts.length)
return false;
for (var i:int = 0; i < parts.length; i++)
{
for (var j:Object in parts[i])
{
if (!(j in other.parts[i] && (parts[i][j] == other.parts[i][j])))
return false;
}
}
return true;
}
}
}