The capabilities for Test Studio UI locators are founded in the ArtOfTest automation library. This means whatever was done through the Test Studio IDE is also doable from the code. All the search methods for locating an element are wrapped inside the Find class. In a WPF application, this class is accessible from any container. In our case, each window will hold a reference for this class through which we can exert our search expressions.
This has two applications in real life. The first one is when accessing an element that is not yet defined in the element repository. Hence, accessing the element becomes allowable through the dynamic evaluation of search expressions fed to the various find methods of the Find class. The accessed element can then be interacted with by applying different UI operations. The other area of application is in automating tests for UI and that is verifying properties for UI elements, and the hierarchical relation with respect to their surrounding elements. For example, making sure whether an element exists, validating its width, layout, content, and so on.
Suppose that in the previous example, we want to verify that there exists a cell with content 2611 before actually clicking on it.
In the Func-9_History_Details_Successful
test, add a script step by clicking on the Script Step button of the Add ribbon. Edit the description to the added step as follows:
this.ActiveApplication.GetWindow("File Comparer").RefreshVisualTrees();XamlFindExpression xamlFindExpression = new XamlFindExpression("XamlTag=datagrid","name=fileCmpDG","|","XamlTag=datagridrow","|","XamlTag=datagridcell","|","TextContent=~2611");Assert.IsNotNull(Applications.File_Comparerexe.File_Comparer.Find.ByExpression(xamlFindExpression));
The first statement of the code refreshes the DOM tree for the File Comparer window, in order to force Test Studio to rebuild the hierarchy element in the event of selecting a value from the dates combobox. Once the DOM is updated, it is safe to search for the newly appeared data grid item.
The second statement is responsible for building the filter expressions, where, by convention, the pipe sign (|
) is used to introduce a chained expression. The chained expressions consist of sequentially finding the data grid, data grid row, data grid cell, and then cell content as we have seen in the Find Settings window of the previous example.
The third statement uses the Assert.IsNotNull
method, which serves in verifying that the search execution did actually result in an element. The outcome of this statement will affect the test result. The search is invoked through a call to the ByExpression
method of the Find
class. The tilde sign (~
) implies that search value 2611
has to be contained inside the cell text. The remaining comparison operators are represented as follows:
!
= NotContain^
= StartsWith?
= EndsWith#
= RegEx-
= Missing+
= ExistsAfter you finish editing the method, place the coded step before the one which performs the action of clicking on the cell, then run the test and verify that the assertion was successful in Test Studio execution log.
The Find.ByExpression
method is just one way of building your expression criteria. The powerful thing about it is that it allows you to build complex filters just as we have seen with chained expression. Other methods are available, for example, to search by name using the Find.ByName
method or automation ID using the Find.ByAutomationId
method, where their parameters correspond respectively to the element name and automation ID.
Test Studio surely enables a powerful and flexible mechanism to locate UI elements without having the need to hardcode values. Despite this flexibility, remember that the elements defined by external reference are scattered among the test scripts and in the normal case the same logic for the find expression is replicated inside those tests' coded steps. Eventually, you might encounter a change to the application UI, which will cause a change to all those find expressions and that is a maintainability deficiency in your tests. As an attempt to find a solution, you strive to abstract out the element's definitions from your test's steps and centralize them at one place. Hence, any change in an inevitable UI element that falls upon your application will engender editing the find expression of that element in only one place. The solution consists of storing the different Find logic for the application elements in one physical file on your disk, and then upon any test startup a coded step is inserted to load the elements and their find expressions in a dictionary, which will be accessible throughout all the test steps. The physical file resembles a factory providing element ingredients to produce test elements at runtime.
To implement the solution:
ElementRepository.xml
file in the root
directory of the C:
of your machine.System.XML.dll
and System.XML.Linq.dll
libraries through the Show button in the Project tab Settings ribbon.Functional Tests
folder.using
statements to enable accessing the XML file through the coded steps as follows:using System.Xml; using System.Xml.Linq;
Dictionary
structure that is going to hold the elements with their respective findExpressions
:Dictionary<string, string> findExpressions = new Dictionary<string, string>();
string pathToXmlFile = @"C:ElementRepository.xml"; XElement elementRep = XElement.Load(pathToXmlFile); foreach (XElement element in elementRep.Elements("add")) { findExpressions.Add(element.Attribute("element").Value, element.Attribute("expression").Value); }
this.ActiveApplication.GetWindow("File Comparer").RefreshVisualTrees(); Applications.File_Comparerexe.File_Comparer.Find.ByExpression(new XamlFindExpression(findExpressions["FileName"])).User.TypeText("Testing File", 1000, true);
The first statement refreshes the DOM element tree in the event of clicking the File Info tab. The second statement uses the retrieved find expression of the File Name text field defined in the element repository file, and calls the TypeText
method to imitate writing a text inside it.
Run your test and notice how the Testing File
expression is entered inside the File Name field.
3.15.231.194