This project has moved. For the latest updates, please go here.

Coded UI Testing works for everything except Extended.Wpf.Toolkit controls

Nov 2, 2016 at 11:56 AM
Edited Nov 2, 2016 at 12:01 PM
I am using Coded UI Testing (available in Microsoft Visual Studio 2015) and creating tests using the recorder. My tests work perfectly in my WPF application except where I have used "IntegerUpDown" control from the Extended.Wpf.Toolkit controls.

The normal approach when you encounter such a problem is to add the optional property AutomationId in your control in XAML. Then next time you record a test it uses that ID, thus uniquely identifying your XAML control. So for example, my button ...
    <Button Width="75" Height="40">Click Me</Button>
Simply becomes...
    <Button Width="75" Height="40" AutomationProperties.AutomationId="Btn1">Click Me</Button>
And my IntegerUpDown control ...

<xctk:IntegerUpDown/>

becomes ...

<xctk:IntegerUpDown AutomationProperties.AutomationId="Nuid1" />

This is easy and works for all controls except the IntegerUpDown control that I have used. In the case of the IntegerUpDown, the CodedUI test sees the AutomationID of "AutoSelectTextBox" and not the value "Nuid1" that I have set. Where did this "AutoSelectTextBox" come from and why can I not set the AutomationID in the way that I do for standard WPF controls?

The problem with not being able to set the AutomationID is that recorded tests sometimes cannot tell which control is which. I therefore have say 3 IntegerUpDown controls on a XAML page. I record a test that adds 3 different values into each one. When my test plays back it enters the wrong values into the same box repeatedly instead of entering the value in the control that I used in my recording. There are other factors at play here because the Coded UI test sometimes can identify a control by other methods even when the AutomationID is not set but the underlying problem is that the IntegerUpDown control cannot have it's AutomationID set by me, the coder as this seems to be masked by a default AutomationID of "AutoSelectTextBox".
Developer
Nov 2, 2016 at 7:36 PM
Hi,

The Button is a simple Framework control.
The IntegerUpDown is a more complex control, made of a ButtonSpinner containing a WatermarkTextBox .

In the ControlTemplate of the IntegerUpDown, the ButtonSpinner is named "PART_Spinner", while the WatermarkTextBox is named "PART_TextBox".

In the ControlTemplate of the ButtonSpinner, there is a ContentPresenter (named "contentPresenter") and 2 RepeatButtons (named "PART_IncreaseButton" and "PART_DecreaseButton").

In code, the WatermarkTextBox derives from AutoSelectTextBox.
The static constructor of AutoSelectTextBox overrides the AutomationIdProperty to set it to "AutoSelectTextBox".

So for 3 IntegerUpDowns, Code UI Test will generate something like :
this.mUIAutoSelectTextBoxEdit.SearchProperties[WpfEdit.PropertyNames.AutomationId] = "AutoSelectTextBox";
this.mUIAutoSelectTextBoxEdit.WindowTitles.Add("MainWindow");

this.mUIAutoSelectTextBoxEdit1.SearchProperties[WpfEdit.PropertyNames.AutomationId] = "AutoSelectTextBox";
this.mUIAutoSelectTextBoxEdit1.SearchProperties[WpfEdit.PropertyNames.Instance] = "2";
this.mUIAutoSelectTextBoxEdit1.WindowTitles.Add("MainWindow");

this.mUIAutoSelectTextBoxEdit1.SearchProperties[WpfEdit.PropertyNames.AutomationId] = "AutoSelectTextBox";
this.mUIAutoSelectTextBoxEdit1.SearchProperties[WpfEdit.PropertyNames.Instance] = "3";
this.mUIAutoSelectTextBoxEdit1.WindowTitles.Add("MainWindow");
where each WatermarkTextBox (from 3 different IntegerUpDowns) have the AutomationId "AutoSelectTextBox", but with different instances !!

If you remove the static constructor from AutoSelectTextBox, Code UI Test will generate something like :
this.mUIPART_TextBoxEdit.SearchProperties[WpfEdit.PropertyNames.AutomationId] = "PART_TextBox";
this.mUIPART_TextBoxEdit.WindowTitles.Add("MainWindow");

this.mUIPART_TextBoxEdit1.SearchProperties[WpfEdit.PropertyNames.AutomationId] = "PART_TextBox";
this.mUIPART_TextBoxEdit1.SearchProperties[WpfEdit.PropertyNames.Instance] = "2";
this.mUIPART_TextBoxEdit1.WindowTitles.Add("MainWindow");

this.mUIPART_TextBoxEdit2.SearchProperties[WpfEdit.PropertyNames.AutomationId] = "PART_TextBox";
this.mUIPART_TextBoxEdit2.SearchProperties[WpfEdit.PropertyNames.Instance] = "3";
this.mUIPART_TextBoxEdit2.WindowTitles.Add("MainWindow");
where each WatermarkTextBox (from 3 different IntegerUpDowns) have the AutomationId "PART_TextBox", but with different instances !!

So you probably set the InterUpDown's AutomationID, but the it's the WatermarkTextBox and the RepeatButtons from IntegerUpDown that are clickables.
Nov 7, 2016 at 10:21 AM
Edited Nov 7, 2016 at 11:13 AM
I understand this explanation to an extent but I don't see where I can change the AutomationID so it affects the TextBox. I also am not aware that I had a static constructor for AutoSelectTextBox so I don't know how to remove it. Sorry if these are silly questions, I'm just aiming to add AutomationID in XAML and not sure how to dig deeper than that.

So far I have used NuGet to get the XCeed toolkit. Then I have added the reference in the window (xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit") and in XAML I have the IntegerUpDown (<xctk:IntegerUpDown AutomationProperties.AutomationId="Nuid1" />).

Here's my XAML ...

<Window x:Class="WpfApplication1.ControlsWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:WpfApplication1"
    mc:Ignorable="d"
    Title="ControlsWindow" Height="900" Width="300"
    WindowStartupLocation="Manual"
    xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit">
<StackPanel Orientation="Vertical">

    <xctk:IntegerUpDown AutomationProperties.AutomationId="Nuid1" />
    <xctk:IntegerUpDown AutomationProperties.AutomationId="Nuid2" />
    <xctk:IntegerUpDown AutomationProperties.AutomationId="Nuid3"  />
    <xctk:IntegerUpDown AutomationProperties.AutomationId="Nuid4" />        

</StackPanel>
</Window>

What you say makes sense, the AutomationID has been overridden but how do I change it so I am setting the TextBox automationID and not the whole control's AutomationID which then gets overridden? I can change the search properties in Coded UI although I would rather just set the AutomationID in the system I am testing so I can record tests easily so that's what I'm trying to do here.
Developer
Nov 7, 2016 at 1:32 PM
Edited Nov 7, 2016 at 1:32 PM
Hi,

The Xceed Toolkit doesn't support AutomationID yet. But here's a solution if you want to set the AutomationID on the TextBox's part of the NumericUpDowns.

Instead of getting the Nuget Package, go to the sourceCode section on codeplex (https://wpftoolkit.codeplex.com/SourceControl/latest) and download the latest sources. In your solution, Add an existing project, and choose the Xceed.Wpf.Toolkit.csproj that you just downloaded. Make sure to reference this Xceed.Wpf.Toolkit.dll in your project.

Then, go in file :
-Xceed.Wpf.Toolkit/NmericUpDown/Themes/Aero2.NormalColor.xaml (for Windows8 and up)
-Xceed.Wpf.Toolkit/NmericUpDown/Themes/Generic.xaml (for other Windows)

In the "PART_TextBox", Add the following property :
AutomationProperties.AutomationId="{TemplateBinding AutomationProperties.AutomationId}"

This will make sure the AutomationID you set on the NumericUpDown will be translated to its TextBox.

Also, make sure to remove the AutoSelect override. For this, go in file
-Xceed.Wpf.Toolkit/AutoSelectTextBox/Implementation/AutoSelectTextBox.cs
and remove the static constructor. This will remove the override on AutomationID property.

Your XAML is good

――――
Get more controls, features, updates and technical support with Xceed Toolkit Plus for WPF