Setting automationIDs across an existing application - wpf

If I have an existing WPF application, and I want to assign automationIDs to the entire application where they aren't set, what's a good way to do that (for controls that aren't dynamically added)? Some sort of script that goes through all the xaml files and adds automationIDs?
My goal is to write ui tests using winappdriver.
I've googled this, but haven't found anything that seems to do what I want. Perhaps I'm misunderstanding the results. This post seems to ask the same question, but I fail to see how the answer provided is an appropriate solution.

In WPF, when a control name property has a value, this corresponds with the AutomationID you will find with a UI inspector tool like Inspect.exe. Take a look at the remarks section about automationID here. So the application should already have most of its automationIDs.
The only time I did not have a automationID for a control was when the control was created in code. A script to adjust XAML won't help you here, because there won't be XAML for those controls. Even if you used a script, you won't be sure all automationIDs will be available.
When using 3rd party controls, the availability of a AutomationId depend on the 3rd party supporting it or not. If they do not support AutomationId, you could wrap that control in a custom control and expose a AutomationID that way.
Here are some resources that might be useful:
wrapped control
UI automation of a WPF Custom Control
When working with a existing application, I usually just fill in the name property for a control as I go, so the amount of change to the application stays at a minimum.

Related

How to find name of my XAML file in my WPF application at run time

I am working on very complex WPF application which has many resource files because of which XAML doesn't load at design time. I want to find names of XAML files, at run time. I am trying to use snoop but not able to find name of XAML file. Please help
Using Snoop won't give you file names but you should be able to locate some type names (i.e. UserControls, custom controls, etc) or elements with x:Names by looking through the visual tree view near where you're trying to get to after using the Ctrl-Shift mouse-over shortcut. Searching for either usages of types (in the case of controls) or using Find in Files on all solution *.xaml files should help you find the elements you're looking for.
Usually I do this by starting at a high level of the UI (for example MainWindow)
and the draw the components on paper that I find there, especially the grids.
Then I try to figure out where the elements of my application are in that view.
If you have multiple views, this can be somewhat timeconsuming. But if you
cannot just click through the designer windows, this is one of the fastest
possible ways to do it.
Okay, if you only have minor changes, you can try to find the element that
you want to change by using string search.
Find the label you want, if it is a resource string, find the usage of it.
If you have a complex MVVM application, you can start by investigating
the ViewModels used. They can be a better starting point than the View
itself.
-edit-
WPF Inspector can give you good hints on where to search.
You can get it here: WPF Inspector home
If you are looking for it for your own needs, you can call BaseUriHelper.GetBaseUri(v) on any visual and it will give you the Uri of the resource that your visual comes from. From this Uri you can get the origin xaml file

Design Time Extension Properties In Winforms

I have built out a couple of keyboards for a touch aware app we are building in work. Since we use a controller that is aware of when the app is in touch screen mode I thought it would be nice if, in design mode, we could associate a control with a keyboard type and have the controller look after the calling of the keyboard.
One of the things I do not want to do is to sub class each type of control just to add this property as I feel it is a very heavy for small gain. I had thought of using the tag property but it is not available in all controls due to use.
I was wondering if there is a way of attaching a property to a control on design time for the purpose of adding this meta data. So to recap I would like to be able to give each control a value that would be read by the controller to decide what keyboard to show.
Yes, the designer supports this. Good examples of existing components that do this are ErrorProvider and HelpProvider. Note how they add properties to existing control types.
You'll want to implement your own component, it needs to implement the IExtenderProvider interface. The MSDN Library article for it has a good example that should help you getting it right.

How to access inner elements of a WPF custom control that doesn't implement the AutomationPeer class?

Recently I came to know from this article -
http://blogs.msdn.com/b/patrickdanino/archive/2009/11/11/custom-controls-and-ui-automation.aspx
-that controls in WPF are responsible for exposing their UIA items themselves, and any newly added functionalities of a custom control aren’t available to the UIA until they are exposed through the implementation of the corresponding AutomationPeer class. At my work I have been assigned to the automation of UI testing of a WPF application that employs a large number of ToolBars. The problem is, through Microsoft UI Automation Library I can access the ToolBars (apparently which are developed as custom control) as AutomationElements, but I cannot access the Buttons inside them – Count of Children/Descendant Collection always return 0. When using Coded UI Test, the tests always fail and shows the following Error Message:
Test method
CAM2QDummyTest.CodedUITest2.CodedUITestMethod1
threw exception:
Microsoft.VisualStudio.TestTools.UITest.Extension.FailedToPerformActionOnBlockedControlException:
Another control is blocking the
control. Please make the blocked
control visible and retry the action.
Additional Details:
TechnologyName: 'MSAA'
Name: 'Standard'
ControlType: 'ToolBar'
--->
System.Runtime.InteropServices.COMException:
Exception from HRESULT: 0xF004F003
Apparently they didn’t implement the corresponding AutomationPeer classes. Now, I only have the application, not the source code. So I cannot solve the problem in the way described in the article I mentioned above. Can anyone HELP with any clue how can I get access to the inner Buttons of the ToolBars? Any suggestion will be gratefully appreciated.
You can have a look at what patterns and properties are supported via AutomationElement.GetSupportedProperties() and AutomationElement.GetSupportedPatterns() to see if there's a different pattern which you can use. It might be that there are list elements, etc. via SelectionPattern or similar which will give you access to the buttons.
Otherwise, get in touch with the vendors and ask them to add the relevant peers.
You can always get the coordinates (maybe by the BoundingRectangleProperty) then use Win32 functions to simulate a mouse click in the appropriate place. Nasty. This thread might help.

Suggestions for replacing legacy VB6/Flash application with WPF/Blend application

We have a legacy application that utilizes VB6, the Flash ActiveX control, and Flash content to display animated movies to users. For plenty of reasons we're looking to migrate away from this. I'm hoping someone out there can answer a few questions about WPF so that we can make a determination about how best to move forward.
First, a little about our current architecture and needs. The Flash content is set up as separate SWF files, where each individual SWF represents a training module with animated content. We have hundreds of these modules. Users run this software in a disconnected fashion where their local machine may or may not have ALL of these SWF files. The current application gives the user the option of downloading the SWF modules as they're needed.
Here's how we're thinking about setting up a new solution using WPF and Blend. We've written a WPF host application that can dynamically show Blend content based on button presses or whatever. And we've created a few test modules in Blend as WPF custom controls. But there are three nagging questions:
Right now we have the custom controls within the main WPF solution, but we need to make these disconnected. I've read several things about using Application.LoadComponent but I don't know if that will work for our solution.
Each of the Blend custom controls contains one or more storyboards that control the animation. As soon as I add one of the custom controls to a container in the WPF app, ALL of the storyboards automatically start "playing". How can I programatically make it so that I start/stop certain storyboards as needed?
Let's say I want to change a text label in one of the custom controls. If we're dynamically loading the custom control, how would I access one of the text labels to make such a change?
Any tips would be greatly appreciated. Loving WPF so far and hoping we can make this work and say goodbye to Flash forever!!!
There is Manage Extensibility Framework, that is a standard approach for dynamic modules.
Anyway, I haven't used it, so I would answer the questions in other way:
1) No, LoadComponent is ised for xaml files, whereas custom control consist of code and xaml. I mean, the custom control that you can add using Add->New Item->Custom Control(WPF). So you should do something like this, with reflection and ContentControl:
Assembly asm = Assembly.LoadFile(#"C:\SomeLibrary.dll");
Type type = asm.GetType("SomeNamespace.SomeControl");
var control = Activator.CreateInstance(type) as Control;
this.myContentControl.Content = control;
2) It isn't fact. You can put the storyboards into Control.Resources and launch them manually.
((Storyboard)control.Resources["myStoryboard"]).Begin(control);
3)
control.FindName("anyname") as TextBlock;

Coded UI Test - get my custom object (WinForms)?

I want to create an automated UI test that will test my syncfusion grid. My problem is that the recorder can't recognize this control (or any syncfusion control). I've searched a lot in the internet but I couldn't find any extension so the recorder will recognize my controls (I'm using WinForms, not WPF!), or at least a way to extend the recorder abilities so syncfusion's controls will be recognized somehow.
Is there any easy way to extend the recorder? Or is there any extension available?
Or maybe can I get the grid object from the WinClient that the recorder generates?
Thanks!
Start your program. Run the Spy++ utility. Type Ctrl+F to start the finder tool and drag the bulls-eye onto your form. Ok, Synchronize and have a look-see at the windows that are visible in the tree. If you see regular Windows Forms controls, like a Button or a Label, but not any of the SyncFusion controls then you've probably found the source of the problem.
Component vendors that try to improve .NET controls typically do so by creating 'window-less' controls. They are not really controls, they don't derive from the Control class and don't have a Handle property. They use the surface of the parent to draw themselves, making them look just like controls. The .NET ToolStripItem classes do this. And this is also the approach WPF uses.
The big advantage is that they render quickly and support all kinds of effects that regular controls can't support, like transparency, rotation and anti-aliased window edges. The big disadvantage is that the kind of tool that you are using suddenly gets noddy and can't find the control back. Because they work by finding the Windows window back on your form, there is no window for them.
This is a hard problem to solve, the 'control' exists only in memory and there's no good way for a tool to find it back. Using Accessibility is about the only other way for such a tool to find a control that I can think of. Which would have to be implemented by the control vendor first, a somewhat obscure feature that gets easily overlooked. You really do need the help of the vendor to find a workaround for this. Shouldn't be a problem, that's why you paid them the big money.
This is Rajadurai from Syncfusion. Thank you for your interest in Syncfusion Products. To make UI Test Automation recognize Syncfusion grids(WinForms), some internal support need to be provided in grid whose implementation is in progress and about to be completed. Please submit an incident through Direct-Trac for any further related inquiries in the following link.
http://www.syncfusion.com/Account/Logon?ReturnUrl=%2fsupport%2fdirecttrac
You can also contact us through support#syncfusion.com. We are happy to assist you.
Regards,
Rajadurai

Resources