开发者

WPF UI Automation with Caliburn.Micro?

I am attempting to write some UI automation tests for a WPF application that is using Caliburn.Micro and White. I am using CM's builtin conventions to bind my controls to the view model's properties and methods. I am also using Conductor classes so that I may have multiple views visible on a single screen. This generally means that multiple controls on a screen can end up having the same x:Name value. It will just get bound to a different view model. A good idea of what I am trying to do can 开发者_C百科be seen in the HelloScreens sample application that comes with CM.

The problem that I am running in to is that I will have multiple XAML elements with the same x:Name attribute so that CM can handle all of the binding work for me. This unfortunately means that multiple UIItem objects will have the same UI Automation ID. The only way I have found to get, for instance, different TextBlock elements with x:Name="DisplayName" is to make a call such as the following:

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

This means my tests need to know the exact order that different controls are placed on the screen, which seems very brittle. I can see my tests all breaking just by adding another view model.

  • Is there a way to specify the Automation ID other than using the x:Name attribute?
  • Would this be easier if I used the UI Automation framework directly instead of using White?
  • Or, do I really have to forego CM's convention based binding and give everyting unique x:Name values and bind them by hand?

UPDATED

To clarify what I mean by having multiple views visible at once, here is my general layout. I have my ShellViewModel which I derive from Conductor<IScreen>.Collection.OneActive. Then my view has an ItemsControl that is bound to the shell view model's Items property. Each item template shows a button that is meant to load that specific IScreen into a ContentControl that is on the shell's view. So, If I try to look for an element with x:Name="DisplayName", I have the label on the shell view, the label on the button in the ItemsControl as well as a label inside of the ContentControl.


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


One option may be to alter the BindProperties and BindActions delegates on the ViewModelBinder type to work with control names whose names are altered based on the view in which they belong.

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

Any text from the control name up to and including the word 'View' could be stripped to form the clean control name before continuing processing the control.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜