Test Runner can't find controls during replay - wpf

I just started with Microsoft Test Manager 2015 and build two test cases.
First one involves clicking on a tray icon and selecting an entry from there - which works fine.
Second case is a bit more complex, I wanted to fill out a form in a WPF window and click some buttons.
The recording went without a problem but the replay doesn't work at all. It should start with selecting a TabItem, select another TabItem that is inside the previous selected TabItem and then fill out the text fields and press a button and confirm two message dialogues.
Problem is, TestRunner isn't able to find any of my controls. Even if I select the correct TabItem and just try and execute one of the 'enter someText here' steps, it takes some time and then throws an exception in my face which, roughly translated, says that the replay of the selected step couldn't be completed because it couldn't find a control that matched the search properties(?). Then follows a List:
TechnologyName: 'UIA'
FrameworkId: 'WPF'
ControlType: 'TabPage'
AutomationId: 'sometabname'
all of that is correct. If I try to execute a different test step it says basically the same thing but instead of 'ControlType: TabPage' it says 'ControlType: Edit'.
I'm not sure how to proceed from here. I did some searching but all I could find were questions about UIAutomation configuration/set-up but as far as I can tell I can't influence/control that directly in MTM.
edit
After simplifying the test 'case' (just click the abort button that is directly placed in the Window/first grid) and editing the mtm.exe.config file and enabling tracing/logging I got this out of the respective logfile:
mtm.exe, Playback - [WARNING] Internal warning: Target element "[UIA]FrameworkId='WPF' && ControlType='Button' && AutomationId='closeWithoutSave'" was not found, so all intermediate elements were ignored. An incorrect element that matches target element Id can be found as the result. Verify that all intermediate elements in QueryId have valid and unique Ids
mtm.exe, Playback - [WARNING] Internal warning: Search failure: [UIA]FrameworkId='WPF' && ControlType='Button' && AutomationId='closeWithoutSave' | Performed (4) searches, UI element not found
mtm.exe, Playback - {1} [FAILED] Function ElementFetcher::FindScreenElement failed to locate UI element (;[UIA]FrameworkId='WPF' && ControlType='Button' && AutomationId='closeWithoutSave') (Das angegebene Objekt wurde nicht gefunden.)
What is weird here is that I even set the Automation.AutomationID on that button and it still failed. Also I'm not sure if that is right but the search doesn't seem to include the name/automationID of the Window that has that button. Since I've, at that point, two windows open in the application I could imagine that being the problem.

I inspected the UI test that was generated by MTM by loading it into a Coded UI Test Project. I opened the UI Control Map and saw what was wrong:
The TabControl/TabPage navigation was grouped in the same Window as the ContextMenu of the TrayIcon.
The reason for that was, that instead of using the Name property of a WPF Window, MTM/Coded UI Tests use the Title property as the identifier of a Window (wtf?).
The Solution:
Setting the Title property of my WPF configuration window to Configuration and redoing the affected test steps solved the problem.
Hint for people with a similiar problem: It may also help to increase the MaxLevelsForItemContainer value in the mtm.exe.config file that is located in Common7\IDE of your Visual Studio installation folder.

Related

WinForms - Can't add picture to picturebox

I pretty much just started using Windows forms and I'm trying to add a picture to a picture box. First I tried the most obvious way, that is - clicking on the little arrow in the top right corner of a picturebox and clicking "choose image" in the small dialog box, but no matter what I do, the "choose image" button does utterly nothing. I know it should open some dialog box where I could choose my picture, but litterally nothing happens, not even an error message pops up.
Next I tried importing the picture through the properties of the picturebox, but after clicking on the three dots next to the image property an error message pops up, saying "value cannot be NULL, Name o parameter: docData".
I tried following this answer (How to attach a resource (an image for example) with the exe file?) and going to the properties of my project and then to the resources tab, but I have this tab completely empty, saying just that my project does not contain any default resources and a "click to create them" button. However when I click it, another error message appears saying "system cannot find the file. Exception based on value HRESULT:0x80070002"
I guess the problem must be somewhere in my resources file (which might be missing or whatever), but I have a default .resx file there that I haven't touched since the creation of this project which I had thought should be fine.
Afterall I pretty much just started with WinForms and I don't have much clue what's going on and this is quite a significant setback for me. I would be grateful for any help.

Event causes exception due to missing resource

My form has 96 check boxes, 4 DataGridView controls, and some other controls. Everything works fine until I add an event to the fourth DataGridView. When I add any event to that control, the code builder adds a resource that compiles but causes a run time exception. The exception is:
An unhandled exception of type 'System.Resources.MissingManifestResourceException' occurred in mscorlib.dll
Additional information: Could not find any resources appropriate for the specified culture or the neutral culture.
I ran a Diff between the code that works and the code that causes the exception. When I add the event to the DataGridView control, the code below is added to my MainForm.h file.
System::ComponentModel::ComponentResourceManager^ resources = (gcnew System::ComponentModel::ComponentResourceManager(Form1::typeid));
Each of the checkbox controls have a line as shown below that wasn't there before adding the event to the DataGridView.
resources->ApplyResources(this->checkBox_D1, L"checkBox_D1");
The code builder deleted the code below from each checkbox after adding the event.
this->checkBox_D1->AutoSize = true;
this->checkBox_D1->Location = System::Drawing::Point(30, 19);
this->checkBox_D1->Size = System::Drawing::Size(40, 17);
this->checkBox_D1->TabIndex = 0;
this->checkBox_D1->Text = L"D1";
The only difference that I can find between the fourth DataGridView and the others that don't cause the problem is that three of them are inside a Group box and the fourth one is outside the Group Box. I created all four DataGridView controls by copy and pasting from the first one. I thought that might have caused the problem so I created the fourth one from scratch, but it didn't resolve the issue. All four DataGridView controls call the same event handler and point to the same function.
I changed the name of Form1 to MainForm, but it still shows up as Form1 in some places. Why is that, and is this causing this issue?
Any suggestions would be greatly appreciated!
Thank you.
I solved this issue by recreating the form. It was faster to recreate the GUI and transfer all my code than to try to figure out how to fix it. I'm going to guess that the project got hosed up, but I don't understand how Visual Studio organizes the resources well enough.

How to make the Windows OSK open when a TextBox gets focus, instead of requiring users to tap a keyboard icon?

We are working on a WPF application in .NET 4 that will be used with a touch screen. We are trying to use the built-in Windows OSK for our input, and the last remaining issue is to get the keyboard to open up as soon as a text box gets focus. Currently, if a text box gets focus, a small keyboard icon appears (this is the InputPanel icon) and the user has to tap that icon to make the keyboard open up.
Is there a way to skip the icon step, and just have the keyboard open up all the way on focus? Preferably something that can be set or coded in one place and apply to all text boxes globally? It also needs to use the current culture settings of the application thread (which it already appears to be doing).
I haven't been able to find anything in the control panel settings that lets you skip the icon step. I also found some examples online of using the TextInputPanel.CurrentInPlaceState, but when I implemented code to open up a TextInputPanel on preview focus of the main window, I kept getting COM INTEROP exceptions and basically hit a dead end (the Microsoft.Ink.dll is an interop DLL).
Is it possible that there is a registry key that can change the default CurrentInPlaceState to Expanded instead of HoverTarget? I haven't been able to find one in my net searching.
Thanks,
Valerie
EDIT: Here is some code that I put in the main window's code behind, as well as the exception message I keep getting - and I have no idea what it means or how to fix it (my net searches failed me!)
protected override void OnPreviewGotKeyboardFocus(KeyboardFocusChangedEventArgs e)
{
base.OnPreviewGotKeyboardFocus(e);
TextBox textbox = e.NewFocus as TextBox;
TextBox oldTextbox = e.OldFocus as TextBox;
if (oldTextbox != null && boxesToInputs.ContainsKey(oldTextbox))
{
TextInputPanel oldPanel = boxesToInputs[oldTextbox];
oldPanel.Dispose();
boxesToInputs.Remove(oldTextbox);
}
if (textbox != null)
{
// Make sure we've cleaned up old panels, just in case
if (boxesToInputs.ContainsKey(textbox))
{
boxesToInputs[textbox].Dispose();
boxesToInputs.Remove(textbox);
}
TextInputPanel newPanel = new TextInputPanel(((HwndSource)PresentationSource.FromDependencyObject(textbox)).Handle);
newPanel.DefaultInPlaceState = InPlaceState.Expanded;
newPanel.DefaultInputArea = PanelInputArea.Keyboard;
boxesToInputs[textbox] = newPanel;
}
}
And here is the exception message, which occurs when my code calls the TextInputPanel constructor:
Retrieving the COM class factory for component with CLSID {F9B189D7-228B-4F2B-8650-B97F59E02C8C} failed due to the following error: 80040154 Class not registered (Exception from HRESULT: 0x80040154 (REGDB_E_CLASSNOTREG))
I verified that the platform target of the WPF app is x86. I ran Dependency Walker and it said that the Microsoft.Ink.dll I was using was 64 bit, and that two delay-loaded dependencies were missing (GPSVC.dll and IESHIMS.dll). I found a 32 bit version of Microsoft.Ink.dll, but I am still getting the same error, and Dependency Walker is saying the same thing - GPSVC.dll and IESHIMS.dll are missing.
I can't target x64, and I'd prefer not to have to put the missing DLLs into my application folder (if that would work?). I hope there is something simple I am missing, because this is a lot of trouble to just get rid of a keyboard hint...
Any help is greatly appreciated - I am a bit of a newb when it comes to working with unmanaged/interop assemblies...
I researched for a similar propose. In my case it was to create a custom OSK. It seems that (by now) it's not possible to create a custom input device. The explanation is in this link:
http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/a813a08a-7960-45fe-bc91-e81cdb75bd10
Moreover, I found a "workaround" which uses Win32 API calls to access SendKey method, and report input independently of the target. The project that I found is:
http://wosk.codeplex.com/
SendKey is also available on WinForms (see http://msdn.microsoft.com/en-us/library/system.windows.forms.sendkeys.aspx ) but I'm not sure if it will produce the same behavior.
I'll checking these options in the following days, but perhaps some of this information might help.
Regards
Herber

Trouble finding source of a designer exception in VS2010

When loading the mainform of a WinForms app I'm working on, I encountered a familiar exception: a "To prevent possible data loss before loading the designer, the following errors must be resolved" error. The stacktrace is as follows:
Object reference not set to an instance of an object.
Instances of this error (4)
1. Hide Call Stack
at System.ComponentModel.ReflectPropertyDescriptor.SetValue(Object component, Object value)
at Microsoft.VisualStudio.Shell.Design.VsTargetFrameworkPropertyDescriptor.SetValue(Object component, Object value)
at System.Windows.Forms.Design.ControlDesigner.CanResetSizePropertyDescriptor.SetValue(Object component, Object value)
at System.ComponentModel.Design.Serialization.CodeDomSerializerBase.DeserializePropertyAssignStatement(IDesignerSerializationManager manager, CodeAssignStatement statement, CodePropertyReferenceExpression propertyReferenceEx, Boolean reportError)
at System.ComponentModel.Design.Serialization.CodeDomSerializerBase.DeserializeAssignStatement(IDesignerSerializationManager manager, CodeAssignStatement statement)
at System.ComponentModel.Design.Serialization.CodeDomSerializerBase.DeserializeStatement(IDesignerSerializationManager manager, CodeStatement statement)
I know what's causing this error -- there are four lines buried somewhere in the MainForm that make reference to an image object that doesn't exist at design time. I even have an idea of how to fix the error, thanks to this post at MSDN. The trouble is, I can't find the lines from which the exception is thrown. Normally I would navigate to the exception using the Error List window, but it says that there are zero errors. Any ideas as to how I can locate the offending lines?
I usually find that this relates to a user control hosted on the form that relies on a DI container or similar, but as you say it is sometimes difficult to determine the source from the call stack the designer provides. If you're hosting a lot of controls, to figure out which controls are causing the issue without diving into each one you could:
Make a list of the user controls that are directly hosted on the form, then
Create a new temporary form, then
Drop each user control in your list onto the form to see which one kills the designer

Tool to know Windows Form Application's Form fields

I am working on a WinForm Application.
The Form has many fields/components but is poorly built.
for example a field is used as user name on one case and used as folder path on the other case. Code is quite poorly maintaned.
Is is possible that when i run the application and GUI appears, i can use a tool like 'spy++' which can show me 'names' of the components (not ids). For instance the name of a button or name of a label.
Or if i can use SPY++ for 'names' please tell me?
I would solve the problem by adding a ToolTip control to your form and iterating over each control and adding a Tool Tip message to each control that is the name of the control.
First, add a ToolTip object to your form (from the Tools section of the designer.) You can rename it, but for the sake of my demo, I left it as the default name toolTip1.
Next, add a method similar to the one I'm posting below to the code page of your form. (I'm assuming this is for C# but the code is simple and can easily be modified for VB or C++).
public void AddNameToToolTip(Control c)
{
toolTip1.SetToolTip(c, c.Name);
foreach (Control child in c.Controls) AddNameToToolTip(child);
}
Finally, from within the Form constructor, add the following line of code after the call to InitializeComponent().
AddNameToToolTip(this);
This will add a ToolTip message to each control in your form. All you should have to do is hover your mouse over each control and the ToolTip will pop up a message after a second or two displaying the name of the underlying control.
Alternatively, you can recursively adding a MouseHover event to each control and when the event is fired, write the name of the control to the debugger. This would also work if you are already using a ToolTip control within your form.

Resources