| //////////////////////////////////////////////////////////////////////////////// |
| // |
| // 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.tool |
| { |
| |
| import flash.display.DisplayObject; |
| import flash.events.Event; |
| import flash.events.IEventDispatcher; |
| import flash.events.TimerEvent; |
| import flash.geom.Point; |
| import flash.utils.Timer; |
| import flash.utils.getQualifiedClassName; |
| |
| import mx.automation.Automation; |
| import mx.automation.AutomationClass; |
| import mx.automation.AutomationConstants; |
| import mx.automation.AutomationError; |
| import mx.automation.AutomationHelper; |
| import mx.automation.AutomationID; |
| import mx.automation.AutomationIDPart; |
| import mx.automation.IAutomationClass; |
| import mx.automation.IAutomationEventDescriptor; |
| import mx.automation.IAutomationManager2; |
| import mx.automation.IAutomationMethodDescriptor; |
| import mx.automation.IAutomationObject; |
| import mx.automation.IAutomationPropertyDescriptor; |
| import mx.automation.IAutomationTabularData; |
| import mx.automation.codec.AdvancedDataGridSelectedCellCodec; |
| import mx.automation.codec.ArrayPropertyCodec; |
| import mx.automation.codec.AssetPropertyCodec; |
| import mx.automation.codec.AutomationObjectPropertyCodec; |
| import mx.automation.codec.ChartItemCodec; |
| import mx.automation.codec.ColorPropertyCodec; |
| import mx.automation.codec.DatePropertyCodec; |
| import mx.automation.codec.DateRangePropertyCodec; |
| import mx.automation.codec.DateScrollDetailPropertyCodec; |
| import mx.automation.codec.DefaultPropertyCodec; |
| import mx.automation.codec.FilePropertyCodec; |
| import mx.automation.codec.HitDataCodec; |
| import mx.automation.codec.IAutomationPropertyCodec; |
| import mx.automation.codec.KeyCodePropertyCodec; |
| import mx.automation.codec.KeyModifierPropertyCodec; |
| import mx.automation.codec.ListDataObjectCodec; |
| import mx.automation.codec.RendererPropertyCodec; |
| import mx.automation.codec.ScrollDetailPropertyCodec; |
| import mx.automation.codec.ScrollDirectionPropertyCodec; |
| import mx.automation.codec.TabObjectCodec; |
| import mx.automation.codec.TriggerEventPropertyCodec; |
| import mx.automation.events.AutomationAirEvent; |
| import mx.automation.events.AutomationCustomReplayEvent; |
| import mx.automation.events.AutomationRecordEvent; |
| import mx.automation.events.EventDetails; |
| import mx.controls.Alert; |
| import mx.controls.Image; |
| import mx.controls.SWFLoader; |
| import mx.core.EventPriority; |
| import mx.core.FlexGlobals; |
| import mx.core.mx_internal; |
| import mx.managers.IMarshalSystemManager; |
| import mx.managers.ISystemManager; |
| import mx.managers.PopUpManager; |
| import mx.managers.SystemManager; |
| import mx.resources.IResourceManager; |
| import mx.resources.ResourceManager; |
| |
| import spark.automation.codec.SparkDropDownListBaseSelectedItemCodec; |
| |
| use namespace mx_internal; |
| |
| [ResourceBundle("automation_agent")] |
| [ResourceBundle("tool_air")] |
| |
| /** |
| * @private |
| */ |
| public class ToolAdapter implements IToolCodecHelper |
| { |
| include "../../core/Version.as"; |
| |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Class constants |
| // |
| //-------------------------------------------------------------------------- |
| |
| /** |
| * Captures all properties of all objects in the application's active |
| * window/dialog box/Web page in the Active Screen of each step. |
| * This means that all objects can be added to object repository / |
| * added checkpoints, etc. |
| * @private |
| */ |
| public static const COMPLETE:uint = 0; |
| |
| /** |
| * (Default). Captures all properties of all objects in the application's |
| * active window/dialog box/Web page in the Active Screen of the first |
| * step performed in an application's window, plus all properties |
| * of the recorded object in subsequent steps in the same window |
| * (it is an optimization of Complete mode). |
| * As in Complete mode, in this mode, all objects can be added to object |
| * repository / added checkpoints, etc. |
| * @private |
| */ |
| public static const PARTIAL:uint = 1; |
| |
| /** |
| * Captures properties only for the recorded object and its parent in the |
| * Active Screen of each step. |
| * This means that only the recorded objects and its parents can be added |
| * to object repository / added checkpoints, etc. |
| * @private |
| */ |
| public static const MINIMUM:uint = 2; |
| |
| /** |
| * Disables capturing of Active Screen files for all applications |
| * and Web pages. |
| * This means no Active Screen will be shown. |
| * @private |
| */ |
| public static const NONE:uint = 3; |
| |
| |
| // indicates what type of application is being automation currently. |
| /** |
| * @private |
| */ |
| public static const ApplicationType_Flex:int = 0; |
| /** |
| * @private |
| */ |
| public static const ApplicationType_AIR:int = 1; |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Class variables |
| // |
| //-------------------------------------------------------------------------- |
| |
| /** |
| * @private |
| */ |
| private static var isInitialized:Boolean = false; |
| |
| /** |
| * @private |
| */ |
| private static var qtpCodecHelper:IToolCodecHelper; |
| |
| |
| /** |
| * @private |
| */ |
| public static var _applicationType:int = -1; |
| |
| /** |
| * @private |
| */ |
| public static var _applicationId:String; |
| |
| /** |
| * @private |
| */ |
| //private var sandboxRoot:IEventDispatcher; |
| |
| |
| /** |
| * @private |
| * The highest place we can listen for events in our DOM |
| */ |
| private static var mainListenerObj:IEventDispatcher; |
| |
| |
| /** |
| * @private |
| */ |
| private var lastApplicationName:String; |
| |
| /** |
| * @private |
| */ |
| private var lastRequestName:String; |
| |
| |
| /** |
| * @private |
| */ |
| private var requestPending:Boolean; |
| |
| |
| /** |
| * @private |
| */ |
| private var requestResultObjArray:Array; |
| |
| /** |
| * @private |
| */ |
| private var resultRecieved:Boolean; |
| |
| /** |
| * @private |
| */ |
| private var sm:ISystemManager; |
| |
| /** |
| * @private |
| */ |
| // private var _smMSm:IMarshalSystemManager; |
| |
| /* |
| public function get smMSm():IMarshalSystemManager |
| { |
| if(!_smMSm) |
| _smMSm = IMarshalSystemManager(sm.getImplementation("mx.managers::IMarshalSystemManager")); |
| |
| return _smMSm; |
| } |
| */ |
| //-------------------------------------------------------------------------- |
| // |
| // Constructor |
| // |
| //-------------------------------------------------------------------------- |
| |
| /** |
| * Constructor |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 4 |
| */ |
| public function ToolAdapter() |
| { |
| super(); |
| sm = FlexGlobals.topLevelApplication.systemManager; |
| //smMSm = sm as IMarshalSystemManager; |
| //_smMSm = IMarshalSystemManager((FlexGlobals.topLevelApplication.systemManager as SystemManager).getImplementation("max.manager::IMarshalSystemManager")); |
| //_smMSm = IMarshalSystemManager((Automation.getMainApplication().systemManager as SystemManager).getImplementation("max.manager::IMarshalSystemManager")); |
| // working line _smMSm = IMarshalSystemManager(sm.getImplementation("mx.managers::IMarshalSystemManager")); |
| |
| |
| // the following code is to take care of Marshalling in Automation |
| // we need to handle all the methods which can reach Tool (which will be a part of |
| // main applicaiton. We need to send the information about this function call to other applications. |
| //sandboxRoot = sm.getSandboxRoot(); |
| |
| // these events are coming from the main application and the children are listening to the main application |
| if(sm.isTopLevelRoot() == false) |
| { |
| var eventDetailsToListenFromParent:Array = new Array(); |
| eventDetailsToListenFromParent.push(new EventDetails(ToolMarshallingEvent.FIND_OBJECTIDS, |
| interAppRequestHandler)); |
| eventDetailsToListenFromParent.push(new EventDetails(ToolMarshallingEvent.RUN, |
| interAppRequestHandler)); |
| eventDetailsToListenFromParent.push(new EventDetails(ToolMarshallingEvent.GET_ACTIVESCREEN, |
| interAppRequestHandler)); |
| eventDetailsToListenFromParent.push(new EventDetails(ToolMarshallingEvent.GET_PARENT, |
| interAppRequestHandler)); |
| eventDetailsToListenFromParent.push(new EventDetails(ToolMarshallingEvent.GET_RECTANGLE, |
| interAppRequestHandler)); |
| eventDetailsToListenFromParent.push(new EventDetails(ToolMarshallingEvent.GET_ELEMENT_FROM_POINT, |
| interAppRequestHandler)); |
| eventDetailsToListenFromParent.push(new EventDetails(ToolMarshallingEvent.GET_ELEMENT_TYPE, |
| interAppRequestHandler)); |
| eventDetailsToListenFromParent.push(new EventDetails(ToolMarshallingEvent.GET_DISPLAY_NAME, |
| interAppRequestHandler)); |
| eventDetailsToListenFromParent.push(new EventDetails(ToolMarshallingEvent.GET_PROPERTIES, |
| interAppRequestHandler)); |
| eventDetailsToListenFromParent.push(new EventDetails(ToolMarshallingEvent.BUILD_DESCRIPTION, |
| interAppRequestHandler)); |
| eventDetailsToListenFromParent.push(new EventDetails(ToolMarshallingEvent.GET_CHILDREN, |
| interAppRequestHandler)); |
| eventDetailsToListenFromParent.push(new EventDetails(ToolMarshallingEvent.LEARN_CHILD_OBJECTS, |
| interAppRequestHandler)); |
| eventDetailsToListenFromParent.push(new EventDetails(ToolMarshallingEvent.GET_LAST_ERROR, |
| interAppRequestHandler)); |
| eventDetailsToListenFromParent.push(new EventDetails(ToolMarshallingEvent.SET_LAST_ERROR, |
| interAppRequestHandler)); |
| eventDetailsToListenFromParent.push(new EventDetails(ToolMarshallingEvent.GET_TABULAR_ATTRIBUTES, |
| interAppRequestHandler)); |
| eventDetailsToListenFromParent.push(new EventDetails(ToolMarshallingEvent.GET_TABULAR_DATA, |
| interAppRequestHandler)); |
| |
| automationManager.addEventListenersToAllParentApplications(eventDetailsToListenFromParent); |
| //addEventListenersToAllParentApplications(eventDetailsToListenFromParent); |
| } |
| |
| |
| |
| |
| var eventDetailsToListenFromChildren:Array = new Array(); |
| eventDetailsToListenFromChildren.push(new EventDetails(ToolMarshallingEvent.FIND_OBJECTIDS_REPLY, |
| interAppReplyHandler)); |
| eventDetailsToListenFromChildren.push(new EventDetails(ToolMarshallingEvent.RUN_REPLY, |
| interAppReplyHandler)); |
| eventDetailsToListenFromChildren.push(new EventDetails(ToolMarshallingEvent.GET_ACTIVESCREEN_REPLY, |
| interAppReplyHandler)); |
| eventDetailsToListenFromChildren.push(new EventDetails(ToolMarshallingEvent.GET_PARENT_REPLY, |
| interAppReplyHandler)); |
| eventDetailsToListenFromChildren.push(new EventDetails(ToolMarshallingEvent.GET_RECTANGLE_REPLY, |
| interAppReplyHandler)); |
| eventDetailsToListenFromChildren.push(new EventDetails(ToolMarshallingEvent.GET_ELEMENT_FROM_POINT_REPLY, |
| interAppReplyHandler)); |
| eventDetailsToListenFromChildren.push(new EventDetails(ToolMarshallingEvent.GET_ELEMENT_TYPE_REPLY, |
| interAppReplyHandler)); |
| eventDetailsToListenFromChildren.push(new EventDetails(ToolMarshallingEvent.GET_DISPLAY_NAME_REPLY, |
| interAppReplyHandler)); |
| eventDetailsToListenFromChildren.push(new EventDetails(ToolMarshallingEvent.GET_PROPERTIES_REPLY, |
| interAppReplyHandler)); |
| eventDetailsToListenFromChildren.push(new EventDetails(ToolMarshallingEvent.BUILD_DESCRIPTION_REPLY, |
| interAppReplyHandler)); |
| eventDetailsToListenFromChildren.push(new EventDetails(ToolMarshallingEvent.GET_CHILDREN_REPLY, |
| interAppReplyHandler)); |
| eventDetailsToListenFromChildren.push(new EventDetails(ToolMarshallingEvent.LEARN_CHILD_OBJECTS_REPLY, |
| interAppReplyHandler)); |
| eventDetailsToListenFromChildren.push(new EventDetails(ToolMarshallingEvent.GET_LAST_ERROR_REPLY, |
| interAppReplyHandler)); |
| eventDetailsToListenFromChildren.push(new EventDetails(ToolMarshallingEvent.GET_TABULAR_ATTRIBUTES_REPLY, |
| interAppReplyHandler)); |
| eventDetailsToListenFromChildren.push(new EventDetails(ToolMarshallingEvent.GET_TABULAR_DATA_REPLY, |
| interAppReplyHandler)); |
| eventDetailsToListenFromChildren.push(new EventDetails(ToolMarshallingEvent.RECORD, |
| marhsalledRecordHandler)); |
| |
| automationManager.addEventListenersToAllChildApplications(eventDetailsToListenFromChildren); |
| |
| automationManager.addEventListener(AutomationRecordEvent.RECORD,recordHandler, false, EventPriority.DEFAULT_HANDLER, true); |
| automationManager.addEventListener(AutomationAirEvent.NEW_AIR_WINDOW,newWindowHandler); |
| |
| if (!isInitialized) |
| { |
| isInitialized = true; |
| |
| qtpCodecHelper = this; |
| |
| // Add the default serializers. |
| addPropertyCodec( |
| "object", new DefaultPropertyCodec()); |
| |
| addPropertyCodec( |
| "keyCode", new KeyCodePropertyCodec()); |
| |
| addPropertyCodec( |
| "keyModifier", new KeyModifierPropertyCodec()); |
| |
| addPropertyCodec( |
| "object[]", new ArrayPropertyCodec(new DefaultPropertyCodec())); |
| |
| addPropertyCodec( |
| "color", new ColorPropertyCodec()); |
| |
| addPropertyCodec( |
| "color[]", new ArrayPropertyCodec(new ColorPropertyCodec())); |
| |
| addPropertyCodec( |
| "automationObject", new AutomationObjectPropertyCodec()); |
| |
| addPropertyCodec( |
| "automationObject[]", |
| new ArrayPropertyCodec(new AutomationObjectPropertyCodec())); |
| |
| addPropertyCodec( |
| "asset", new AssetPropertyCodec()); |
| |
| addPropertyCodec( |
| "asset[]", new ArrayPropertyCodec(new AssetPropertyCodec())); |
| |
| addPropertyCodec( |
| "listDataObject", new ListDataObjectCodec()); |
| |
| addPropertyCodec( |
| "listDataObject[]", |
| new ArrayPropertyCodec(new ListDataObjectCodec())); |
| |
| addPropertyCodec( |
| "rendererObject", new RendererPropertyCodec()); |
| |
| addPropertyCodec( |
| "dateRange", new DateRangePropertyCodec()); |
| |
| addPropertyCodec( |
| "dateObject", new DatePropertyCodec()); |
| |
| addPropertyCodec( |
| "dateRange[]", |
| new ArrayPropertyCodec(new DateRangePropertyCodec())); |
| |
| addPropertyCodec( |
| "event", new TriggerEventPropertyCodec()); |
| |
| addPropertyCodec( |
| "tab", new TabObjectCodec()); |
| |
| addPropertyCodec( |
| "scrollDetail", new ScrollDetailPropertyCodec()); |
| |
| addPropertyCodec( |
| "dateScrollDetail", new DateScrollDetailPropertyCodec()); |
| |
| addPropertyCodec( |
| "scrollDirection", new ScrollDirectionPropertyCodec()); |
| |
| addPropertyCodec( |
| "AdvancedDataGridSelectedCell[]", new ArrayPropertyCodec(new AdvancedDataGridSelectedCellCodec())); |
| |
| addPropertyCodec( |
| "ChartItemCodec", new ChartItemCodec()); |
| |
| addPropertyCodec( |
| "ChartItemCodec[]", new ArrayPropertyCodec(new ChartItemCodec())); |
| |
| addPropertyCodec( |
| "hitDataCodec[]", new ArrayPropertyCodec(new HitDataCodec())); |
| |
| addPropertyCodec( |
| "fileCodec", new FilePropertyCodec()); |
| |
| addPropertyCodec( |
| "SparkDropDownListBaseSelectedItem", new SparkDropDownListBaseSelectedItemCodec()); |
| |
| |
| /* |
| This portion of the code is removed to make the automation_dmv source compilable in Flex Builder source. |
| |
| Why this code was used : |
| To make the application which does not need the datavisuaalisation components, not including these codes |
| The required codecs were supposed to be present in the automation_dmv swc and hence only if the user |
| provides this swc, these classes would have been loaded. |
| But to make these classes under the automation_dmv , we bring the dependancy of qtp and automation source |
| as the codecs use IToolProper.... class. Hence we cannot compile them independantly |
| |
| try |
| { |
| // check for availability of chart codec. |
| // it may not be available if user has not included chart delegates |
| var codec:Object = getDefinitionByName("mx.automation.codec.HitDataCodec"); |
| |
| addPropertyCodec( |
| "hitDataCodec[]", new ArrayPropertyCodec(new codec())); |
| } |
| catch(e:Error) |
| { |
| } |
| */ |
| |
| var message:String; |
| /* |
| |
| |
| if (Capabilities.playerType != "ActiveX") |
| { |
| message = resourceManager.getString( |
| "automation_agent", "notActiveX"); |
| trace(message); |
| return; |
| } |
| |
| if (! Capabilities.os.match(/^Windows/)) |
| { |
| message = resourceManager.getString( |
| "automation_agent", "notWindows", [Capabilities.os]); |
| trace(message); |
| return; |
| } |
| |
| if (!ExternalInterface.available) |
| { |
| message = resourceManager.getString( |
| "automation_agent", "noExternalInterface"); |
| trace(message); |
| return; |
| } |
| |
| if (!playerID || playerID.length == 0) |
| { |
| message = resourceManager.getString( |
| "automation_agent", "noPlayerID"); |
| trace(message); |
| return; |
| } |
| |
| if (playerID.match(/[\.-]/)) |
| { |
| message = resourceManager.getString( |
| "automation_agent", "invalidPlayerID", [playerID]); |
| trace(message); |
| return; |
| } |
| */ |
| |
| try |
| { |
| //ToolAgent.initSocket(); |
| //beginRecording(); |
| |
| /* |
| // for js driver |
| ExternalInterface.addCallback("SetTestingEnvironment", |
| setTestingEnvironment); |
| |
| // Add QTP callbacks |
| ExternalInterface.addCallback("GetParent", getParent); |
| ExternalInterface.addCallback("GetChildren", getChildren); |
| ExternalInterface.addCallback("BuildDescription", buildDescription); |
| ExternalInterface.addCallback("FindObjectId", findObjectID); |
| ExternalInterface.addCallback("FindObjectId2", findObjectIDs); |
| ExternalInterface.addCallback("GetDisplayName", getDisplayName); |
| ExternalInterface.addCallback("GetElementType", getElementType); |
| ExternalInterface.addCallback("GetProperties", getProperties); |
| ExternalInterface.addCallback("GetTabularData", getTabularData); |
| ExternalInterface.addCallback("GetTabularAttributes", |
| getTabularAttributes); |
| ExternalInterface.addCallback("Run", run); |
| ExternalInterface.addCallback("GetLastError", getLastError); |
| ExternalInterface.addCallback("SetLastError", setLastError); |
| ExternalInterface.addCallback("BeginRecording", beginRecording); |
| ExternalInterface.addCallback("EndRecording", endRecording); |
| ExternalInterface.addCallback("GetElementFromPoint", |
| getElementFromPoint); |
| ExternalInterface.addCallback("GetRectangle", getRectangle); |
| ExternalInterface.addCallback("GetActiveScreen", getActiveScreen); |
| ExternalInterface.addCallback("LearnChildObjects", learnChildObjects); |
| |
| // Register ActiveX plugin |
| ExternalInterface.call("eval", |
| "try { window._mx_testing_plugin_" + playerID + |
| " = new ActiveXObject('TEAPluginIE.TEAFlexAgentIE'); }" + |
| "catch(e) { document.getElementById('" + playerID + |
| "').SetLastError(e.message); } "); |
| |
| if (lastError) |
| { |
| message = resourceManager.getString( |
| "automation_agent", "unableToLoadPluginGeneric", |
| [lastError.message]); |
| trace(message); |
| return; |
| } |
| |
| ExternalInterface.call("eval", |
| "if (!window._mx_testing_plugin_" + playerID + |
| ".RegisterPluginWithQTP(self, " + "'" + playerID + "')) {" + |
| "document.getElementById('" + playerID + |
| "').SetLastError('TEAPluginIE.TEAFlexAgentIE is not scriptable'); }"); |
| |
| if (lastError) |
| { |
| message = resourceManager.getString( |
| "automation_agent", "unableToLoadPluginGeneric", |
| [lastError.message]); |
| trace(message); |
| return; |
| } |
| |
| // Load environment XML |
| var te:String = ExternalInterface.call("window._mx_testing_plugin_" + |
| playerID + |
| ".GetTestingEnvironment"); |
| setTestingEnvironment(te); |
| */ |
| |
| } |
| catch (se:SecurityError) |
| { |
| message = resourceManager.getString( |
| "automation_agent", "unableToLoadPluginGeneric", |
| [se.message]); |
| Automation.automationDebugTracer.traceMessage("ToolAdapter","ToolAdapter()",message); |
| } |
| } |
| } |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Variables |
| // |
| //-------------------------------------------------------------------------- |
| |
| /** |
| * @private |
| */ |
| private var lastError:Error; |
| |
| /** |
| * @private |
| */ |
| private var propertyCodecMap:Object = []; |
| |
| /** |
| * @private |
| * Used for accessing localized Error messages. |
| */ |
| private static var resourceManager:IResourceManager = |
| ResourceManager.getInstance(); |
| |
| /** |
| * @private |
| * Used for accessing localized Error messages. |
| */ |
| private var detailsSentToTool :Boolean = false; |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Properties |
| // |
| //-------------------------------------------------------------------------- |
| |
| //---------------------------------- |
| // automationManager |
| //---------------------------------- |
| |
| /** |
| * @private |
| */ |
| private function get automationManager():IAutomationManager2 |
| { |
| //return Automation.automationManager ; |
| return Automation.automationManager2 as IAutomationManager2; |
| } |
| |
| //---------------------------------- |
| // playerID |
| //---------------------------------- |
| |
| /** |
| * @private |
| */ |
| private function get playerID():String |
| { |
| return FlexGlobals.topLevelApplication.id; |
| } |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Methods |
| // |
| //-------------------------------------------------------------------------- |
| |
| /** |
| * @private |
| * Registers a custom codec to encoding an decoding of object properties and |
| * event properties to and from a testing tool. For example, ColorPicker |
| * events can contain the selected color. A special color codec is provided |
| * to encode and decode colors from their native number format to hex. |
| * |
| * Predefined codecs include: |
| * "" - The default codec that supports basic types such as String, Number, int and uint. |
| * "color" - Converts a number to hex. |
| * "keyCode" - Converts a keyCode number to a human readable string |
| * "keyState" - Converts ctrlKey, shiftKey and altKey booleans to a human |
| * readable bitfield string. |
| * "skin" - Converts a skin asset class name to closely resemble it's |
| * original asset name. Path separators and periods in the orignal |
| * path name will be converted to underscores. This is only available |
| * on readonly properties. |
| * "automationObject" - Converts an object to it's automationName. |
| * |
| * @param codecName the name of the codec. |
| * |
| * @param codec the implementation of the codec. |
| */ |
| private function addPropertyCodec(codecName:String, codec:IAutomationPropertyCodec):void |
| { |
| propertyCodecMap[codecName] = codec; |
| } |
| |
| |
| /** |
| * @private |
| */ |
| public function setTestingEnvironment(te:String):void |
| { |
| //trace (te); |
| automationManager.automationEnvironment = new ToolEnvironment(new XML(te)); |
| |
| // For supportig Marshalling we need the env information as string and |
| // the name of the class which interprets the information |
| // this information will be used by the Automation Manger in each of the AppDomain |
| // to intialise the class with the details. |
| // #IMP: MARSHALLING NOTE#: The name of the class needs to be maintained across versions |
| // However the implementation of the class can be different in each version. |
| automationManager.automationEnvironmentString = te; |
| automationManager.automationEnvironmentHandlingClassName = "mx.automation.tool.ToolEnvironment"; |
| } |
| |
| /** |
| * Encodes a single value to a testing tool value. Unlike encodeProperties which |
| * takes an object which contains all the properties to encode, this method |
| * takes the actual value to encode. This is useful for encoding return values. |
| * |
| * @param obj the value to be encoded. |
| * |
| * @param propertyDescriptor the property descriptor that describes this value. |
| * |
| * @param relativeParent the IAutomationObject that is related to this value. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 4 |
| */ |
| public function encodeValue(value:Object, |
| testingToolType:String, |
| codecName:String, |
| relativeParent:IAutomationObject):Object |
| { |
| //setup a fake descriptor and object to send to the codec |
| var pd:ToolPropertyDescriptor = |
| new ToolPropertyDescriptor("value", |
| false, |
| false, |
| testingToolType, |
| codecName); |
| var obj:Object = {value:value}; |
| return getPropertyValue(obj, pd, relativeParent); |
| } |
| |
| |
| public function getPropertyValue(obj:Object, |
| pd:ToolPropertyDescriptor, |
| relativeParent:IAutomationObject = null):Object |
| { |
| var codec:IAutomationPropertyCodec = propertyCodecMap[pd.codecName]; |
| |
| if (codec == null) |
| codec = propertyCodecMap["object"]; |
| |
| if (relativeParent == null) |
| relativeParent = obj as IAutomationObject; |
| |
| return codec.encode(automationManager, obj, pd, relativeParent); |
| } |
| |
| /** |
| * Encodes properties in an AS object to an array of values for a testing tool |
| * using the codecs. Since the object being passed in may not be an IAutomationObject |
| * (it could be an event class) and some of the properties require the |
| * IAutomationObject to be transcoded (such as the item renderers in |
| * a list event), relativeParent should always be set to the relevant |
| * IAutomationObject. |
| * |
| * @param obj the object that contains the properties to be encoded. |
| * |
| * @param propertyDescriptors the property descriptors that describes the properties for this object. |
| * |
| * @param relativeParent the IAutomationObject that is related to this object. |
| * |
| * @return the encoded property value. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 4 |
| */ |
| public function encodeProperties(obj:Object, |
| propertyDescriptors:Array, |
| interactionReplayer:IAutomationObject):Array |
| { |
| var result:Array = []; |
| var consecutiveDefaultValueCount:Number = 0; |
| for (var i:int = 0; i < propertyDescriptors.length; i++) |
| { |
| var val:Object = getPropertyValue(obj, |
| propertyDescriptors[i], |
| interactionReplayer); |
| |
| var isDefaultValueNull:Boolean = propertyDescriptors[i].defaultValue == "null"; |
| |
| consecutiveDefaultValueCount = (!(val == null && isDefaultValueNull) && |
| (propertyDescriptors[i].defaultValue == null || |
| val == null || |
| propertyDescriptors[i].defaultValue != val.toString()) |
| ? 0 |
| : consecutiveDefaultValueCount + 1); |
| |
| result.push(val); |
| } |
| |
| result.splice(result.length - consecutiveDefaultValueCount, |
| consecutiveDefaultValueCount); |
| |
| return result; |
| } |
| |
| |
| |
| /** |
| * @private |
| */ |
| private function getValuesWithTypeInformation(elemetnsArray:Array):Array |
| { |
| var count:int = elemetnsArray.length; |
| var index:int = 0; |
| |
| var currentArgsArray:Array= new Array(); |
| |
| while(index < count) |
| { |
| var currentObject:Object = elemetnsArray[index]; |
| var currentObjectType:String = getQualifiedClassName(currentObject); |
| |
| var currentobjString:String; |
| if(currentObject == null) |
| currentobjString = ClientSocketHandler.nullValueIndicator; |
| else |
| currentobjString = currentObject.toString(); |
| |
| var currentArgString:String = currentObjectType+ ClientSocketHandler.typeValueSeparator + currentobjString; |
| currentArgsArray.push(currentArgString); |
| |
| index++; |
| } |
| |
| return currentArgsArray; |
| } |
| |
| /** |
| * @private |
| */ |
| private function handleIncompleteRecord(event:Event):void |
| { |
| if (!automationManager.isSynchronized(null)) |
| { |
| var myTimer:Timer = new Timer(1000,1); |
| myTimer.addEventListener("timer", handleIncompleteRecord); |
| myTimer.start(); |
| } |
| else |
| { |
| |
| var objectId2Object:Object = findObjectIDs(currentDescriptionXMLString); |
| var objectId2Array:Array = (objectId2Object["result"] as Array); |
| var objectId2String:String =""; |
| if(objectId2Array) |
| { |
| var completeString:String; |
| objectId2String = objectId2Array.join(ClientSocketHandler.objectIdSeparators); |
| objectId2String = objectId2Array.join(ClientSocketHandler.objectIdSeparators); |
| completeString = recordInfoString+ objectId2String + ClientSocketHandler.recordInfoSeparator; |
| |
| var request1:RequestData = new RequestData(); |
| request1.requestID = ClientSocketHandler.activeScreenDataStoreRequestString; |
| request1.requestData = activeScreenString; |
| |
| var request2:RequestData = new RequestData(); |
| request2.requestID = ClientSocketHandler.recordRequestString; |
| request2.requestData = completeString; |
| |
| if(sm.isTopLevelRoot() == false) |
| { |
| // send the event to the root applicaiton and let it take care of the socket communication. |
| var marshalledEvent:ToolMarshallingEvent = new ToolMarshallingEvent( |
| ToolMarshallingEvent.RECORD); |
| |
| // #IMP: MARSHALLING NOTE#: This order of ariguments should not be changed |
| // across versions. If any new arguements is needed in new versions |
| // add them to the end of the list and handle appropriately in the |
| // handler of this event. |
| var recordDetails:Array = new Array(); |
| recordDetails.push(request1); |
| recordDetails.push(request2); |
| marshalledEvent.interAppDataToMainApp = recordDetails; |
| |
| dispatchEventToParent(marshalledEvent); |
| |
| } |
| else |
| { |
| if(ToolAgent.clientSocketHandler) |
| { |
| (ToolAgent.clientSocketHandler).addToRecordRequestQueue(request1); |
| (ToolAgent.clientSocketHandler).addToRecordRequestQueue(request2); |
| |
| //trace ("calling processQueuedRecordRequests ToolAgent"); |
| (ToolAgent.clientSocketHandler).processQueuedRecordRequests(true); |
| } |
| } |
| /* |
| Application.application.alpha= appAlpha; |
| Application.application.enabled = true; */ |
| ClientSocketHandler.enableApplication(); |
| } |
| } |
| } |
| |
| private var recordInfoString:String; |
| private var activeScreenString:String; |
| private var currentDescriptionXMLString:String; |
| private var appAlpha:int = -1; |
| private function recordHandler(event:AutomationRecordEvent):void |
| { |
| if(event.isDefaultPrevented()) |
| return; |
| |
| automationManager.incrementCacheCounter(); |
| |
| try |
| { |
| var obj:IAutomationObject = event.automationObject ; |
| var rid:AutomationID = automationManager.createID(obj); |
| var descriptionXML:XML = getDescriptionXML(rid, obj); |
| |
| // We are storing the actual pretty printing value so that we can |
| // reset it back when we are done with our operation. |
| // Ref: http://bugs.adobe.com/jira/browse/FLEXENT-1140 |
| var actualPrettyPrinting:Boolean = XML.prettyPrinting; |
| |
| XML.prettyPrinting = false; |
| var parentRids:Array = []; |
| |
| while (obj) |
| { |
| rid = automationManager.createID(obj); |
| parentRids.push(rid.toString()); |
| obj = automationManager.getParent(obj); |
| } |
| |
| // the last rid corresponds to the highest parent |
| // get the window id for this obejct |
| // clone the automationID |
| var rid1:AutomationID = rid.clone(); |
| //get the first part |
| var objectIdPart:AutomationIDPart = rid1.removeFirst(); |
| var windowId:String = automationManager.getAIRWindowUniqueIDFromAutomationIDPart(objectIdPart); |
| |
| |
| var completeString:String = parentRids.join(":|:"); |
| completeString=completeString.concat(ClientSocketHandler.recordInfoSeparator,descriptionXML.toXMLString(),ClientSocketHandler.recordInfoSeparator,event.name); |
| // now we have parentRids | descriptionXML | event name in the complete string |
| |
| |
| // for the argument arrays |
| var argsArray:Array = event.args as Array; |
| if(argsArray) |
| { |
| var argLength:int = argsArray.length; |
| |
| if(argLength != 0) |
| { |
| var argString :String = (getValuesWithTypeInformation(event.args as Array)).join(ClientSocketHandler.eventArgsSeparator) ; |
| //completeString=completeString.concat(ClientSocketHandler.recordInfoSeparator,event.args.join(ClientSocketHandler.eventArgsSeparator),ClientSocketHandler.recordInfoSeparator); |
| completeString=completeString.concat(ClientSocketHandler.recordInfoSeparator,argString,ClientSocketHandler.recordInfoSeparator); |
| |
| } |
| else |
| completeString=completeString.concat(ClientSocketHandler.recordInfoSeparator,ClientSocketHandler.recordNoArgIndicator,ClientSocketHandler.recordInfoSeparator); |
| } |
| else |
| completeString=completeString.concat(ClientSocketHandler.recordInfoSeparator,ClientSocketHandler.recordNoArgIndicator,ClientSocketHandler.recordInfoSeparator); |
| // now we have the argument details also in the complete string |
| |
| |
| // get the active screen details |
| // before sending the record details , capture the active screen details and send |
| // for the time being we dont have the player coordinates in screen coordinates |
| // we need the top offset and left offset of the player |
| |
| // we need the stage start points |
| |
| //get the point for sub apps using automation manager's API, that returns main |
| //air app's start point. Retuns null if this is main air app |
| var stageStartCoordinate:Point = automationManager.getStartPointInScreenCoordinates(windowId); |
| |
| if(!stageStartCoordinate) //null if this is main air app |
| stageStartCoordinate = getStageStartPointInScreenCoords(windowId); |
| |
| if(!stageStartCoordinate) |
| stageStartCoordinate = new Point(0,0); |
| |
| // we would have got the message for this. so the user is not expected to proceed. |
| // the above is done to avoid the null obejct access. |
| |
| |
| var resultObj:Object = getActiveScreen(0,parentRids[0],stageStartCoordinate.x,stageStartCoordinate.y); |
| // var activeScreenData:String = resultObj.result; |
| activeScreenString = resultObj.result; |
| |
| // calculate object ID string |
| var objectId2Object:Object = findObjectIDs(descriptionXML.toXMLString()); |
| var objectId2Array:Array = (objectId2Object["result"] as Array); |
| var objectId2String:String =""; |
| if(objectId2Array) |
| { |
| objectId2String = objectId2Array.join(ClientSocketHandler.objectIdSeparators); |
| completeString = completeString+ objectId2String + ClientSocketHandler.recordInfoSeparator; |
| |
| var request1:RequestData = new RequestData(); |
| request1.requestID = ClientSocketHandler.activeScreenDataStoreRequestString; |
| request1.requestData = activeScreenString; |
| |
| var request2:RequestData = new RequestData(); |
| request2.requestID = ClientSocketHandler.recordRequestString; |
| request2.requestData = completeString; |
| |
| |
| if(sm.isTopLevelRoot() == false) |
| { |
| // send the event to the root applicaiton and let it take care of the socket communication. |
| var marshalledEvent:ToolMarshallingEvent = new ToolMarshallingEvent( |
| ToolMarshallingEvent.RECORD); |
| |
| // #IMP: MARSHALLING NOTE#: This order of ariguments should not be changed |
| // across versions. If any new arguements is needed in new versions |
| // add them to the end of the list and handle appropriately in the |
| // handler of this event. |
| var recordDetails:Array = new Array(); |
| recordDetails.push(request1); |
| recordDetails.push(request2); |
| marshalledEvent.interAppDataToMainApp = recordDetails; |
| |
| dispatchEventToParent(marshalledEvent); |
| |
| } |
| else |
| { |
| if(ToolAgent.clientSocketHandler) |
| { |
| (ToolAgent.clientSocketHandler).addToRecordRequestQueue(request1); |
| (ToolAgent.clientSocketHandler).addToRecordRequestQueue(request2); |
| |
| //trace ("calling processQueuedRecordRequests ToolAgent"); |
| (ToolAgent.clientSocketHandler).processQueuedRecordRequests(true); |
| } |
| } |
| |
| } |
| else |
| { |
| /* |
| appAlpha = Application.application.alpha; |
| Application.application.alpha= .4; |
| Application.application.enabled = false; |
| */ |
| |
| ClientSocketHandler.disableApplication(); |
| |
| currentDescriptionXMLString = descriptionXML.toXMLString(); |
| recordInfoString = completeString; |
| var myTimer:Timer = new Timer(1000,1); |
| myTimer.addEventListener("timer", handleIncompleteRecord); |
| myTimer.start(); |
| } |
| |
| |
| |
| |
| |
| |
| |
| //rani |
| /* |
| ExternalInterface.call("window._mx_testing_plugin_" + playerID + ".Record", |
| parentRids, |
| descriptionXML.toXMLString(), |
| event.name, |
| event.args);*/ |
| XML.prettyPrinting = actualPrettyPrinting; |
| |
| } |
| catch (e:Error) |
| { |
| lastError = e; |
| Automation.automationDebugTracer.traceMessage("ToolAdapter","recordHandler()",e.message); |
| } |
| |
| automationManager.decrementCacheCounter(); |
| } |
| |
| private function marhsalledRecordHandler(event:Event):void |
| { |
| // Marshalling events are needeed across applicaiton domain |
| // so this conversion shall fail in the same domain |
| // i.e the above check is to avoid the echoing |
| if(event is ToolMarshallingEvent) |
| return; |
| |
| // this handler is only for the main app. so if we are not the main app root |
| // application, we should not handle it, we should just pass to our parent. |
| |
| //if(smMSm && (smMSm.useSWFBridge() == true)) |
| if(sm.isTopLevelRoot() == false) |
| { |
| var event1:ToolMarshallingEvent = ToolMarshallingEvent.marshal(event); |
| dispatchEventToParent(event1); |
| } |
| else |
| { |
| // i.e take the deta send from the sub app and call the external interface call. |
| // #IMP: MARSHALLING NOTE#: |
| var recordDetails:Array = event["interAppDataToMainApp"]; |
| if(recordDetails && recordDetails.length == 2) |
| { |
| /* ExternalInterface.call("window._mx_testing_plugin_" + playerID + ".Record", |
| recordDetails[0], //parentRids, |
| recordDetails[1], //descriptionXML.toXMLString(), |
| recordDetails[2], //event.name, |
| recordDetails[3]); // event.args); */ |
| if(ToolAgent.clientSocketHandler) |
| { |
| (ToolAgent.clientSocketHandler).addToRecordRequestQueue(recordDetails[0]); |
| (ToolAgent.clientSocketHandler).addToRecordRequestQueue(recordDetails[1]); |
| |
| //trace ("calling processQueuedRecordRequests ToolAgent"); |
| (ToolAgent.clientSocketHandler).processQueuedRecordRequests(true); |
| } |
| } |
| } |
| } |
| |
| /** |
| * @private |
| */ |
| public function beginRecording():Object |
| { |
| return useErrorHandler(function():Object |
| { |
| var o:Object = { result:null, error:0 }; |
| automationManager.addEventListener(AutomationRecordEvent.RECORD, |
| recordHandler, false, EventPriority.DEFAULT_HANDLER, true); |
| automationManager.beginRecording(); |
| |
| |
| return o; |
| }); |
| } |
| |
| /** |
| * @private |
| */ |
| public function endRecording():Object |
| { |
| return useErrorHandler(function():Object |
| { |
| var o:Object = { result:null, error:0 }; |
| automationManager.endRecording(); |
| automationManager.removeEventListener(AutomationRecordEvent.RECORD, |
| recordHandler); |
| return o; |
| }); |
| } |
| |
| /** |
| * @private |
| */ |
| public function getElementType(objID:String, fromTool:Boolean = true):Object |
| { |
| return useErrorHandler(function():Object |
| { |
| var o:Object = { result:null, error:0 }; |
| try{ |
| var rid:AutomationID = AutomationID.parse(objID); |
| var requiredApplicationName:String = getApplicationNameFromAutomationID(rid); |
| var currentApplicationName:String = getApplicationName(); |
| if(requiredApplicationName == currentApplicationName) |
| { |
| if (fromTool == true) |
| detailsSentToTool = true; |
| var target:IAutomationObject = automationManager.resolveIDToSingleObject(rid); |
| o.result = automationManager.getAutomationClassName(target); |
| } |
| else |
| { |
| // we need to send this as information to the other application |
| // and let the appropriate application handle it. |
| |
| // #IMP: MARSHALLING NOTE#: This order of ariguments should not be changed |
| // across versions. If any new arguements is needed in new versions |
| // add them to the end of the list and handle appropriately in the |
| // handler of this event. |
| |
| var details:Array = new Array(); |
| details.push(objID); |
| |
| if(fromTool == true) |
| { |
| requestPending = false; |
| resultRecieved = false; |
| } |
| o.result = handleRequestToDifferentApplication(requiredApplicationName, |
| ToolMarshallingEvent.GET_ELEMENT_TYPE,details); |
| |
| if((resultRecieved == true)&&(fromTool == true)) |
| { |
| // since we have recieved the result, we can send the information back to QTP |
| o = requestResultObjArray[0] as Object; |
| detailsSentToTool = true; |
| } |
| } |
| } |
| catch (e:Error) |
| { |
| throw e; |
| } |
| return o; |
| }); |
| } |
| |
| /** |
| * @private |
| */ |
| public function getDisplayName(objID:String, fromTool:Boolean = true):Object |
| { |
| return useErrorHandler(function():Object |
| { |
| var o:Object = { result:null, error:0 }; |
| try |
| { |
| var rid:AutomationID = AutomationID.parse(objID); |
| // we need to find out whether the current app and the |
| // reuired app are the same. |
| var requiredApplicationName:String = getApplicationNameFromAutomationID(rid); |
| var currentApplicationName:String = getApplicationName(); |
| if(requiredApplicationName == currentApplicationName) |
| { |
| |
| if (fromTool == true) |
| detailsSentToTool = true; |
| var target:IAutomationObject = automationManager.resolveIDToSingleObject(rid); |
| o.result = automationManager.getAutomationName(target); |
| } |
| else |
| { |
| // we need to send this as information to the other application |
| // and let the appropriate application handle it. |
| |
| |
| // #IMP: MARSHALLING NOTE#: This order of ariguments should not be changed |
| // across versions. If any new arguements is needed in new versions |
| // add them to the end of the list and handle appropriately in the |
| // handler of this event. |
| |
| var details:Array = new Array(); |
| details.push(objID); |
| if(fromTool == true) |
| { |
| requestPending = false; |
| resultRecieved = false; |
| } |
| o.result = handleRequestToDifferentApplication(requiredApplicationName, |
| ToolMarshallingEvent.GET_DISPLAY_NAME,details); |
| if((resultRecieved == true)&&(fromTool == true)) |
| { |
| // since we have recieved the result, we can send the information back to QTP |
| o = requestResultObjArray[0] as Object; |
| detailsSentToTool = true; |
| } |
| } |
| } |
| catch(e:Error) |
| { |
| throw e; |
| } |
| return o; |
| }); |
| } |
| |
| private function replayEvent(target:IAutomationObject, eventName:String, args:Array):Object |
| { |
| var automationClass:IAutomationClass = |
| automationManager.automationEnvironment.getAutomationClassByInstance(target); |
| |
| var message:String; |
| |
| // try to find the automation class |
| if (! automationClass) |
| { |
| message = resourceManager.getString( |
| "automation_agent", "classNotFound", |
| [AutomationClass.getClassName(target)]); |
| throw new Error(message); |
| } |
| |
| var eventDescriptor:IAutomationEventDescriptor = |
| automationClass.getDescriptorForEventByName(eventName); |
| |
| if (!eventDescriptor) |
| { |
| message = resourceManager.getString( |
| "automation_agent", "methodNotFound", |
| [eventName, automationClass]); |
| throw new Error(message); |
| } |
| |
| var retValue:Object = eventDescriptor.replay(target, args); |
| return {value:retValue, type:null}; |
| } |
| |
| private function replayMethod(target:IAutomationObject, method:String, args:Array):Object |
| { |
| var automationClass:IAutomationClass = |
| automationManager.automationEnvironment.getAutomationClassByInstance(target); |
| |
| var message:String; |
| |
| // try to find the automation class |
| if (! automationClass) |
| { |
| message = resourceManager.getString( |
| "automation_agent", "classNotFound", |
| [AutomationClass.getClassName(target)]); |
| throw new Error(message); |
| } |
| |
| var methodDescriptor:IAutomationMethodDescriptor = |
| automationClass.getDescriptorForMethodByName(method); |
| |
| if (!methodDescriptor) |
| { |
| message = resourceManager.getString( |
| "automation_agent", "methodNotFound", |
| [method, automationClass]); |
| throw new Error(message); |
| } |
| |
| var retValue:Object = methodDescriptor.replay(target, args); |
| |
| if(retValue is IAutomationObject) |
| retValue = automationManager.createID(IAutomationObject(retValue)).toString(); |
| |
| return {value:retValue, type:methodDescriptor.returnType}; |
| } |
| |
| private var replayResultObj:Object = null; |
| private function replayDefaultHandler(event:AutomationCustomReplayEvent):void |
| { |
| replayResultObj = { result:null, error:0 }; |
| if(event.isDefaultPrevented()) |
| return; |
| |
| automationManager.removeEventListener(AutomationCustomReplayEvent.CUSTOM_REPLAY,replayDefaultHandler); |
| |
| if((event.type != AutomationCustomReplayEvent.CUSTOM_REPLAY) || |
| (event.automationObject == null )|| |
| (event.name == null)) |
| return; |
| |
| |
| |
| //var o:Object = { result:null, error:0 }; |
| |
| try |
| { |
| replayResultObj.result = replayMethod(event.automationObject, event.name, event.args); |
| } |
| catch(e:Error) |
| { |
| try |
| { |
| //replayResultObj.result = replayEvent(target, method, args); |
| replayResultObj.result = replayEvent(event.automationObject, event.name, event.args); |
| } |
| catch(e:Error) |
| { |
| automationManager.decrementCacheCounter(); |
| throw e; |
| } |
| } |
| |
| } |
| /** |
| * @private |
| */ |
| public function replay(target:IAutomationObject, method:String, args:Array):Object |
| { |
| // first let us dispatch the custom replay event. |
| replayResultObj = null; |
| |
| // create the custom replay event and dispatch the same |
| var customReplayEventObj:AutomationCustomReplayEvent = |
| new AutomationCustomReplayEvent(AutomationCustomReplayEvent.CUSTOM_REPLAY,false,true); |
| //customReplayEventObj.cancelable should be true. We need to make this true as the default handler can prevent the default. |
| |
| customReplayEventObj.automationObject = target; |
| customReplayEventObj.name = method; |
| customReplayEventObj.args = args; |
| |
| |
| // dispatch the event from the automation manager. |
| automationManager.addEventListener(AutomationCustomReplayEvent.CUSTOM_REPLAY,replayDefaultHandler,false, |
| EventPriority.DEFAULT_HANDLER,false); |
| |
| automationManager.dispatchEvent(customReplayEventObj); |
| return replayResultObj; |
| |
| |
| } |
| |
| |
| /** |
| * @private |
| */ |
| public function run(objID:String, method:String, args:String, fromTool:Boolean = true):Object |
| { |
| return useErrorHandler(function():Object |
| { |
| var resultObj:Object; |
| try |
| { |
| var rid:AutomationID = AutomationID.parse(objID); |
| var requiredApplicationName:String = getApplicationNameFromAutomationID(rid); |
| var currentAppName:String = getApplicationName(); |
| |
| if(requiredApplicationName != currentAppName) |
| { |
| // we need to send this as information to the other application |
| // and let the appropriate application handle it. |
| |
| // #IMP: MARSHALLING NOTE#: This order of ariguments should not be changed |
| // across versions. If any new arguements is needed in new versions |
| // add them to the end of the list and handle appropriately in the |
| // handler of this event. |
| |
| var details:Array = new Array(); |
| details.push(objID); |
| details.push(method); |
| details.push(args); |
| |
| if(fromTool == true) |
| { |
| requestPending = false; |
| resultRecieved = false; |
| } |
| |
| resultObj = handleRequestToDifferentApplication(requiredApplicationName, |
| ToolMarshallingEvent.RUN,details); |
| if((resultRecieved == true)&&(fromTool == true)) |
| { |
| // since we have recieved the result, we can send the information back to QTP |
| resultObj = requestResultObjArray[0]; |
| detailsSentToTool = true; |
| } |
| } |
| else |
| { |
| |
| if (fromTool == true) |
| detailsSentToTool = true; |
| |
| // *************************************** |
| var target:IAutomationObject = automationManager.resolveIDToSingleObject(rid); |
| resultObj = replay(target, method, convertArrayFromCrazyToAs(args)); |
| } |
| |
| // if we have not sent the request to QTP, we need to send the error message that we are not yet synchronised |
| // we need this message only if the request to this method has come from QTP |
| if((detailsSentToTool == false)&&(fromTool == true)) |
| { |
| // we dont expect this case to happen. But just to be on the |
| // safe side we are keeping this error |
| var message:String = resourceManager.getString( |
| "automation_agent", "notSynchronized"); |
| throw new AutomationError(message, |
| AutomationError.OBJECT_NOT_VISIBLE); |
| } |
| } |
| catch(e:Error) |
| { |
| throw e; |
| } |
| |
| return resultObj; |
| }); |
| } |
| |
| /** |
| * @private |
| */ |
| public function findObjectID(descriptionXML:String):Object |
| { |
| // this method is not used in 3 onwards |
| // hence this method is modified to support Marshalling |
| return useErrorHandler(function():Object |
| { |
| var o:Object = { result:null, error:0 }; |
| try |
| { |
| var rid:AutomationID = new AutomationID(); |
| var x:XML = new XML(descriptionXML); |
| while (x) |
| { |
| var part:AutomationIDPart = new AutomationIDPart(); |
| part.automationClassName = x.@type.toString(); |
| var automationClass:IToolAutomationClass = |
| automationManager.automationEnvironment.getAutomationClassByName(part.automationClassName) as IToolAutomationClass; |
| var propertyCaseRemapping:Object = automationClass.propertyLowerCaseMap; |
| |
| for (var property:Object in x.Property) |
| { |
| var propertyName:String = x.Property[property].@name.toString().toLowerCase(); |
| |
| if (propertyName in propertyCaseRemapping) |
| { |
| var propertyDescriptor:ToolPropertyDescriptor = |
| propertyCaseRemapping[propertyName]; |
| |
| propertyName = propertyDescriptor.name; |
| |
| var regEx:String = x.Property[property].@regExp; |
| var value:String = x.Property[property].@value; |
| |
| if (regEx == "true" || regEx == "t") |
| part[propertyName] = new RegExp(value); |
| else |
| part[propertyName] = value; |
| } |
| } |
| rid.addLast(part); |
| x = x.Element.length() == 1 ? x.Element[0] : null; |
| } |
| |
| var message:String; |
| if (!automationManager.isSynchronized(null)) |
| { |
| message = resourceManager.getString( |
| "automation_agent", "notSynchronized"); |
| throw new AutomationError(message, |
| AutomationError.OBJECT_NOT_VISIBLE); |
| } |
| var obj:IAutomationObject = automationManager.resolveIDToSingleObject(rid); |
| if (!automationManager.isSynchronized(obj)) |
| { |
| message = resourceManager.getString( |
| "automation_agent", "notSynchronized"); |
| throw new AutomationError(message, |
| AutomationError.OBJECT_NOT_VISIBLE); |
| } |
| if (!automationManager.isVisible(obj as DisplayObject)) |
| { |
| message = resourceManager.getString( |
| "automation_agent", "invisible"); |
| throw new AutomationError(message, |
| AutomationError.OBJECT_NOT_VISIBLE); |
| } |
| o.result = automationManager.createID(obj).toString(); |
| } |
| catch(e:Error) |
| { |
| throw e; |
| } |
| |
| return o; |
| }); |
| } |
| |
| /** |
| * @private |
| */ |
| public function findObjectIDs(descriptionXML:String, fromTool :Boolean = true):Object |
| { |
| return useErrorHandler(function():Object |
| { |
| var o:Object = { result:null, error:0 }; |
| var message:String; |
| try |
| { |
| var rid:AutomationID = new AutomationID(); |
| var x:XML = new XML(descriptionXML); |
| var partIndex:int = 0; |
| |
| var sameApplication:Boolean = true; |
| var requiredApplicationName :String ; |
| while (x && sameApplication) |
| { |
| var part:AutomationIDPart = new AutomationIDPart(); |
| part.automationClassName = x.@type.toString(); |
| var automationClass:IToolAutomationClass = |
| automationManager.automationEnvironment.getAutomationClassByName(part.automationClassName) as IToolAutomationClass; |
| var propertyCaseRemapping:Object = automationClass.propertyLowerCaseMap; |
| |
| for (var property:Object in x.Property) |
| { |
| var propertyName:String = x.Property[property].@name.toString().toLowerCase(); |
| |
| if (propertyName in propertyCaseRemapping) |
| { |
| var propertyDescriptor:ToolPropertyDescriptor = |
| propertyCaseRemapping[propertyName]; |
| |
| propertyName = propertyDescriptor.name; |
| |
| var regEx:String = x.Property[property].@regExp; |
| var value:String = x.Property[property].@value; |
| |
| if (regEx == "true" || regEx == "t") |
| part[propertyName] = new RegExp(value); |
| else |
| part[propertyName] = value; |
| } |
| } |
| rid.addLast(part); |
| |
| // we need to decide whehter we are in the correct application |
| if((partIndex == 0) && (fromTool == true)) |
| { |
| requiredApplicationName = automationManager.getApplicationNameFromAutomationIDPart(part); |
| //requiredApplicationName = part["automationName"][0].toString(); |
| var currentAppName:String = getApplicationName(); |
| |
| // we need to check whether this request is for the |
| // root application or sub application. |
| // if it is for the sub applicaiton, we need to send the information as event to the other |
| // applications and wait for the result. |
| if(requiredApplicationName != currentAppName ) |
| sameApplication = false; |
| } |
| partIndex++; |
| x = x.Element.length() == 1 ? x.Element[0] : null; |
| } |
| |
| if (!automationManager.isSynchronized(null)) |
| { |
| message = resourceManager.getString( |
| "automation_agent", "notSynchronized"); |
| throw new AutomationError(message, |
| AutomationError.OBJECT_NOT_VISIBLE); |
| } |
| |
| // before we call methods on the automation manger, whether this request is for the |
| // root application or sub application. |
| // if it is for the sub applicaiton, we need to send the information as event to the other |
| // applications and wait for the result. |
| if(sameApplication == true ) |
| { |
| |
| if (fromTool == true) |
| detailsSentToTool = true; |
| |
| //here we can proceed with the root applicaiton. |
| var autObjects:Array = automationManager.resolveID(rid); |
| for (var i:int = 0; i < autObjects.length; ++i) |
| { |
| autObjects[i] = automationManager.createID(autObjects[i]).toString(); |
| } |
| o.result = autObjects; |
| detailsSentToTool = true; |
| } |
| else |
| { |
| // #IMP: MARSHALLING NOTE#: This order of ariguments should not be changed |
| // across versions. If any new arguements is needed in new versions |
| // add them to the end of the list and handle appropriately in the |
| // handler of this event. |
| |
| var details:Array = new Array(); |
| details.push(descriptionXML); |
| |
| if(fromTool == true) |
| { |
| requestPending = false; |
| resultRecieved = false; |
| } |
| o.result = handleRequestToDifferentApplication(requiredApplicationName, |
| ToolMarshallingEvent.FIND_OBJECTIDS , |
| details); |
| |
| if((resultRecieved == true)&&(fromTool == true)) |
| { |
| // since we have recieved the result, we can send the information back to Tool |
| o.result = requestResultObjArray[0]; |
| detailsSentToTool = true; |
| } |
| } |
| |
| // if we have not sent the request to QTP, we need to send the error message that we are not yet synchronised |
| // we need this message only if the request to this method has come from QTP |
| if((detailsSentToTool == false)&&(fromTool == true)) |
| { |
| // we dont expect this case to happen. But just to be on the |
| // safe side we are keeping this error |
| var message1:String = resourceManager.getString( |
| "automation_agent", "notSynchronized"); |
| throw new AutomationError(message1, |
| AutomationError.OBJECT_NOT_VISIBLE); |
| } |
| } |
| catch(e:Error) |
| { |
| throw e; |
| } |
| |
| return o; |
| }); |
| } |
| |
| /** |
| * @private |
| */ |
| public function buildDescription(objID:String, fromTool:Boolean = true):Object |
| { |
| return useErrorHandler(function():Object |
| { |
| var o:Object = { result:null, error:0 }; |
| try |
| { |
| var rid:AutomationID = AutomationID.parse(objID); |
| // we need to find out whether the current app and the |
| // reuired app are the same. |
| var requiredApplicationName:String = getApplicationNameFromAutomationID(rid); |
| var currentApplicationName:String = getApplicationName(); |
| if(requiredApplicationName == currentApplicationName) |
| { |
| if (fromTool == true) |
| detailsSentToTool = true; |
| var obj:IAutomationObject = automationManager.resolveIDToSingleObject(rid); |
| //Don't use getDescriptionXML because it uses the attributes |
| //that were sent into us, and in theory those attributes could |
| //be regular expressions used to find the item |
| //var result:XML = getDescriptionXML(rid, obj); |
| //XML.prettyPrinting = false; |
| //o.result = stripSlashRHack(result.toXMLString()); |
| o.result = getActiveOrLearnXMLTree(objID, false).learnChildrenXML; |
| } |
| else |
| { |
| // #IMP: MARSHALLING NOTE#: This order of ariguments should not be changed |
| // across versions. If any new arguements is needed in new versions |
| // add them to the end of the list and handle appropriately in the |
| // handler of this event. |
| |
| var details:Array = new Array(); |
| details.push(objID); |
| |
| if(fromTool == true) |
| { |
| requestPending = false; |
| resultRecieved = false; |
| } |
| o.result = handleRequestToDifferentApplication(requiredApplicationName, |
| ToolMarshallingEvent.BUILD_DESCRIPTION , |
| details); |
| |
| if((resultRecieved == true)&&(fromTool == true)) |
| { |
| // since we have recieved the result, we can send the information back to Tool |
| o = requestResultObjArray[0]; |
| detailsSentToTool = true; |
| } |
| } |
| |
| // if we have not sent the request to QTP, we need to send the error message that we are not yet synchronised |
| // we need this message only if the request to this method has come from QTP |
| if((detailsSentToTool == false)&&(fromTool == true)) |
| { |
| // we dont expect this case to happen. But just to be on the |
| // safe side we are keeping this error |
| var message:String = resourceManager.getString( |
| "automation_agent", "notSynchronized"); |
| throw new AutomationError(message, |
| AutomationError.OBJECT_NOT_VISIBLE); |
| } |
| } |
| catch (e:Error) |
| { |
| throw e; |
| } |
| return o; |
| }); |
| } |
| |
| /** |
| * @private |
| */ |
| public function getPropertyDescriptors(obj:IAutomationObject, |
| names:Array = null, |
| forVerification:Boolean = true, |
| forDescription:Boolean = true):Array |
| { |
| if (!obj) |
| return null; |
| |
| try |
| { |
| automationManager.incrementCacheCounter(); |
| |
| var automationClass:IToolAutomationClass = |
| automationManager.automationEnvironment.getAutomationClassByInstance(obj) as IToolAutomationClass; |
| var i:int; |
| var propertyCaseRemapping:Object = automationClass.propertyLowerCaseMap; |
| |
| var result:Array = []; |
| if (!names) |
| { |
| var propertyDescriptors:Array = |
| automationClass.getPropertyDescriptors(obj, |
| forVerification, |
| forDescription); |
| names = []; |
| for (i = 0; i < propertyDescriptors.length; i++) |
| { |
| names[i] = propertyDescriptors[i].name; |
| } |
| } |
| for (i = 0; i < names.length; i++) |
| { |
| var lowerCaseName:String = names[i].toLowerCase(); |
| var propertyDescriptor:ToolPropertyDescriptor = |
| propertyCaseRemapping[lowerCaseName]; |
| result.push(propertyDescriptor); |
| } |
| |
| automationManager.decrementCacheCounter(); |
| } |
| catch(e:Error) |
| { |
| automationManager.decrementCacheCounter(); |
| |
| throw e; |
| } |
| |
| return result; |
| } |
| |
| private function encodeValues(obj:IAutomationObject, values:Array, descriptors:Array):Array |
| { |
| var result:Array = []; |
| for (var i:int = 0; i < values.length; ++i) |
| { |
| var descriptor:ToolPropertyDescriptor = descriptors[i]; |
| var codec:IAutomationPropertyCodec = propertyCodecMap[descriptor.codecName]; |
| |
| if (codec == null) |
| codec = propertyCodecMap["object"]; |
| |
| var relativeParent:IAutomationObject = obj; |
| |
| var retValue:Object = codec.encode(automationManager, obj, descriptor, relativeParent); |
| result.push({value:retValue, descriptor:descriptor}); |
| } |
| |
| return result; |
| } |
| |
| |
| /** |
| * @private |
| */ |
| public function getProperties(objID:String, names:String, fromTool:Boolean = true):Object |
| { |
| return useErrorHandler(function():Object |
| { |
| var o:Object = { result:null, error:0 }; |
| try |
| { |
| var rid:AutomationID = AutomationID.parse(objID); |
| // we need to find out whether the current app and the |
| // reuired app are the same. |
| var requiredApplicationName:String = getApplicationNameFromAutomationID(rid); |
| var currentApplicationName:String = getApplicationName(); |
| if(requiredApplicationName == currentApplicationName) |
| { |
| |
| if (fromTool == true) |
| detailsSentToTool = true; |
| |
| // we are in the same applicaiton, and hence we can proceed. |
| var obj:IAutomationObject = automationManager.resolveIDToSingleObject(rid); |
| var asNames:Array = convertArrayFromCrazyToAs(names); |
| |
| var descriptors:Array = []; |
| if(asNames && asNames.length) |
| { |
| //trace("getProperties 1- Lenght of Name"+ asNames.length); |
| var automationClass:IToolAutomationClass = |
| automationManager.automationEnvironment.getAutomationClassByInstance(obj) as IToolAutomationClass;; |
| var propertyCaseRemapping:Object = automationClass.propertyLowerCaseMap; |
| for (var i:int = 0; i < asNames.length; i++) |
| { |
| |
| var lowerCaseName:String = asNames[i].toLowerCase(); |
| var propertyDescriptor:IAutomationPropertyDescriptor = |
| propertyCaseRemapping[lowerCaseName]; |
| // trace("getProperties 2 + Name - "+ lowerCaseName); |
| if(propertyDescriptor) |
| { |
| asNames[i] = propertyDescriptor.name; |
| descriptors.push(propertyDescriptor); |
| //trace("getProperties 3 + Name - found"+ lowerCaseName); |
| } |
| else |
| { |
| // descriptor was not found delete the entry. |
| asNames.splice(i, 1); |
| //trace("getProperties 3 + Name - Not found"+ lowerCaseName); |
| } |
| |
| } |
| |
| } |
| |
| var values:Array = automationManager.getProperties(obj, asNames); |
| var x:Array = encodeValues(obj, values, descriptors); |
| |
| //trace("getProperties 4 + found values"+ x.length); |
| for (var no:int = 0; no < x.length; ++no) |
| { |
| x[no] = x[no].value; |
| } |
| |
| |
| o.result = getValuesWithTypeInformation(x); |
| } |
| else |
| { |
| // we need to send this as information to the other application |
| // and let the appropriate application handle it. |
| |
| // #IMP: MARSHALLING NOTE#: This order of ariguments should not be changed |
| // across versions. If any new arguements is needed in new versions |
| // add them to the end of the list and handle appropriately in the |
| // handler of this event. |
| |
| var details:Array = new Array(); |
| details.push(objID); |
| details.push(names); |
| |
| if(fromTool == true) |
| { |
| requestPending = false; |
| resultRecieved = false; |
| } |
| o.result = handleRequestToDifferentApplication(requiredApplicationName, |
| ToolMarshallingEvent.GET_PROPERTIES,details); |
| if((resultRecieved == true)&&(fromTool == true)) |
| { |
| // since we have recieved the result, we can send the information back to QTP |
| o = requestResultObjArray[0] as Object; |
| detailsSentToTool = true; |
| } |
| } |
| } |
| catch (e:Error) |
| { |
| throw e; |
| } |
| return o; |
| }); |
| } |
| |
| /** |
| * @private |
| */ |
| public function getParent(objID:String, fromTool:Boolean = true):Object |
| { |
| return useErrorHandler(function():Object |
| { |
| var o:Object = { result:null, error:0 }; |
| try |
| { |
| var rid:AutomationID = AutomationID.parse(objID); |
| // we need to find out whether the current app and the |
| // reuired app are the same. |
| var requiredApplicationName:String = getApplicationNameFromAutomationID(rid); |
| var currentApplicationName:String = getApplicationName(); |
| if(requiredApplicationName == currentApplicationName) |
| { |
| |
| if (fromTool == true) |
| detailsSentToTool = true; |
| var obj:IAutomationObject = automationManager.resolveIDToSingleObject(rid); |
| obj = automationManager.getParent(obj); |
| o.result = (obj |
| ? automationManager.createID(obj).toString() |
| : null); |
| } |
| else |
| { |
| // we need to send this as information to the other application |
| // and let the appropriate application handle it. |
| |
| // #IMP: MARSHALLING NOTE#: This order of ariguments should not be changed |
| // across versions. If any new arguements is needed in new versions |
| // add them to the end of the list and handle appropriately in the |
| // handler of this event. |
| |
| var details:Array = new Array(); |
| details.push(objID); |
| |
| if(fromTool == true) |
| { |
| requestPending = false; |
| resultRecieved = false; |
| } |
| o.result = handleRequestToDifferentApplication(requiredApplicationName, |
| ToolMarshallingEvent.GET_PARENT,details); |
| if((resultRecieved == true)&&(fromTool == true)) |
| { |
| // since we have recieved the result, we can send the information back to QTP |
| o = requestResultObjArray[0] as Object; |
| detailsSentToTool = true; |
| } |
| } |
| |
| // if we have not sent the request to QTP, we need to send the error message that we are not yet synchronised |
| // we need this message only if the request to this method has come from QTP |
| if((detailsSentToTool == false)&&(fromTool == true)) |
| { |
| // we dont expect this case to happen. But just to be on the |
| // safe side we are keeping this error |
| var message:String = resourceManager.getString( |
| "automation_agent", "notSynchronized"); |
| throw new AutomationError(message, |
| AutomationError.OBJECT_NOT_VISIBLE); |
| } |
| } |
| catch(e:Error) |
| { |
| throw e; |
| } |
| return o; |
| }); |
| } |
| |
| /** |
| * @private |
| */ |
| public function getChildren(objID:String, |
| filterXMLString:String = null, fromTool:Boolean = true):Object |
| { |
| return useErrorHandler(function():Object |
| { |
| var o:Object = { result:null, error:0 }; |
| try |
| { |
| var rid:AutomationID = AutomationID.parse(objID); |
| // we need to find out whether the current app and the |
| // reuired app are the same. |
| var requiredApplicationName:String = getApplicationNameFromAutomationID(rid); |
| var currentApplicationName:String = getApplicationName(); |
| if(requiredApplicationName == currentApplicationName) |
| { |
| |
| if (fromTool == true) |
| detailsSentToTool = true; |
| var autObject:IAutomationObject = automationManager.resolveIDToSingleObject(rid); |
| var children:Array; |
| if (autObject.numAutomationChildren > 0) |
| { |
| var part:AutomationIDPart = createPartFromFilterXML(filterXMLString); |
| children = automationManager.getChildrenFromIDPart(autObject, part); |
| |
| for (var i:int = 0; i < children.length; ++i) |
| { |
| children[i] = automationManager.createID(children[i]).toString(); |
| } |
| } |
| else |
| children = [automationManager.createID(autObject).toString()]; |
| |
| o.result = children; |
| } |
| else |
| { |
| // we need to send this as information to the other application |
| // and let the appropriate application handle it. |
| |
| // #IMP: MARSHALLING NOTE#: This order of ariguments should not be changed |
| // across versions. If any new arguements is needed in new versions |
| // add them to the end of the list and handle appropriately in the |
| // handler of this event. |
| |
| var details:Array = new Array(); |
| details.push(objID); |
| details.push(filterXMLString); |
| |
| if(fromTool == true) |
| { |
| requestPending = false; |
| resultRecieved = false; |
| } |
| o.result = handleRequestToDifferentApplication(requiredApplicationName, |
| ToolMarshallingEvent.GET_CHILDREN,details); |
| if((resultRecieved == true)&&(fromTool == true)) |
| { |
| // since we have recieved the result, we can send the information back to QTP |
| o = requestResultObjArray[0] as Object; |
| detailsSentToTool = true; |
| } |
| } |
| } |
| catch (e:Error) |
| { |
| throw e; |
| } |
| return o; |
| }); |
| } |
| |
| /** |
| * @private |
| */ |
| public function setLastError(message:String, fromTool:Boolean = true):void |
| { |
| // we need to find out which was the last responded application. |
| var currentAppname:String = getApplicationName(); |
| if ((fromTool == false) || (currentAppname == lastResponseRecievedApplicationName)) |
| { |
| lastError = new Error(message); |
| } |
| else |
| { |
| // this will be called if the fromTool == true and currentAppname != lastResponseRecievedApplicationName |
| // we need to dispatch the event and get the error details from the appropriate application |
| |
| // we need to send this as information to the other application |
| // and let the appropriate application handle it. |
| |
| // #IMP: MARSHALLING NOTE#: This order of ariguments should not be changed |
| // across versions. If any new arguements is needed in new versions |
| // add them to the end of the list and handle appropriately in the |
| // handler of this event. |
| |
| var details:Array = new Array(); |
| details.push(message); |
| handleRequestToDifferentApplication(lastResponseRecievedApplicationName, |
| ToolMarshallingEvent.SET_LAST_ERROR,details); |
| |
| } |
| } |
| |
| /** |
| * @private |
| */ |
| public function getLastError(fromTool:Boolean = true):Object |
| { |
| // we need to find out which was the last responded application. |
| var currentAppname:String = getApplicationName(); |
| if ((fromTool == false) || (currentAppname == lastResponseRecievedApplicationName)) |
| { |
| detailsSentToTool = true; |
| return { result: (lastError ? lastError.message.substr(0, 1 << 9) : null), |
| error: 0 }; |
| } |
| else |
| { |
| var o:Object = { result:null, error:0 }; |
| // we will reach this condition only when fromTool == true and |
| // currentAppname != lastResponseRecievedApplicationName |
| // we need to dispatch the event and get the error details from the appropriate application |
| |
| // we need to send this as information to the other application |
| // and let the appropriate application handle it. |
| |
| // #IMP: MARSHALLING NOTE#: This order of ariguments should not be changed |
| // across versions. If any new arguements is needed in new versions |
| // add them to the end of the list and handle appropriately in the |
| // handler of this event. |
| |
| var details:Array = new Array(); |
| //details.push(lastResponseRecievedApplicationName); |
| |
| if(fromTool == true) |
| { |
| requestPending = false; |
| resultRecieved = false; |
| } |
| |
| o.result = handleRequestToDifferentApplication(lastResponseRecievedApplicationName, |
| ToolMarshallingEvent.GET_LAST_ERROR,details); |
| if((resultRecieved == true)&&(fromTool == true)) |
| { |
| // since we have recieved the result, we can send the information back to QTP |
| o = requestResultObjArray[0] as Object; |
| detailsSentToTool = true; |
| } |
| |
| return o; |
| } |
| } |
| |
| /** |
| * @private |
| */ |
| protected function getRectangle(objID:String, fromTool:Boolean = true):Object |
| { |
| return useErrorHandler(function():Object |
| { |
| var o:Object = { result:null, error:0 }; |
| try |
| { |
| var rid:AutomationID = AutomationID.parse(objID); |
| // we need to find out whether the current app and the |
| // reuired app are the same. |
| var requiredApplicationName:String = getApplicationNameFromObjectIDString(objID); |
| var currentApplicationName:String = getApplicationName(); |
| if(requiredApplicationName == currentApplicationName) |
| { |
| |
| if (fromTool == true) |
| detailsSentToTool = true; |
| var obj:IAutomationObject = automationManager.resolveIDToSingleObject(rid); |
| o.result = automationManager.getRectangle(obj as DisplayObject); |
| } |
| else |
| { |
| // we need to send this as information to the other application |
| // and let the appropriate application handle it. |
| |
| // #IMP: MARSHALLING NOTE#: This order of ariguments should not be changed |
| // across versions. If any new arguements is needed in new versions |
| // add them to the end of the list and handle appropriately in the |
| // handler of this event. |
| var details:Array = new Array(); |
| details.push(objID); |
| |
| if(fromTool == true) |
| { |
| requestPending = false; |
| resultRecieved = false; |
| } |
| |
| o.result = handleRequestToDifferentApplication(requiredApplicationName, |
| ToolMarshallingEvent.GET_RECTANGLE,details); |
| if((resultRecieved == true)&&(fromTool == true)) |
| { |
| // since we have recieved the result, we can send the information back to QTP |
| o = requestResultObjArray[0] as Object; |
| detailsSentToTool = true; |
| } |
| } |
| |
| } |
| catch(e:Error) |
| { |
| throw e; |
| } |
| return o; |
| }); |
| } |
| |
| public function getRectangleInScreenCoordinates(objID:String):Array |
| { |
| // for AIR, we need to add the chromeHeight and Chrome width to get the screen coordinates |
| // as the app 0,0 does not include the chrome details. |
| |
| var boundarObj:Object = getRectangle(objID); |
| var objBoundaryInAppCoordinates:Array = boundarObj["result"] as Array; |
| var objBoundaryInScreenCoordinates:Array = new Array(); |
| |
| var windowId:String = automationManager.getAIRWindowUniqueIDFromObjectIDString(objID); |
| |
| if(objBoundaryInAppCoordinates.length == 4) |
| { |
| var stageStartScreenCoordinate:Point = getStageStartPointInScreenCoords(windowId); |
| |
| if(!stageStartScreenCoordinate) |
| stageStartScreenCoordinate = new Point(0,0); |
| // we would have got the message for this. so the user is not expected to proceed. |
| // the above is done to avoid the null obejct access. |
| |
| |
| //var chromeHeight:int = getChromeHeight(); // for flex this will return 0 |
| //var chromeWidth:int = getChromeWidth(); // for flex this will return 0 |
| |
| var chromeHeight:int = 0; // for flex this will return 0 |
| var chromeWidth:int = 0; // for flex this will return 0 |
| |
| objBoundaryInScreenCoordinates.push(objBoundaryInAppCoordinates[0] + stageStartScreenCoordinate.x+chromeWidth); |
| objBoundaryInScreenCoordinates.push(objBoundaryInAppCoordinates[1] + stageStartScreenCoordinate.y+chromeHeight); |
| objBoundaryInScreenCoordinates.push(objBoundaryInAppCoordinates[2] + stageStartScreenCoordinate.x+chromeWidth); |
| objBoundaryInScreenCoordinates.push(objBoundaryInAppCoordinates[3] + stageStartScreenCoordinate.y+chromeHeight); |
| /*trace (String(objBoundaryInScreenCoordinates[0]) + |
| String(objBoundaryInScreenCoordinates[1]) + |
| String( objBoundaryInScreenCoordinates[2] ) + |
| String( objBoundaryInScreenCoordinates[3]) |
| );*/ |
| } |
| |
| return objBoundaryInScreenCoordinates; |
| |
| } |
| /** |
| * @private |
| */ |
| public function getElementFromPoint(x:int, y:int, windowId:String, fromTool:Boolean= true):Object |
| { |
| return useErrorHandler(function():Object |
| { |
| var o:Object = { result:null, error:0 }; |
| |
| try |
| { |
| var details:Array = new Array(); |
| details.push(x); |
| details.push(y); |
| details.push(windowId); |
| |
| // here the handling is different from the other methods |
| // here we need just let the sub application handle the point |
| // first. if no sub application handles the point, then the main application needs to handle the same |
| if(fromTool == true) |
| { |
| // we need to send this as information to the other application |
| // and let the appropriate application handle it. |
| |
| // #IMP: MARSHALLING NOTE#: This order of ariguments should not be changed |
| // across versions. If any new arguements is needed in new versions |
| // add them to the end of the list and handle appropriately in the |
| // handler of this event. |
| |
| if(fromTool == true) |
| { |
| requestPending = false; |
| resultRecieved = false; |
| } |
| |
| // in the case of this method, we need to let all application process |
| // the request. If the application is able to process the details, we need to |
| // get the details. If we get a Popup or Alerts we need to give the importance of the same. |
| // secondly we need to give priority of a non SWFLoader object. |
| |
| // first let us call from the main applicaiton |
| var appWindow:DisplayObject = automationManager.getAIRWindow(windowId); |
| //Application.application as DisplayObject; |
| var appPoint:Point = convertScreenPointToStagePoint(new Point(x,y),windowId); |
| var appGlobalPoint:Point = appWindow.localToGlobal(appPoint); |
| var obj:IAutomationObject = automationManager.getElementFromPoint2(appGlobalPoint.x, appGlobalPoint.y,windowId); |
| var result:AutomationID; |
| var mainAppObj:Object = null; |
| |
| |
| // add the result to the resultObejct array if the result is not a SWFLoader |
| // Note: we need to check how the object is to be handled when the |
| // application is loaded using Loader |
| if((obj != null) && (!(isObjectSWFLoader(obj1)))) |
| { |
| |
| var currentAppName1:String = getApplicationName(); |
| // we dont need to find out if the object belong to popup |
| // if we dont get a pop up from child, and if we got and |
| // object from main application, main application object has the |
| // preference. |
| var isPopup1:Boolean = automationManager.isObjectPopUp(obj); |
| mainAppObj = { result:null, applicationName:currentAppName1, |
| isPopup:isPopup1, error:0 }; |
| var resultY:AutomationID = automationManager.createID(obj); |
| mainAppObj.result = resultY.toString(); |
| } |
| |
| // irrespective of the result from the main application we |
| // to check what is the object at this point by other application. |
| handleRequestToDifferentApplication(null, |
| ToolMarshallingEvent.GET_ELEMENT_FROM_POINT,details); |
| |
| if(mainAppObj) |
| { |
| var tempArray:Array = new Array(); |
| tempArray.push(mainAppObj); |
| requestResultObjArray = tempArray.concat(requestResultObjArray); |
| } |
| |
| // we would have got replies from all applicaitons which could process the object |
| var count:int = requestResultObjArray.length; |
| if(count != 0) |
| { |
| var index:int = 0; |
| var requiredObjectIdentified:Boolean = false; |
| // process each object |
| var currentObj:Object = null; |
| while((!requiredObjectIdentified) && (index < count)) |
| { |
| currentObj = requestResultObjArray[index]; |
| if(currentObj["isPopup"] == true) |
| { |
| // NOTE: TBD: we need to handle the case of other objects which can be |
| // hosted by the PopupManager |
| requiredObjectIdentified = true; |
| } |
| index++; |
| } |
| |
| if(requiredObjectIdentified == true) |
| { |
| lastApplicationName = currentObj["applicationName" ]; |
| o.result = currentObj.result; |
| } |
| else |
| { |
| // the last loaded application need not be the application on the top. |
| // this depends on the order of the swfloader in an application. |
| // so we need to get the index of the last application. |
| var lastRequiredObjectIndex:int = automationManager.getTopApplicationIndex(requestResultObjArray); |
| |
| //var lastRequiredObjectIndex:int = requestResultObjArray.length - 1; |
| |
| if(lastRequiredObjectIndex != -1) |
| { |
| currentObj = requestResultObjArray[lastRequiredObjectIndex]; |
| lastApplicationName = currentObj["applicationName" ]; |
| o.result = currentObj.result; |
| } |
| } |
| } |
| |
| detailsSentToTool = true; |
| } |
| else |
| { |
| appWindow = FlexGlobals.topLevelApplication as DisplayObject; |
| appPoint = convertScreenPointToStagePoint(new Point(x,y),windowId); |
| if(appPoint) |
| { |
| appGlobalPoint = appWindow.localToGlobal(appPoint); |
| var obj1:IAutomationObject = automationManager.getElementFromPoint(appGlobalPoint.x, appGlobalPoint.y); |
| |
| // check whether the object is a child of system manager |
| // we expect the Alerts and object hosted by the PopupManager |
| // only to get a special treatment |
| if((obj1 != null) && (!isObjectSWFLoader(obj1))) |
| { |
| var isPopup:Boolean = automationManager.isObjectPopUp(obj1); |
| |
| var result1:AutomationID = automationManager.createID(obj1); |
| |
| var currentAppName:String = getApplicationName(); |
| var o2:Object = { result:null, applicationName:currentAppName, |
| isPopup:isPopup, error:0 }; |
| o2.result = result1.toString(); |
| return o2; |
| } |
| } |
| } |
| } |
| catch (e:Error) |
| { |
| throw e; |
| } |
| return o; |
| }); |
| } |
| |
| |
| private function isObjectSWFLoader(obj:Object):Boolean |
| { |
| var retValue:Boolean = false; |
| if(obj is SWFLoader) |
| { |
| // Image is also a SWFLoader. But we should not ignore that. |
| if(!(obj is Image)) |
| retValue = true; |
| } |
| return retValue |
| } |
| |
| /** |
| * @private |
| */ |
| public function getActiveScreen(level:uint, |
| objID:String, |
| leftOffset:int, |
| topOffset:int, fromTool:Boolean = true):Object |
| { |
| return useErrorHandler(function():Object |
| { |
| var o:Object = { result:null, error:0 }; |
| try |
| { |
| // we need to find out whether the current app and the |
| // reuired app are the same. |
| var requiredApplicationName:String = getApplicationNameFromObjectIDString(objID); |
| var currentApplicationName:String = getApplicationName(); |
| if(requiredApplicationName == currentApplicationName) |
| { |
| if (fromTool == true) |
| detailsSentToTool = true; |
| //we could make the 2nd parameter true if we wanted to support |
| //the complete level |
| o.result = getActiveOrLearnXMLTree(objID, false, "", true, leftOffset, topOffset).learnChildrenXML; |
| } |
| else |
| { |
| // we need to send this as information to the other application |
| // and let the appropriate application handle it. |
| |
| // #IMP: MARSHALLING NOTE#: This order of ariguments should not be changed |
| // across versions. If any new arguements is needed in new versions |
| // add them to the end of the list and handle appropriately in the |
| // handler of this event. |
| var details:Array = new Array(); |
| details.push(level); |
| details.push(objID); |
| details.push(leftOffset); |
| details.push(topOffset); |
| |
| if(fromTool == true) |
| { |
| requestPending = false; |
| resultRecieved = false; |
| } |
| |
| o.result = handleRequestToDifferentApplication(requiredApplicationName, |
| ToolMarshallingEvent.GET_ACTIVESCREEN,details); |
| if((resultRecieved == true)&&(fromTool == true)) |
| { |
| // since we have recieved the result, we can send the information back to QTP |
| o = requestResultObjArray[0] as Object; |
| detailsSentToTool = true; |
| } |
| } |
| |
| } |
| catch(e:Error) |
| { |
| throw e; |
| } |
| return o; |
| }); |
| } |
| |
| /** |
| * @private |
| */ |
| public function learnChildObjects(objID:String, |
| filterXMLString:String, fromTool:Boolean = true):Object |
| { |
| return useErrorHandler(function():Object |
| { |
| var o:Object = { result:null, error:0 }; |
| try |
| { |
| // we need to find out whether the current app and the |
| // reuired app are the same. |
| var requiredApplicationName:String = getApplicationNameFromObjectIDString(objID); |
| var currentApplicationName:String = getApplicationName(); |
| if(requiredApplicationName == currentApplicationName) |
| { |
| if (fromTool == true) |
| detailsSentToTool = true; |
| //we could make the 2nd parameter true if we wanted to support |
| //the complete level |
| o.result = getActiveOrLearnXMLTree(objID, true, filterXMLString); |
| } |
| else |
| { |
| // we need to send this as information to the other application |
| // and let the appropriate application handle it. |
| |
| // #IMP: MARSHALLING NOTE#: This order of ariguments should not be changed |
| // across versions. If any new arguements is needed in new versions |
| // add them to the end of the list and handle appropriately in the |
| // handler of this event. |
| var details:Array = new Array(); |
| details.push(objID); |
| details.push(filterXMLString); |
| |
| if(fromTool == true) |
| { |
| requestPending = false; |
| resultRecieved = false; |
| } |
| o.result = handleRequestToDifferentApplication(requiredApplicationName, |
| ToolMarshallingEvent.LEARN_CHILD_OBJECTS,details); |
| if((resultRecieved == true)&&(fromTool == true)) |
| { |
| // since we have recieved the result, we can send the information back to QTP |
| o = requestResultObjArray[0] as Object; |
| detailsSentToTool = true; |
| } |
| } |
| |
| } |
| catch(e:Error) |
| { |
| throw e; |
| } |
| return o; |
| }); |
| } |
| |
| /** |
| * @private |
| */ |
| public function getTabularData(objID:String, begin:uint = 0, end:uint = 0, fromTool:Boolean = true):Object |
| { |
| return useErrorHandler(function():Object |
| { |
| var o:Object = { result:null, error:0 }; |
| try |
| { |
| var rid:AutomationID = AutomationID.parse(objID); |
| // we need to find out whether the current app and the |
| // reuired app are the same. |
| var requiredApplicationName:String = getApplicationNameFromAutomationID(rid); |
| var currentApplicationName:String = getApplicationName(); |
| if(requiredApplicationName == currentApplicationName) |
| { |
| if (fromTool == true) |
| detailsSentToTool = true; |
| var obj:IAutomationObject = automationManager.resolveIDToSingleObject(rid); |
| var td:IAutomationTabularData = automationManager.getTabularData(obj); |
| o.result = { |
| columnTitles: td ? td.columnNames : [], |
| tableData: (td |
| ? td.getValues(begin, end) |
| : [[]]) |
| }; |
| } |
| else |
| { |
| // we need to send this as information to the other application |
| // and let the appropriate application handle it. |
| |
| // #IMP: MARSHALLING NOTE#: This order of ariguments should not be changed |
| // across versions. If any new arguements is needed in new versions |
| // add them to the end of the list and handle appropriately in the |
| // handler of this event. |
| var details:Array = new Array(); |
| details.push(objID); |
| details.push(begin); |
| details.push(end); |
| if(fromTool == true) |
| { |
| requestPending = false; |
| resultRecieved = false; |
| } |
| o.result = handleRequestToDifferentApplication(requiredApplicationName, |
| ToolMarshallingEvent.GET_TABULAR_DATA,details); |
| if((resultRecieved == true)&&(fromTool == true)) |
| { |
| // since we have recieved the result, we can send the information back to QTP |
| o = requestResultObjArray[0] as Object; |
| detailsSentToTool = true; |
| } |
| } |
| |
| } |
| catch(e:Error) |
| { |
| throw e; |
| } |
| return o; |
| }); |
| } |
| |
| public function getTabularAttributes(objID:String, fromTool:Boolean = true):Object |
| { |
| return useErrorHandler(function():Object |
| { |
| var o:Object = { result:null, error:0 }; |
| try |
| { |
| var rid:AutomationID = AutomationID.parse(objID); |
| // we need to find out whether the current app and the |
| // reuired app are the same. |
| var requiredApplicationName:String = getApplicationNameFromAutomationID(rid); |
| var currentApplicationName:String = getApplicationName(); |
| if(requiredApplicationName == currentApplicationName) |
| { |
| if (fromTool == true) |
| detailsSentToTool = true; |
| var obj:IAutomationObject = automationManager.resolveIDToSingleObject(rid); |
| var td:IAutomationTabularData = automationManager.getTabularData(obj); |
| o.result = { |
| minVisibleRow: td ? td.firstVisibleRow : [], |
| maxVisibleRow: td ? td.lastVisibleRow : [], |
| fullSize: td ? td.numRows : [] |
| }; |
| } |
| else |
| { |
| // we need to send this as information to the other application |
| // and let the appropriate application handle it. |
| |
| // #IMP: MARSHALLING NOTE#: This order of ariguments should not be changed |
| // across versions. If any new arguements is needed in new versions |
| // add them to the end of the list and handle appropriately in the |
| // handler of this event. |
| var details:Array = new Array(); |
| details.push(objID); |
| if(fromTool == true) |
| { |
| requestPending = false; |
| resultRecieved = false; |
| } |
| o.result = handleRequestToDifferentApplication(requiredApplicationName, |
| ToolMarshallingEvent.GET_TABULAR_ATTRIBUTES,details); |
| if((resultRecieved == true)&&(fromTool == true)) |
| { |
| // since we have recieved the result, we can send the information back to QTP |
| o = requestResultObjArray[0] as Object; |
| detailsSentToTool = true; |
| } |
| } |
| |
| } |
| catch(e:Error) |
| { |
| throw e; |
| } |
| return o; |
| }); |
| } |
| |
| /** |
| * @private |
| */ |
| private function useErrorHandler(f:Function):Object |
| { |
| var o:Object = { result:null, error:0 }; |
| try |
| { |
| o = f(); |
| } |
| catch (e:Error) |
| { |
| lastError = e; |
| o.error = (e is AutomationError |
| ? AutomationError(e).code |
| : AutomationError.ILLEGAL_OPERATION); |
| Automation.automationDebugTracer.traceMessage("ToolAdapter","setErrorHandler()",e.message); |
| } |
| return o; |
| } |
| |
| /** |
| * @private |
| */ |
| private function getDescriptionXML(rid:AutomationID, |
| target:IAutomationObject):XML |
| { |
| var obj:IAutomationObject = target; |
| var result:XML; |
| while (obj) |
| { |
| var part:AutomationIDPart = rid.removeLast(); |
| if (automationManager.showInHierarchy(obj) || target == obj) |
| { |
| var automationClass:String = automationManager.getAutomationClassName(obj); |
| var automationName:String = part.automationName; |
| |
| //build description xml - probably could use the same methods |
| //that learn and activescreen use, but those were added later |
| //and this has been working so don't fix it |
| var x:XML = (<Element type={automationClass} |
| name={automationName}/>); |
| for (var i:String in part) |
| x.appendChild(<Property name={i} value={part[i] != null ? part[i] : ""}/>); |
| |
| if (result) |
| x.appendChild(result); |
| result = x; |
| } |
| obj = automationManager.getParent(obj); |
| } |
| return new XML(result); |
| } |
| |
| /** |
| * @private |
| */ |
| private function createPartFromFilterXML(filterXMLString:String):AutomationIDPart |
| { |
| var part:AutomationIDPart = new AutomationIDPart(); |
| var filterXML:XML = new XML(filterXMLString); |
| for (var o:Object in filterXML.Property) |
| { |
| var propertyNode:XML = filterXML.Property[o]; |
| var name:String = propertyNode.@Name.toString(); |
| var value:String = propertyNode.@Value.toString(); |
| |
| if(name.toLowerCase() == "automationname") |
| name = "automationName"; |
| else if(name.toLowerCase() == "automationindex") |
| name = "automationIndex"; |
| else if(name.toLowerCase() == "classname") |
| name = "className"; |
| else if(name.toLowerCase() == "id") |
| name = "id"; |
| |
| if (propertyNode.@RegExp.toString() == "true") |
| part[name] = new RegExp(value); |
| else |
| part[name] = value; |
| } |
| |
| if (filterXML.@Type && filterXML.@Type.toString().length != 0) |
| part["automationClassName"] = filterXML.@Type.toString(); |
| |
| return part; |
| } |
| |
| /** |
| * @private |
| */ |
| private function getActiveOrLearnXMLTree(objID:String, |
| addChildren:Boolean, |
| filterXML:String = "", |
| addActiveInfo:Boolean = false, |
| leftOffset:int = -1, |
| topOffset:int = -1):Object |
| { |
| var rid:AutomationID = AutomationID.parse(objID); |
| var activeAO:IAutomationObject = automationManager.resolveIDToSingleObject(rid); |
| var rids:Array = addActiveInfo ? null : []; |
| |
| //add the current item |
| var activeNode:XML = getActiveOrLearnScreenXML(rids, |
| activeAO, |
| true, |
| addActiveInfo, |
| leftOffset, |
| topOffset); |
| |
| //add the children |
| if (addChildren) |
| getActiveOrLearnChildrenXML(rids, |
| activeAO, |
| filterXML, |
| activeNode, |
| addActiveInfo, |
| leftOffset, |
| topOffset); |
| |
| //add the parents |
| var result:XML = getActiveOrLearnParentsXML(rids, |
| automationManager.getParent(activeAO), |
| activeNode, |
| addActiveInfo, |
| leftOffset, |
| topOffset); |
| |
| // We are storing the actual pretty printing value so that we can |
| // reset it back when we are done with our operation. |
| // Ref: http://bugs.adobe.com/jira/browse/FLEXENT-1140 |
| var actualPrettyPrinting:Boolean = XML.prettyPrinting; |
| |
| XML.prettyPrinting = false; |
| var resultXMLString:String; |
| var objectIdPart:AutomationIDPart = rid.removeFirst(); |
| var windowId:String = automationManager.getAIRWindowUniqueIDFromAutomationIDPart(objectIdPart); |
| // using the check to see if we are requesting activeScreen XML or learn XML |
| // activeScreenXML requires the outermost element to contain the bounding rectangle |
| // learn XML doesnot require this. |
| |
| // We are using activeWindow API in order to get the rectangle corresponding to |
| // the active window instead of getting the top level application's always. |
| // http://bugs.adobe.com/jira/browse/FLEXENT-1123 |
| var appObj:Object = AutomationHelper.getActiveWindow(windowId); |
| var rect:Array = automationManager.getRectangle(appObj as DisplayObject); |
| |
| if(leftOffset != -1) |
| { |
| var wrapper:XML = <Element> |
| <Rectangle left={leftOffset} top={topOffset} |
| right={leftOffset + rect[0] + appObj.screen.right} |
| bottom = {topOffset + rect[1] + appObj.screen.bottom}/> |
| </Element>; |
| wrapper.appendChild(result); |
| resultXMLString = String(wrapper.toXMLString()); |
| } |
| |
| else |
| resultXMLString = String(result.toXMLString()); |
| |
| XML.prettyPrinting = actualPrettyPrinting; |
| return {learnChildrenXML: resultXMLString, childrenIDs: rids}; |
| } |
| |
| /** |
| * @private |
| */ |
| private function getActiveOrLearnParentsXML(rids:Array, |
| currentAO:IAutomationObject, |
| currentNode:XML = null, |
| addActiveInfo:Boolean = false, |
| leftOffset:int = -1, |
| topOffset:int = -1):XML |
| { |
| while (currentAO != null) |
| { |
| var newNode:XML = getActiveOrLearnScreenXML(rids, |
| currentAO, |
| false, |
| addActiveInfo, |
| leftOffset, |
| topOffset); |
| newNode.appendChild(currentNode); |
| |
| currentNode = newNode; |
| currentAO = automationManager.getParent(currentAO); |
| } |
| |
| return currentNode; |
| } |
| |
| /** |
| * @private |
| */ |
| private function getActiveOrLearnChildrenXML(rids:Array, |
| parentAO:IAutomationObject, |
| filterXMLString:String, |
| parentNode:XML, |
| addActiveInfo:Boolean = false, |
| leftOffset:int = -1, |
| topOffset:int = -1):void |
| { |
| if (parentAO.numAutomationChildren == 0) |
| return; |
| |
| //convert the XML filter to a part - note QTP hasn't implemented the filter part yet |
| var part:AutomationIDPart = createPartFromFilterXML(filterXMLString); |
| var children:Array = automationManager.getChildrenFromIDPart(parentAO, part); |
| |
| for (var i:int = 0; i < children.length; ++i) |
| { |
| var childAO:IAutomationObject = children[i]; |
| |
| //we probably can skip anything that doesn't show in the hieararchy |
| //remove this if this assumption turns out to be untrue (but comment as to why) |
| if (!automationManager.showInHierarchy(childAO)) |
| continue; |
| |
| var childNode:XML = getActiveOrLearnScreenXML(rids, childAO, false, addActiveInfo, leftOffset, topOffset); |
| parentNode.appendChild(childNode); |
| |
| getActiveOrLearnChildrenXML(rids, childAO, filterXMLString, childNode, false, leftOffset, topOffset); |
| } |
| } |
| |
| /** |
| * @private |
| * Prepares the XML description of the component along with bounding rectangle. |
| * This function is used for active screen recording as well as returning information |
| * for learning objects. |
| * |
| * @param leftOffset left coordinate of the player |
| * |
| * @param topOffset top coordinate of player |
| */ |
| private function getActiveOrLearnScreenXML(rids:Array, |
| currentAO:IAutomationObject, |
| isActiveAO:Boolean = false, |
| addActiveInfo:Boolean = false, |
| leftOffset:int = -1, |
| topOffset:int= -1):XML |
| { |
| var automationClass:String = automationManager.getAutomationClassName(currentAO); |
| var automationName:String = automationManager.getAutomationName(currentAO); |
| |
| if (rids != null) |
| rids.push(automationManager.createID(currentAO).toString()); |
| |
| // build description xml |
| var result:XML = (addActiveInfo |
| ? (<Element type={automationClass} |
| name={automationName} |
| isActiveElement={isActiveAO}> |
| </Element>) |
| : (<Element type={automationClass} |
| name={automationName} |
| index={rids != null ? rids.length - 1 : 0}> |
| </Element>) |
| |
| ); |
| |
| //add properties |
| var values:Array = automationManager.getProperties(currentAO, null, addActiveInfo, true); |
| |
| var descriptors:Array = getPropertyDescriptors(currentAO, null, addActiveInfo, true); |
| |
| var properties:Array = encodeValues(currentAO, values, descriptors); |
| |
| for (var i:uint = 0; i < properties.length; i++) |
| { |
| var name:String = properties[i].descriptor.name; |
| var value:String = properties[i].value != null ? properties[i].value : ""; |
| var forDescription:Boolean = properties[i].descriptor.forDescription; |
| |
| var childXML:XML = (addActiveInfo |
| ? <Property name={name} |
| value={value} |
| forDescription={forDescription}/> |
| : <Property name={name} |
| value={value}/>); |
| |
| result.appendChild(childXML); |
| } |
| |
| //add screen coordinates |
| if (addActiveInfo) |
| { |
| var rect:Array = automationManager.getRectangle(currentAO as DisplayObject); |
| result.appendChild(<Rectangle left={leftOffset + rect[0]} |
| top={topOffset + rect[1]} |
| right={leftOffset + rect[2]} |
| bottom={topOffset + rect[3]} />); |
| } |
| |
| return result; |
| } |
| |
| /** |
| * @private |
| * Converts Tool specific strings to proper values. |
| */ |
| private function convertArrayFromCrazyToAs(a:String):Array |
| { |
| var result:Array = a.split("__MX_ARG_SEP__"); |
| for (var i:uint = 0; i < result.length; i++) |
| { |
| if (result[i] == "__MX_NULL__") |
| result[i] = null; |
| } |
| return result; |
| } |
| |
| /** |
| * Decodes an array of properties from a testing tool into an AS object. |
| * using the codecs. |
| * |
| * @param obj the object that contains the properties to be encoded. |
| * |
| * @param args the property values to transcode. |
| * |
| * @param propertyDescriptors the property descriptors that describes the properties for this object. |
| * |
| * @param relativeParent the IAutomationObject that is related to this object. |
| * |
| * @return the decoded property value. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 4 |
| */ |
| public function decodeProperties(obj:Object, |
| args:Array, |
| propertyDescriptors:Array, |
| interactionReplayer:IAutomationObject):void |
| { |
| for (var i:int = 0; i < propertyDescriptors.length; i++) |
| { |
| var value:String = null; |
| if (args != null && |
| i < args.length && |
| args[i] == "null" && |
| propertyDescriptors[i].defaultValue == "null") |
| args[i] = null; |
| if (args != null && |
| i < args.length && |
| ((args[i] != null && args[i] != "") || propertyDescriptors[i].defaultValue == null)) |
| setPropertyValue(obj, |
| args[i], |
| propertyDescriptors[i], |
| interactionReplayer); |
| else if (propertyDescriptors[i].defaultValue != null) |
| setPropertyValue(obj, |
| (propertyDescriptors[i].defaultValue == "null" |
| ? null |
| : propertyDescriptors[i].defaultValue), |
| propertyDescriptors[i], |
| interactionReplayer); |
| else |
| { |
| var message:String = resourceManager.getString( |
| "automation_agent", "missingArgument", |
| [propertyDescriptors[i].name]); |
| throw new Error(message); |
| } |
| } |
| } |
| |
| |
| /** |
| * @private |
| */ |
| public function setPropertyValue(obj:Object, |
| value:Object, |
| pd:ToolPropertyDescriptor, |
| relativeParent:IAutomationObject = null):void |
| { |
| var codec:IAutomationPropertyCodec = propertyCodecMap[pd.codecName]; |
| |
| if (codec == null) |
| codec = propertyCodecMap["object"]; |
| |
| if (relativeParent == null) |
| relativeParent = obj as IAutomationObject; |
| |
| codec.decode(automationManager, obj, value, pd, relativeParent); |
| } |
| |
| /** |
| * @private |
| */ |
| public static function getCodecHelper():IToolCodecHelper |
| { |
| return qtpCodecHelper; |
| } |
| |
| public static function set applicationType( appType:int):void |
| { |
| _applicationType = appType; |
| } |
| |
| public static function get applicationType():int |
| { |
| return _applicationType; |
| } |
| |
| public static function set applicationId( appId:String):void |
| { |
| _applicationId = appId; |
| } |
| |
| public static function get applicationId():String |
| { |
| return _applicationId; |
| } |
| /* |
| // this will give the stage boundary for AIR apps. |
| public static function getStageBoundaryInScreenCoords(applicationId:String):Rectangle |
| { |
| |
| var stageBoundary:Rectangle; |
| var stageHeight:int; |
| var stageWidth:int; |
| var allPropFound:Boolean= false; |
| |
| // get the application start cooridnate in screen points |
| //&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& |
| var stageStartPointInScreenCoordinates:Point; |
| |
| // get the type of the application. |
| if(_applicationType == ToolAdapter.ApplicationType_AIR) |
| { |
| var airFunctionHandler:Class = null; |
| try |
| { |
| allPropFound = true; |
| airFunctionHandler = getAirFunctionHelperClass("stageHeight,stageWidth,stageStartCoordinates"); |
| if(airFunctionHandler) |
| { |
| var obj:Object = new airFunctionHandler(applicationId); |
| |
| if(obj.hasOwnProperty("stageStartCoordinates")) |
| stageStartPointInScreenCoordinates = obj["stageStartCoordinates"]; |
| else |
| allPropFound = false; |
| |
| |
| if(obj.hasOwnProperty("stageWidth")) |
| stageWidth = obj["stageWidth"]; |
| else |
| allPropFound = false; |
| |
| |
| if(obj.hasOwnProperty("stageHeight")) |
| stageHeight = obj["stageHeight"]; |
| else |
| allPropFound = false; |
| |
| |
| } |
| |
| } |
| catch(e:Error) |
| { |
| trace("stageHeight,stageWidth, stageStartCoordinates - In AIR we are supposed to have class 'mx.automation.air.AirFunctionsHelper'."); |
| // TBD. Converting this as user message and adding this in the locales. |
| |
| } |
| if(allPropFound == false) |
| { |
| trace("stageHeight - In AIR we are supposed to have class 'mx.automation.air.AirFunctionsHelper' with stageHeight,stageWidth, stageStartCoordinates as properties."); |
| // TBD. Converting this as user message and adding this in the locales. |
| } |
| } |
| else // we are in flex app |
| { |
| // get the application start coordinate from the browsers |
| //stageStartPointInScreenCoordinates = ExternalInterfaceMethods_AS.getApplicationStartPointInScreenCoordinates(_applicationId); |
| stageHeight = Application.application.height; |
| stageWidth = Application.application.width; |
| stageStartPointInScreenCoordinates = new Point(0, 0); |
| //stageStartPointInScreenCoordinates = (Automation.automationManager2 as IAutomationManager2).getStartPoint(); |
| |
| } |
| //&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& |
| if(stageStartPointInScreenCoordinates) |
| { |
| |
| // get the application boudary Array in screen cooridnates. |
| |
| stageBoundary = new Rectangle(stageStartPointInScreenCoordinates.x, |
| stageStartPointInScreenCoordinates.y, |
| stageWidth, |
| stageHeight); |
| } |
| |
| return stageBoundary; |
| } |
| */ |
| |
| public static function getStageStartPointInScreenCoords(windowId:String ):Point |
| { |
| var stageStartPoint:Point = new Point(0,0) |
| try |
| { |
| stageStartPoint = AutomationHelper.getStageStartPointInScreenCoords(windowId); |
| } |
| catch(e:Error) |
| { |
| showAirHelperNotFoundMessage(); |
| Automation.automationDebugTracer.traceMessage("ToolAdapter","stageStartCoordinates()", AutomationConstants.missingAIRClass); |
| } |
| return stageStartPoint; |
| } |
| |
| public function convertScreenPointToStagePoint(screenPoint:Point, applicationId:String):Point |
| { |
| var stageStartPoint:Point = getStageStartPointInScreenCoords(applicationId) |
| var stagePoint:Point; |
| |
| // convert the point to app cooridnates |
| stagePoint = new Point(screenPoint.x-stageStartPoint.x, screenPoint.y-stageStartPoint.y); |
| return stagePoint; |
| |
| } |
| |
| |
| public function getAppTitle():String |
| { |
| var title:String = ""; |
| try |
| { |
| title = AutomationHelper.getAppTitle(); |
| } |
| catch(e:Error) |
| { |
| showAirHelperNotFoundMessage(); |
| Automation.automationDebugTracer.traceMessage("ToolAdapter","appTitle()", AutomationConstants.missingAIRClass); |
| // TBD. Converting this as user message and adding this in the locales. |
| } |
| return title; |
| } |
| |
| |
| /*public function getChromeHeight():int |
| { |
| var chromeHeight:int = 0; // default for flex = 0; |
| var allPropFound:Boolean= false; |
| |
| // get the type of the application. |
| if(_applicationType == ToolAdapter.ApplicationType_AIR) |
| { |
| var airFunctionHandler:Class = null; |
| try |
| { |
| airFunctionHandler = getAirFunctionHelperClass("chromeHeight"); |
| if(airFunctionHandler) |
| { |
| var obj:Object = new airFunctionHandler(null); |
| |
| if(obj.hasOwnProperty("chromeHeight")) |
| { |
| chromeHeight = obj["chromeHeight"]; |
| allPropFound = true; |
| } |
| } |
| |
| } |
| catch(e:Error) |
| { |
| trace("chromeHeight - In AIR we are supposed to have class 'mx.automation.air.AirFunctionsHelper'."); |
| // TBD. Converting this as user message and adding this in the locales. |
| |
| } |
| if(allPropFound == false) |
| { |
| trace("chromeHeight - In AIR we are supposed to have class 'mx.automation.air.AirFunctionsHelper' with chromeHeight property."); |
| // TBD. Converting this as user message and adding this in the locales. |
| } |
| } |
| return chromeHeight; |
| |
| |
| } |
| private static var classLoadingFailed:Boolean = false; |
| public function isAirClassLoaded():Boolean |
| { |
| return !classLoadingFailed; |
| } |
| |
| private static function getAirFunctionHelperClass(prpertyName:String):Class |
| { |
| if(!classLoadingFailed) |
| { |
| try |
| { |
| return Class(getDefinitionByName("mx.automation.air.AirFunctionsHelper")); |
| } |
| catch (e:Error) |
| { |
| var message:String = showAirHelperNotFoundMessage(); |
| classLoadingFailed = true; |
| throw new Error(message); |
| } |
| } |
| return null; |
| |
| } |
| public function getChromeWidth():int |
| { |
| var chromeWidth:int = 0; // default for flex = 0; |
| var allPropFound:Boolean= false; |
| |
| // get the type of the application. |
| if(_applicationType == ToolAdapter.ApplicationType_AIR) |
| { |
| var airFunctionHandler:Class = null; |
| try |
| { |
| airFunctionHandler = getAirFunctionHelperClass("chromeWidth"); |
| if(airFunctionHandler) |
| { |
| var obj:Object = new airFunctionHandler(null); |
| |
| if(obj.hasOwnProperty("chromeWidth")) |
| { |
| chromeWidth = obj["chromeWidth"]; |
| allPropFound = true; |
| } |
| } |
| |
| } |
| catch(e:Error) |
| { |
| trace("chromeWidth - In AIR we are supposed to have class 'mx.automation.air.AirFunctionsHelper'."); |
| // TBD. Converting this as user message and adding this in the locales. |
| |
| } |
| if(allPropFound == false) |
| { |
| trace("chromeWidth - - In AIR we are supposed to have class 'mx.automation.air.AirFunctionsHelper' with chromeWidth property."); |
| // TBD. Converting this as user message and adding this in the locales. |
| } |
| } |
| return chromeWidth; |
| }*/ |
| |
| private function getApplicationName():String |
| { |
| return automationManager.getUniqueApplicationID(); |
| } |
| |
| private function getApplicationNameFromObjectIDString(objectID:String):String |
| { |
| var rid:AutomationID = AutomationID.parse(objectID); |
| |
| return getApplicationNameFromAutomationID(rid); |
| } |
| |
| private function getApplicationNameFromAutomationID(objectID:AutomationID):String |
| { |
| // clone the automationID |
| var rid:AutomationID = objectID.clone(); |
| |
| //remove the application |
| var part:AutomationIDPart = rid.removeFirst(); |
| |
| return automationManager.getApplicationNameFromAutomationIDPart (part); |
| |
| /* |
| |
| |
| |
| // check whether the current class is an AIR window as it is the another object |
| // which can be the first level |
| // we have added a property by name 'applicationName' which is applicable only |
| // for the top level windows for AIR |
| if (part.hasOwnProperty("applicationName")) |
| return (part["applicationName"].toString()); |
| |
| |
| // if we reach here we are not the AIR top level window |
| // hence we can use the automationName to get the automation class name |
| return (part["automationName"].toString()); |
| */ |
| } |
| |
| |
| public function dispatchMarshalledEvent(type:String, applicationName:String , details1:Array):void |
| { |
| |
| // This method is called to send all events from the root Automation Manager to the sub applicaitons. |
| // we need to store the information that the we have sent the information and we are waiting |
| // for the reply |
| lastApplicationName = applicationName; |
| lastRequestName = type; |
| requestPending = true; |
| |
| var marshalledEvent:ToolMarshallingEvent |
| = new ToolMarshallingEvent(type); |
| marshalledEvent.applicationName = applicationName; |
| marshalledEvent.interAppDataToSubApp = details1; |
| |
| |
| dispatchEventToChildren(marshalledEvent); |
| |
| } |
| |
| |
| public function dispatchMarshalledReplyEvent(type:String, applicationName:String , details:Array):void |
| { |
| |
| |
| var marshalledEvent:ToolMarshallingEvent |
| = new ToolMarshallingEvent(type); |
| marshalledEvent.applicationName = applicationName; |
| marshalledEvent.interAppDataToMainApp = details; |
| |
| |
| dispatchEventToParent(marshalledEvent); |
| |
| } |
| |
| private function dispatchEventToParent(event:Event):void |
| { |
| automationManager.dispatchToParent(event); |
| } |
| |
| private function dispatchEventToChildren(event:Event):void |
| { |
| automationManager.dispatchToAllChildren(event); |
| } |
| |
| |
| private function handleRequestToDifferentApplication(requiredApplicationName:String, |
| requestType:String , details:Array):Array |
| { |
| // clear the result object array so that we have only the result of the |
| // current request |
| requestResultObjArray = new Array(); |
| |
| dispatchMarshalledEvent( requestType,requiredApplicationName,details ); |
| return null; |
| } |
| |
| |
| /** |
| * @private |
| */ |
| private var lastResponseRecievedApplicationName:String; |
| |
| |
| /** |
| * @private |
| */ |
| private var inReplySendingToParent:Boolean = false; |
| private function interAppReplyHandler(eventObj:Event) :void |
| { |
| // Marshalling events are needeed across applicaiton domain |
| // so this conversion shall fail in the same domain |
| // i.e the above check is to avoid the echoing |
| if(eventObj is ToolMarshallingEvent) |
| return; |
| |
| if(inReplySendingToParent) |
| return; |
| |
| // if we are not the root application we need not handle the reply, just pass it to the parent |
| //if(smMSm && (smMSm.useSWFBridge() == true)) |
| if(sm.isTopLevelRoot() == false) |
| { |
| inReplySendingToParent = true; |
| var eventObj1:ToolMarshallingEvent = ToolMarshallingEvent.marshal(eventObj); |
| dispatchEventToParent(eventObj1); |
| inReplySendingToParent = false; |
| } |
| else |
| { |
| // we got the last event details |
| resultRecieved = true; |
| // this handler happens in the root application |
| // so we need to find out which was the application last responded to the last request |
| // we need this information to get the last error. |
| // the only case where we recieve reply from a non relevant application also |
| // is for the getElementFromPoint. However for this case, we dont expect |
| // a last error. and the final handling of the getElement from happens in the |
| // main application, hence we will handle this variable appropriately in that |
| // method separately. |
| lastResponseRecievedApplicationName = (eventObj["applicationName"]); |
| |
| // we need a special handling if the event was |
| // get element from point as we expect results from different applicaiton |
| // so we need to add them to the array instead of storing in the result object. |
| |
| if(eventObj.type == ToolMarshallingEvent.GET_ELEMENT_FROM_POINT_REPLY) |
| { |
| // dont assign the value to the array, instead add to the array |
| requestResultObjArray.push(eventObj["interAppDataToMainApp"][0]); |
| } |
| else |
| requestResultObjArray= (eventObj["interAppDataToMainApp"]); |
| } |
| |
| |
| } |
| |
| private var inRequestSendingToChildren:Boolean = false; |
| /** |
| * @private |
| */ |
| private function interAppRequestHandler(eventObj:Event) :void |
| { |
| // Marshalling events are needeed across applicaiton domain |
| // so this conversion shall fail in the same domain |
| // i.e the above check is to avoid the echoing |
| if(eventObj is ToolMarshallingEvent) |
| return; |
| |
| if(inRequestSendingToChildren) |
| return; |
| |
| var appName:String = getApplicationName(); |
| var details:Array = new Array(); |
| var type:String; |
| var resultObj:Object; |
| var objectID:String; |
| var filterXML:String; |
| |
| if((eventObj["applicationName"] == appName)||(eventObj["applicationName"] == null)) |
| { |
| var dispatchEvent:Boolean = true; |
| |
| if(eventObj.type == ToolMarshallingEvent.FIND_OBJECTIDS) |
| { |
| var descriptionXML:String = eventObj["interAppDataToSubApp"][0] as String; |
| resultObj = findObjectIDs(descriptionXML, false)["result"]; |
| details.push(resultObj); |
| type = ToolMarshallingEvent.FIND_OBJECTIDS_REPLY; |
| } |
| else if (eventObj.type == ToolMarshallingEvent.RUN) |
| { |
| //run(objID:String, method:String, args:String):Object |
| objectID = eventObj["interAppDataToSubApp"][0]; |
| var method:String = eventObj["interAppDataToSubApp"][1]; |
| var args:String = eventObj["interAppDataToSubApp"][2]; |
| resultObj = run(objectID,method,args,false); |
| details.push(resultObj); |
| type = ToolMarshallingEvent.RUN_REPLY; |
| |
| } |
| else if (eventObj.type == ToolMarshallingEvent.GET_ACTIVESCREEN) |
| { |
| //run(objID:String, method:String, args:String):Object |
| var level:int = eventObj["interAppDataToSubApp"][0]; |
| objectID = eventObj["interAppDataToSubApp"][1]; |
| var leftOffset:int = eventObj["interAppDataToSubApp"][2]; |
| var topOffset:int = eventObj["interAppDataToSubApp"][3]; |
| resultObj = getActiveScreen(level,objectID,leftOffset,topOffset,false); |
| details.push(resultObj); |
| type = ToolMarshallingEvent.GET_ACTIVESCREEN_REPLY; |
| } |
| else if (eventObj.type == ToolMarshallingEvent.GET_PARENT) |
| { |
| objectID = eventObj["interAppDataToSubApp"][0]; |
| resultObj = getParent(objectID,false); |
| details.push(resultObj); |
| type = ToolMarshallingEvent.GET_RECTANGLE_REPLY; |
| } |
| else if (eventObj.type == ToolMarshallingEvent.GET_RECTANGLE) |
| { |
| objectID = eventObj["interAppDataToSubApp"][0]; |
| resultObj = getRectangle(objectID,false); |
| details.push(resultObj); |
| type = ToolMarshallingEvent.GET_RECTANGLE_REPLY; |
| } |
| else if (eventObj.type == ToolMarshallingEvent.GET_ELEMENT_FROM_POINT) |
| { |
| var x:int = eventObj["interAppDataToSubApp"][0]; |
| var y:int = eventObj["interAppDataToSubApp"][1]; |
| var appId:String = eventObj["interAppDataToSubApp"][2] as String; |
| resultObj = getElementFromPoint(x,y,appId,false); |
| if((resultObj["result"] == "" )||(resultObj["result"] == null)) |
| dispatchEvent = false; |
| else |
| { |
| details.push(resultObj); |
| type = ToolMarshallingEvent.GET_ELEMENT_FROM_POINT_REPLY; |
| } |
| } |
| else if (eventObj.type == ToolMarshallingEvent.GET_ELEMENT_TYPE) |
| { |
| objectID = eventObj["interAppDataToSubApp"][0]; |
| resultObj = getElementType(objectID,false); |
| details.push(resultObj); |
| type = ToolMarshallingEvent.GET_ELEMENT_TYPE_REPLY; |
| } |
| else if (eventObj.type == ToolMarshallingEvent.GET_DISPLAY_NAME) |
| { |
| objectID = eventObj["interAppDataToSubApp"][0]; |
| resultObj = getDisplayName(objectID,false); |
| details.push(resultObj); |
| type = ToolMarshallingEvent.GET_DISPLAY_NAME_REPLY; |
| } |
| else if (eventObj.type == ToolMarshallingEvent.GET_PROPERTIES) |
| { |
| objectID = eventObj["interAppDataToSubApp"][0]; |
| var names:String = eventObj["interAppDataToSubApp"][1]; |
| resultObj = getProperties(objectID,names,false); |
| details.push(resultObj); |
| type = ToolMarshallingEvent.GET_PROPERTIES_REPLY; |
| } |
| else if (eventObj.type == ToolMarshallingEvent.BUILD_DESCRIPTION) |
| { |
| objectID = eventObj["interAppDataToSubApp"][0]; |
| resultObj = buildDescription(objectID,false); |
| details.push(resultObj); |
| type = ToolMarshallingEvent.BUILD_DESCRIPTION_REPLY; |
| } |
| else if (eventObj.type == ToolMarshallingEvent.GET_CHILDREN) |
| { |
| objectID = eventObj["interAppDataToSubApp"][0]; |
| filterXML = eventObj["interAppDataToSubApp"][1]; |
| resultObj = getChildren(objectID,filterXML,false); |
| details.push(resultObj); |
| type = ToolMarshallingEvent.GET_CHILDREN_REPLY; |
| } |
| else if (eventObj.type == ToolMarshallingEvent.LEARN_CHILD_OBJECTS) |
| { |
| objectID = eventObj["interAppDataToSubApp"][0]; |
| var filterXML1:String = eventObj["interAppDataToSubApp"][1]; |
| resultObj = learnChildObjects(objectID,filterXML1,false); |
| details.push(resultObj); |
| type = ToolMarshallingEvent.LEARN_CHILD_OBJECTS_REPLY; |
| } |
| else if (eventObj.type == ToolMarshallingEvent.GET_LAST_ERROR) |
| { |
| resultObj = getLastError(false); |
| details.push(resultObj); |
| type = ToolMarshallingEvent.GET_LAST_ERROR_REPLY; |
| } |
| else if (eventObj.type == ToolMarshallingEvent.SET_LAST_ERROR) |
| { |
| var message:String = eventObj["interAppDataToSubApp"][0]; |
| setLastError(message,false); |
| dispatchEvent = false; // there is no reply for the setLast error |
| } |
| else if (eventObj.type == ToolMarshallingEvent.GET_TABULAR_ATTRIBUTES) |
| { |
| objectID = eventObj["interAppDataToSubApp"][0]; |
| resultObj = getTabularAttributes(objectID,false); |
| details.push(resultObj); |
| type = ToolMarshallingEvent.GET_TABULAR_ATTRIBUTES_REPLY; |
| } |
| else if (eventObj.type == ToolMarshallingEvent.GET_TABULAR_DATA) |
| { |
| objectID = eventObj["interAppDataToSubApp"][0]; |
| var begin:int = eventObj["interAppDataToSubApp"][1]; |
| var end:int = eventObj["interAppDataToSubApp"][2]; |
| resultObj = getTabularData(objectID,begin,end,false); |
| details.push(resultObj); |
| type = ToolMarshallingEvent.GET_TABULAR_DATA_REPLY; |
| } |
| |
| if (dispatchEvent == true) |
| dispatchMarshalledReplyEvent(type,appName,details); |
| if(eventObj.type == ToolMarshallingEvent.GET_ELEMENT_FROM_POINT) |
| { |
| inRequestSendingToChildren = true; |
| var eventObj1:ToolMarshallingEvent = ToolMarshallingEvent.marshal(eventObj); |
| dispatchEventToChildren(eventObj1); |
| inRequestSendingToChildren = false; |
| } |
| |
| } |
| else |
| { |
| inRequestSendingToChildren = true; |
| var eventObj2:ToolMarshallingEvent = ToolMarshallingEvent.marshal(eventObj); |
| dispatchEventToChildren(eventObj2); |
| inRequestSendingToChildren = false; |
| } |
| |
| } |
| |
| |
| private function newWindowHandler(event:AutomationAirEvent):void |
| { |
| // we need to inform the socket handler to communicate to the plugin |
| // to get the hwnd for this new window. |
| if(ToolAgent.clientSocketHandler) |
| (ToolAgent.clientSocketHandler).processNewWindowInformation(event.windowId); |
| } |
| |
| |
| |
| |
| |
| |
| private static var connectionAttemptAlert:Alert; |
| private static var successMessageAlert:Alert; |
| public static function showConnectionAttemptMessage():String |
| { |
| var message:String = resourceManager.getString("tool_air","qtpConnectionAttempt"); |
| connectionAttemptAlert = Alert.show( message); |
| return message; |
| } |
| |
| public static function showConnectionSuccessMessage():String |
| { |
| if(connectionAttemptAlert) |
| PopUpManager.removePopUp(connectionAttemptAlert); |
| |
| var message:String = resourceManager.getString("tool_air","qtpConnectionSuccess"); |
| successMessageAlert = Alert.show(message); |
| |
| removeSuccessMessageAlert(); |
| // let us close this |
| return message; |
| } |
| |
| |
| // we need only one type of error message. |
| private static var errorMessageDisplayed:Boolean = false; |
| |
| public static function showioErrorMessage(eventString:String):String |
| { |
| if(connectionAttemptAlert) |
| PopUpManager.removePopUp(connectionAttemptAlert); |
| |
| var message :String = resourceManager.getString( |
| "tool_air", "noConnectionToTool"); |
| |
| message = message + "\n" + resourceManager.getString( |
| "tool_air", "noConnectionToTool_Recommendation"); |
| |
| if(!errorMessageDisplayed) |
| Alert.show(message); |
| |
| errorMessageDisplayed = true; |
| |
| return message; |
| } |
| |
| |
| public static function showSecurityErrorMessage(eventString:String):String |
| { |
| if(connectionAttemptAlert) |
| PopUpManager.removePopUp(connectionAttemptAlert); |
| |
| var message :String = resourceManager.getString( |
| "tool_air", "securityError"); |
| |
| message = message + "\n" + "\n"; |
| message = message + "securityErrorHandler: " + eventString; |
| //trace (message); |
| if(!errorMessageDisplayed) |
| Alert.show(message); |
| |
| errorMessageDisplayed = true; |
| |
| return message; |
| } |
| |
| |
| public static function showConnectionFailureMessage():String |
| { |
| if(connectionAttemptAlert) |
| PopUpManager.removePopUp(connectionAttemptAlert); |
| |
| // we wait for 3000 milliseconds 3 times to check whether we |
| // could connect to QTP. |
| var message:String = resourceManager.getString("tool_air","qtpConnectionFailed"); |
| if(!errorMessageDisplayed) |
| Alert.show(message); |
| |
| |
| errorMessageDisplayed = true; |
| ClientSocketHandler.enableApplication(); |
| return message; |
| } |
| |
| |
| |
| public static function showAirHelperNotFoundMessage():String |
| { |
| if(connectionAttemptAlert) |
| PopUpManager.removePopUp(connectionAttemptAlert); |
| |
| var message:String = resourceManager.getString("tool_air", "airHelperClassNotFound"); |
| if(!errorMessageDisplayed) |
| Alert.show(message); |
| |
| errorMessageDisplayed = true; |
| return message; |
| } |
| |
| public static function removeSuccessMessageAlert():void |
| { |
| var tempTimer:Timer = new Timer(3000,1); |
| tempTimer.addEventListener(TimerEvent.TIMER,removeSuccessMessageAlertTimerHandler); |
| tempTimer.start(); |
| } |
| |
| public static function removeSuccessMessageAlertTimerHandler(event:Event):void |
| { |
| if(successMessageAlert) |
| PopUpManager.removePopUp(successMessageAlert); |
| } |
| } |
| } |