Sorry for disturbance but it seems that I need your help.
I am really beginner in C#, White framework.
Here is the problem...
I am trying to automate WinForm application, very basic.
Manual steps for automation:
Open window
Download file to this window
Find caption at bottom of this window
Problem: I can press any buttons, open dialogs and so on.
But after several steps I can't find label (caption).
I tried this code at 2 PCs. For one PC it works, for other - doesn't work.
I saw only one time that this label was found.
Usually I see that Studio just hang up and trying to search elements.
I think that Studio works very quickly and elements are not available for reading. Could you help me with this?enter image description here
//Add file name for opening
TextBox listLoadFile = mainWindow.Get<TextBox>(SearchCriteria.ByText("File name:"));
listLoadFile.Text = "Omneon_72.lst";
application.WaitWhileBusy();
// open file
Keyboard.Instance.PressSpecialKey(KeyboardInput.SpecialKeys.RETURN);
application.WaitWhileBusy();
mainWindow.Focus();
mainWindow.ReloadIfCached();
//Can't find this element
Label caption3 = mainWindow.Get<Label>(SearchCriteria.ByAutomationId("lblStatus"));
//Can't see elements
IUIItem[] children1 = mainWindow.GetMultiple(SearchCriteria.All);
What if instead of reloading mainWindow you'd just reattach the process again.
process = Process.GetProcessesByName("myProcess")[0];
application = Application.Attach(process.Id);
mainWindow = application.GetWindow("myWindowTitle");
Label caption3 = mainWindow.Get<Label>(SearchCriteria.ByAutomationId("lblStatus"));
IUIItem[] children1 = mainWindow.GetMultiple(SearchCriteria.All);
Related
I'm trying to use UI Automation with C# to type file path in opened Open dialog and then press Open button. I'm able to find the dialog itself, but searching for inner elements (file path text box and Open button) gives no result. When I traverse elements tree writing elements to log file, I see that the log is obviously too short and not all elements printed out.
Strange behavior: if I switch with mouse on another window, traversing of the dialog returns all elements and I'm able to find desired controls and interact with them.
I've tried many approaches to bypass the problem:
open some window, switch to it with AutomationElement.SetFocus;
search for element with Win API (FindWindowEx);
get AutomationElement by point on screen within dialog's bounding rectangle iterating by x and y with some step.
No one approach give me desired result.
What can cause incomplete elements tree using UI Automation and what is workaround for this?
My scenario is:
test clicks on a button on web page
standard Windows dialog to select a file is opened
I'm trying to fill file path text box and press Open button using UI Automation
I finally came to this workaround:
the dialog is opened with textbox focused, so get handle to currently focused control;
get AutomationElement by the handle;
send Alt + O using SendKeys.SendWait.
I'm new to C# and TestStack.White,
The application that I'm testing (trying ....) is a WPF application.
I have a window that has a popup child-window, and I want to close it.
I have no AutomationId to those popup windows :(
I have the MainWindow and MainWindow.HasPopup() returns true :)
But I don't know to to get a list of (TestStack.White.UIItems.WindowItems.Window) from my MainWindow so I can do:
Foreach _windItem ... _windItem .Close();
Thanks in advance !.
EyalS.
There should be a Popup property on the Window. The HasPopup is actually checking the popup property. I think a better way to do this would be to ask the application for all it's windows and then close all of them except the one that has a property that designates it as your main window. Here is an example in White for how to do this.
Application application = Application.Launch("Path to Application");
foreach (Window window in application.GetWindows())
{
if (window.AutomationElement.Current.AutomationId == "MainWindow") continue;
window.Close();
}
I also suggest looking into FlaUI because FlaUI's APIs make it alot easier to get at the information in the AutomationElement without having to add dependencies to the underlying framework that White is wrapping. Plus White has alot of properties which don't work the way you would think they would like the Popup property for instance.
I'm trying to automate a part of our application WinForms/MFC application (to be able to perform automated tests) - however, currently I'm struggling with slow finding of the main menu (SysTreeView32 control) - basically the central component, which enables access to all the screens which I need to test.
I tried to find it with AutomationElement.FindFirst(), also with the TreeWalker.GetFirstChild(), but both methods seem far too slow.
What was interesting, once I started interaction with this TreeView during the time the test was trying to find the control - like expand/collapse some items, move with the mouse over the tested application - the control was found almost immediately.
What's the catch? Application is reacting very smoothly - only lookup process takes ages, when the app is inactive.
I had the same problem trying to find a child of my main window. You should give as many details as you can (filter things out) so that the search goes faster. In my case, I had a Save As Window, I added the following:
The window should be a ControlType.Window
AndCondition
The AutomationElement.NameProperty of the window should be: "Save As"
var saveWindow = appElement.FindFirst(TreeScope.Children | TreeScope.Descendants, new AndCondition(new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Window), new PropertyCondition(AutomationElement.NameProperty, "Save As")));
You need to do further tests to determine if the AutomationElement you are searching for can be found within the Descendants or the Children and skip search in one of them if necessary. In my case, the code above worked fine, but in a subsequent step, I required to find the Edit control / Text box next to "File name:" so I first created a condition:
var saveWindow = appElement.FindFirst(TreeScope.Children | TreeScope.Descendants, new AndCondition(new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Window), new PropertyCondition(AutomationElement.NameProperty, "Save As")));
And then added the condition to the search:
var fileName = saveWindow.FindFirst(TreeScope.Children | TreeScope.Descendants, fileNameCondition);
Strangely, and probably because of UIAutomation limitations, and unexpected behaviour, the line above was finding the element instantly in a Windows 10 Creators Update machine, but was getting stuck in a Windows 10 Anniversary Update... so after some debugging I found out that I could find the element by just searching in the children and that found it instantly in. both machines:
var fileName = saveWindow.FindFirst(TreeScope.Children, fileNameCondition);
I tried
textview.GrabFocus();
but it does nothing. Is there any way to do that? (Please try to answer this time instead of telling me to use google - I have tried and failed, thanks).
I also tried the same for a window:
// searchbox is a GTK window, which was initialised on load of this form
searchbox.Show();
searchbox.GrabFocus();
// this function will set focus to text box
searchbox.setFocus();
the main window in this case open a new window and is supposed to make this new window focused, and certain text box in this window focused - it doesn't work though and I have no idea why, full source code:
the window I am opening: https://github.com/pidgeonproject/pidgeon/blob/gtk%23/Forms/ScriptEdit.cs
the window from which I am opening: https://github.com/pidgeonproject/pidgeon/blob/gtk%23/Forms/Main.cs#L520
okay so given that this is probably very uncommon problem that was related to configuration of my application I don't expect anyone to solve it, however I found out what the problem was.
The window I created was of type
window.Hint = Gtk.WindowTypeHint.Utility
And for some reason unknown to me, it's not possible to set focus for this window. It may be even bug inside of GTK, but changing this to Normal did work.
I have textbox inside a usercontrol and I add the usercontrol to the MainWindow with the following XAML:
<Views:MyUserControl />
I have one TextBox in MyUserControl, the problem is that the TextBox doesn't take any input. Backspace och space works, but if I press the letter och numbers no text is added to the TextBox.
I have made sure that the text is not just hidden in the TextBox.
I have also tried to add a RichTextBox to MyUserControl with the same result, it doens't take any input (beside space och backspace).
I have also tried to add a TextBox to the MainWindow with the same result; it doens't take any input (beside space och backspace).
Also MyUserControl is added in a TabControl and TabItem.
Any clues?
Edit: Additional information
Forgot to write that I'm opening/creating the WPF Window from a WinForm application.
When I set my startup project in VS10 to be my WPF-project it work great with the keyboard input to the TextBox.
How come?
Im opening/creating my WPF windows with the following code:
MyWpfProject.MainWindow mw = new MyWpfProject.MainWindow();
mw.Show();
Edit: Solution
So I guess my real problem was that is was opening the WPf project from a WinForms application.
I added the following code:
MyWpfProject.MainWindow mw = new MyWpfProject.MainWindow();
ElementHost.EnableModelessKeyboardInterop(mw);
mw.Show();
"The EnableModelessKeyboardInterop() call is necessary to handle keyboard input in the WPF window if loaded from a non-WPF host like WinForms."
http://weblogs.asp.net/jdanforth/archive/2008/07/29/open-a-wpf-window-from-winforms.aspx
Answer to my own question (if someone else run into the same problem):
If you open a WPF-form from a WinForms application you have to do the following to get keyboard input:
MyWpfProject.MainWindow mw = new MyWpfProject.MainWindow();
ElementHost.EnableModelessKeyboardInterop(mw);
mw.Show();
"The EnableModelessKeyboardInterop() call is necessary to handle keyboard input in the WPF window if loaded from a non-WPF host like WinForms." http://weblogs.asp.net/jdanforth/archive/2008/07/29/open-a-wpf-window-from-winforms.aspx
maybe your user control is getting the keyboard event instead of your textbox? try to search in this way, it happens with mouse buttons.
I had the same problem but my Environment was built such that I could not apply the solution above. As it turned out that wasn't the problem. It was much more easier than expected.
I host a WPF User Control inside WinForms. My WinForms MainView (Startup form) did override the "ProcessCmdKey". Because of logical errors it returned nothing.
Nevertheless I received all key events in code behind in my XAML file but this events never updated the "Text" of my text box. Only space and backwards did so and this were the key events I didn't receive in code behind.
So in case you don't think of the simplest solution here it is for VB.NET.
STRG+F "ProcessCmdKey" and make sure that you Return the correct value of you may completely uncomment it just to verify that it isn't causing you the same trouble as it did to me.
I would like to add my own answer just on the off chance it can help anyone else with the same or similar problems. My particular use case was a .Net windows form created by an addin. The addin was running out of Autodesk Inventor which I think may be WPF (but don't take my word for it.) The addin had several windows forms some docked within the application and with some acting as popups or a separate secondary window. The solution was to set the windows forms owner to one of the docked forms. Doing this allowed text to be edited and entered into its textboxes. Very niche solution to a niche problem but hopefully it may help someone at some point in the future.
private void CreatePanels(DockableWindows DockableWindows)
{
//Create the dockable window that the panel form will live on.
DockableWindow SideWindow =
DockableWindows.Add(SidePanelNames.GUID, SidePanelNames.InternalWindowName, SidePanelNames.Title);
//Configure the windows settings.
SideWindow.ShowTitleBar = true;
SideWindow.ShowVisibilityCheckBox = true;
SideWindow.DisableCloseButton = false;
SideWindow.Visible = true;
SideWindow.AddChild(SidePanel.Handle); //Add the forms as children and then display to the user.
SidePanel.Show(); //Display the panel to the user.
}
/// <summary>
/// Creates the Display window were order and patient information is displayed to the user.
/// This method makes the adjust device form the owner of the display window. Because of this
/// dependecency it should be run after the panels have been created.
/// </summary>
private void CreateDisplayWindow()
{
DisplayForm = new DisplayForm //Create the display form.
{
Owner = SidePanel //Doing this allows text boxes to have values entered into them.
};
DisplayForm.Show(); //Show the display form to the user.
}
//Adding the side side panel as the owner of the display form was effectively the only change I needed to make.
I will add a few words of warning for anyone attempting this solution. Simply put I've since found out it's not great. It prevents the form or any of its controls from detecting certain key presses (enter and tab) which matters a lot for my usage. You'll find a much better and solution here https://forums.autodesk.com/t5/inventor-forum/dockable-window-with-wpf-controls-don-t-receive-keyboard-input/td-p/9115997