Using multiple search properties to find an object in CUITe code.

Sep 7, 2012 at 8:26 PM

I created a class in the object repository to hold all of my objects.  I'm trying to find a WPF text box but it has the same automation id as another text box so that the test finds the wrong one.  Is there a way to define multiple search properties in the object repository?

Something like this:

public CUITe_WpfEdit CustomerSearchEdit {

     get{

            CUITe_WpfEdit myEdit = new CUITe_WpfEdit();

             myEdit.SetSearchProperty("AutomationID", "txtSearchValue");

             myEdit.SetSearchPropertyRegex("Ancestor", "Customer Search");

             return myEdit;

            }

}

 

Thanks for the help.

Coordinator
Sep 7, 2012 at 10:38 PM

Hi krag451,

Please try using the overloaded constructor that takes a search parameter string, similar to the following:

return new CUITe_WpfEdit("AutomationID=txtSearchValue;Ancestor=Customer Search");

Thank you.

Sep 10, 2012 at 5:07 PM

icnocop,

Thanks for the reply.

I tired that command and I got an error stating that Ancestor is not a valid Search Parameter.  Here is the error:

CUITe.CUITe_InvalidSearchKey: Search Pattern Key not supported -> 'value' in 'AutomationID=txtSearchValue;value=Customer Search'. Available Properties: BoundingRectangle, ControlType, Name, FriendlyName, ClassName, NativeElement, TechnologyName, IsTopParent, TopParent, WindowHandle, Exists, Enabled, HasFocus, Instance, MaxDepth, UITechnologyElement, QueryId, HelpText, Font, LabeledBy, AutomationId, AcceleratorKey, AccessKey.

 

What do I need to do to add support for a new search param like "Ancestor"

Jeff

 

 

Coordinator
Sep 10, 2012 at 8:16 PM

Hi Jeff,

I recommend first finding the parent control and then finding the child control.

For example,

CUITe_WpfControl customerSearch = new CUITe_WpfControl("Name=Customer Search");

CUITe_WpfEdit customerSearchValue = customerSearch.Get<CUITe_WpfEdit>("Name=txtSearchValue");

This will search for customerSearchValue as a child control of customerSearch.

Another way is to use navigation methods like GetChildren() and properties like NextSibling, but that doesn't seem necessary in this scenario.

Sep 10, 2012 at 10:11 PM

icnocop,

 

Thanks again for the response.

 

It's odd but I tried this code and the automation still picks the item that is part of the higher level container.

CUITe_WpfControl customerSearch = new CUITe_WpfControl("Name=Customer Search");

CUITe_WpfEdit customerSearchValue = customerSearch.Get<CUITe_WpfEdit>("Name=txtSearchValue");

 

My application looks like this

WPF window Main

   WPF edit box with name txtSearchValue

       WPF Search Window

           WPF edit box with name txtSearchValue.

 

How does the search logarithm work and could it be searching the lower level window and it if it doesn't find what it is looking for go to the higher level container?

Thanks

Jeff

 

Coordinator
Sep 11, 2012 at 3:49 AM
Edited Sep 11, 2012 at 3:49 AM

Hi Jeff,

Can you provide a sample app and coded ui test that can reproduce the problem?

It is unclear as to where "Customer Search" is in relation to "txtSearchValue"

Maybe you want to do the following:

CUITe_WpfWindow customerSearchWindow = new CUITe_WpfWindow("Name=Customer Search");

CUITe_WpfEdit customerSearchValue = customerSearchWindow.Get<CUITe_WpfEdit>("Name=txtSearchValue");

 

Significance of Window Titles in Coded UI Test Playback

http://blogs.msdn.com/b/visualstudioalm/archive/2012/07/15/significance-of-window-titles-in-coded-ui-test-playback.aspx

"The control search in Coded UI Test playback is essentially a breadth first search."

 

How does “Coded UI test” finds a control ??

http://blogs.msdn.com/b/balagans/archive/2009/12/28/9941582.aspx

"Search in Coded UI test is a Breadth-First which compares each of the controls in the traversal for the match of the properties given in the code."

"Search starts at the 'someAncestorControl' control as it is specified as the ancestor for the control to be found."

CUITe uses the instance that the Get<> method is called on as the container control to find the control whose matching properties are specified by the search parameters.

From my experience, it seems that if the control cannot be found in the container, "Coded UI" will start from the top level \ desktop window, but this may just be a default setting that's configurable.

PlaybackSettings.SmartMatchOptions Property

http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.testtools.uitesting.playbacksettings.smartmatchoptions%28v=vs.100%29.aspx

SmartMatchOptions Enumeration

http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.testtools.uitest.extension.smartmatchoptions%28v=vs.100%29.aspx

PlaybackSettings.MatchExactHierarchy Property

http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.testtools.uitesting.playbacksettings.matchexacthierarchy%28v=vs.100%29

Configuring Playback in VSTT 2010

http://blogs.msdn.com/b/vstsqualitytools/archive/2009/08/10/configuring-playback-in-vstt-2010.aspx

Sep 12, 2012 at 4:45 PM

icnocop,

Thanks for all of the great information.  It is really interesting and helpful.  Unfortunately, the app is too large so I can't provide a sample of it to show the problem.

To answer your question the Customer Search is the second window in the hierarchy that I showed above.  Here is the revision showing this.  Sorry for the confusion:

My application looks like this

WPF window Main

   WPF edit box with name txtSearchValue

       WPF Customer Search Window

           WPF edit box with name txtSearchValue.

 

However, I had something of a breakthrough yesterday in that I tired to set focus on the Customer Search window and received the following error:

Test method TestProject4.CodedUITest1.ClickCustomerSearch threw exception:
Microsoft.VisualStudio.TestTools.UITest.Extension.PlaybackFailureException: Cannot perform 'SetFocus' on the control. Additional Details:
TechnologyName:  'MSAA'
Name:  'Customer Search'
ClassName:  'WindowsForms10.Window'
ControlType:  'Window'
 ---> System.Runtime.InteropServices.COMException: Error HRESULT E_FAIL has been returned from a call to a COM component.

 

I noticed that the TechnologyName is MSAA however in my code I specified that the control was wpf:

public CUITe_WpfWindow CustomerSearch = new CUITe_WpfWindow("Name=Customer Search");

Even with this declaration the application was still searching via MSAA and not UIA.  I made the following changes and this helped to resolve my problems:

1. Changed the line above to this:

public CUITe_WpfWindow CustomerSearch { get { return Get<CUITe_WpfWindow>("Name=Customer Search"); } }

2. Then I changed the line that returns the reference to the text box to this:

public CUITe_WpfEdit CustomerSearchEdit { get { return CustomerSearch.Get<CUITe_WpfEdit>("AutomationID=txtSearchValue"); } }

 

The Customer Search is now being found and the automation understands that the edit field that I am trying to click is within this parent object. 

Thanks again for all of the help and information.

As a side note is there an easy way to expose the search criteria that coded ui is using when it is trying to find an object.  It would have been helpful to know that the automation was searching using MSAA and not UIA.  Also, is there a way to force the search to use UIA instead of MSAA?

Jeff

 

Coordinator
Sep 15, 2012 at 12:51 AM

Hi Jeff,

CUITe does not explicitly specify \ override the TechnologyName.

You can set the TechnologyName property of the underlying UITestControl by calling the UnWrap() method.

For example,

CustomerSearch.UnWrap().TechnologyName = "UIA";

I have not played too much with overriding the TechnologyName property, so YMMV.

.UnWrap().TechnologyName = ""