Automate WPF UI with Caliburn.Micro?

I am trying to write some user interface automation tests for a WPF application that uses Caliburn.Micro and White . I use the built-in CM conventions to bind my controls to the properties and methods of the view model. I also use Conductor classes so that I can see multiple views on one screen. Typically, this means that multiple controls on the screen can have the same x:Name value. It is simply tied to a different presentation model. A good idea of ​​what I'm trying to do can be seen in the HelloScreens application that comes with CM .

The problem I am facing is that I will have multiple XAML elements with the same x:Name attribute so that CM can handle all the binding work for me. Unfortunately, this means that multiple UIItem objects will have the same UI Automation Identifier. The only way I found to get, for example, different TextBlock elements with x:Name="DisplayName" , is to make a call, for example:

 SearchCriteria criteria = SearchCriteria.ByAutomationId("DisplayName").AndIndex(1); WPFLabel label = myWindow.Get<WPFLabel>(criteria); 

This means that my tests need to know the exact order of the different controls on the screen, which seems very fragile. I see that my tests are all breaking down by simply adding another view model.

  • Is there a way to specify an automation identifier other than the x:Name attribute?
  • Would it be easier if I used the UI Automation infrastructure directly instead of using White?
  • Or do I really need to give up the binding based on the CM-based convention and give each one unique x:Name values ​​and bind them manually?

UPDATED

To clarify what I mean by having multiple views at once, here is my general layout. I have a ShellViewModel that I get from Conductor<IScreen>.Collection.OneActive . Then my view has an ItemsControl tied to the Items wrapper model property. Each element template shows a button designed to load this particular IScreen into the ContentControl , which is in the shell view. So, if I try to find an element with x:Name="DisplayName" , I have a label on the shell view, a label on the button in the ItemsControl , and also a label inside the ContentControl .

+4
source share
2 answers

While AutomationId comes from the x: Name attribute by default, you can override it by setting AutomationProperties.AutomationId .

+5
source

One option would be to modify the BindProperties and BindActions in the ViewModelBinder type to work with the names of managers whose names are changed based on the view in which they belong.

For example, you can add a view name as a prefix for each control that is likely to have duplicate names in other views. So DisplayName can become ListViewDisplayName and ContentViewDisplayName .

You can remove any text from the control name before and including the word "View" to form a clean control name before continuing with the control.

+1
source

Source: https://habr.com/ru/post/1346361/


All Articles