Cogitek RIATest 6 Documentation Copyright © Cogitek Inc.

Different ways to locate components in your application

When you specify actions that must be performed on your application the first thing you specify is what component you want to be located by RIATest so that an action is performed on it. The piece of code that specifies component what component to look for is called Locator for Flex objects and HtmlLocator for HTML elements and HTML-based widgets such as ExtJS objects. In recording mode RIATest automatically creates locators to specify the components with which the user interacts. For example a click on a button with 'OK' label is usually recorded as:

FlexButton("OK")=>click();

The part that precedes operator => is the Locator. It specifies that the component to find is of FlexButton class and the automation name the component is "OK". Locators can also be composed of the several parts and combined together with operator ->, in which case they specify a hierarchy of component to locate and match. For example:

FlexTitleWindow("Properties")->FlexButton("OK")=>click();

The above locator will find an button labeled "OK" and which is contained in a window with title "Properties". Multi-part locators are useful for locating components which have non-unique names. So if your application contains several "OK" buttons in different windows or panel you can use above multi-part locator to find "OK" button that is contained in the required title window.

Locators which have FlexClassName(automationName) are the most simple ones. These are usually generated by RIATest recorder and are have easy readable format. In some cases you may have components in your application that are of same Flex class and have identical automation names. In such cases additional information is required to specify which one of these components must be located. All components in all Flex containers (starting from Application container) are numerated and have so called automationIndex. automationIndex is automatically generated by Flex automation framework and usually has the form "index:some-number". When there is a need RIATest recorder will use automationIndex to define exactly which component must be located. The locator in that case will have a form FlexClassName(automationName,automationIndex), for example:

FlexButton("OK","index:3")=>click();

The above locator will find an button labeled "OK" and which is at position 3 in the container.

 

Advanced Locators

RIATest recorder always generates one of the above two forms of locators. The form without automationIndex is the simplest. The second form which uses automationIndex is the most exact and is sufficient to locate any component since automationIndex is a unique property of every component however it is not very readable and is also very sensitive to any changes in your application. If you add any component to the container all subsequent component indices are shifted and thus automationIndex of all those components is changed, breaking your test script. Another drawback of both forms of locators generated by RIATest recorder is that they must always specify the class name of the component to locate and in some cases you may want to omit this and find a component based on other properties.

To overcome the limitation of standard locator forms RIATest allows you to manually construct locators and gives you full control as to which properties must be used for finding the component. The manual locators are created using the following construct:

new Locator({propName1:value1, propName2: value2, ...}) // Create Flex object locator
// or
new HtmlLocator({propName1:value1, propName2: value2, ...}) // Create Html element locator

This statement creates a locator that will match any component which has propName1 and the value of that property is value1 and similarly for as many properties as you want. The Locator() constructor function accept an object with property-name/value pairs. You can have one or more property name/value pairs in the object specifier. The object does not have to be constructed using {} literal, it can be any valid RIAScript object.

Now let's see some examples of Locator() usage:

// This is equivalent to FlexButton("OK")
new Locator({automationClassName:"FlexButton", automationName: "OK"}) 

// This is equivalent to FlexButton("OK","index:3")
new Locator({automationClassName:"FlexButton", automationName: "OK", automationIndex:"index:3"})

// This locator will match a button with id equal to okButton
new Locator({automationClassName:"FlexButton", id: "okButton"})

// This locator will match any component with id equal to myViewId
new Locator({id: "myViewId"}) 

// This locator will match any HTML element with id equal to myInput
new HtmlLocator({id: "myInput"})

You can compose multi-part locators using Locator():

// This is equivalent to FlexTitleWindow("Properties")->FlexButton("OK")
new Locator({automationClassName:"FlexTitleWindow", automationName: "Properties"})->new Locator({automationClassName:"FlexButton", automationName: "OK"})

// Equivalent to above
FlexTitleWindow("Properties")->new Locator({automationClassName:"FlexButton", automationName: "OK"})

Important: Using the id property to locate HTML elements is the fastest search method. It is a best practice to assign in your application unique and descriptive id property values to all HTML elements and HTML-based widgets that you intend to automate using RIATest and then use id-based locators for automation. For HTML locators the following form that has # hash sign prepended to a string also uses the id property if it is available:

HtmlInput("#myInput") // locate a HTML input element having id equal to "myInput"
ExtTreePanel("#tree") // locate an ExtJS Tree Panel object having  id equal to "tree"

Regular Expressions

All above examples used strict strings to match properties of the components being located. But what if you want to perform partial matching of property value? In this cases you can use regular expressions to match property values. For example:

// Find a Flex button with label text beginning with word "Hello"
FlexButton(/Hello.*/)

// Find any Html component with automationName containing "OK" text
new HtmlLocator({automationName:/.*OK.*/})

 

Related Objects

When an action is performed on a component that must also reference another component this other component is called related object and is usually specified as a parameter to action call function. For example when performing a select() operation on a DataGrid the parameter specifies which cell in the DataGrid must be selected:

// Select row containing js,John,Smith
FlexDataGrid("dg1")=>select("*js* | John | Smith");

The parameter passed to select() event is a string. RIATest knows by looking at the definition of select() event in the class definition file that the expected parameter is a related object (automationObject codec is specified in xml file). In that case RIATest will attempt to search for the related object by starting component hierarchy traversing from the main object (DataGrid in this case). RIATest will attempt to find a child component who's automationName matches the specified string. No attempt to match class name or automationIndex is performed in such case. In this particular example RIATest will find one of the child items of the DataGrid which happens to be in a row containing "js", "John" and "Smith" cells.

This is the simplest form of related object specifiers, which is generated by RIATest recorder. However it is also possible to use all extra location methods outlined above to locate related objects. This is achieved by passing as event parameter a Locator in one of the above forms or a property name/value pair list specified as anonymous object or a regular expression to match. For example:

// This will select item with same automationName as above and in addition to that also is of FlexListLabel class
FlexDataGrid("dg1")=>select(FlexListLabel("*js* | John | Smith"));

// Select using 'data' of the cell
FlexDataGrid("dg1")=>select({data:{first:"Arthur"}});

// Using dataField to specify column and label to specify row
FlexDataGrid("dg1")=>select({listData:{dataField:"first",label:"Paul"}});

// Using full locator to specify item to select
FlexDataGrid("dg1")=>select(FlexListLabel("*js* | John | Smith"));

// Using new Locator to specify item to select
FlexDataGrid("dg1")=>select(new Locator({automationValue:"aw"}));

// Using automationValue as short form to find specific cell
FlexDataGrid("dg1")=>select({automationValue:"pw"});

// This will select row which contains text "John". Note regular expression usage.
FlexDataGrid("dg1")=>select(/.*John.*/);

As you can see new forms of specifying related objects give a lot of new possibilities for performing actions exactly in the way you want.

 


Found a typo? Have a suggestion? Please submit your request here.