I'm currently making a program that will automate a task that I need to do on a program.
One issue I'm currently having, is "clicking" on a menu in a menu bar.
I found the class name for the menu bar using Spy++, it's called TActionMainMenuBar, but everything "under" it is localized as ammbSSC.
https://i.imgur.com/R7lLfVg.png
I can find the main menu bar using:
var x = window.Get(SearchCriteria.ByClassName("TActionMainMenuBar"));
Console.WriteLine(x.ToString());
Which returns:
Panel. AutomationId:1311676, Name:ammbSSC, ControlType:pane, FrameworkId:Win32
TestStack.White.Application
But trying to find "ACTIONS" using .ByText or .ByIndex (or anything else really) throws an exception that it can't find "ACTIONS".
Can I even find the text like this? Or should I resort to using mouse input - i.e. automating mouse movements?
EDIT:
I've tried doing it like this as well:
window.GetMultiple(SearchCriteria.ByControlType(ControlType.Pane).AndByClassName("TActionMainMenuBar"))[1].Click();
But that throws a 'Index was outside the bounds of the array.'
I've also tried doing it as:
window.GetMultiple(SearchCriteria.ByControlType(ControlType.Pane))[1].Click();
And:
window.GetMultiple(SearchCriteria.ByControlType(ControlType.Pane).AndByClassName("TActionMainMenuBar").AndByText("ACTIONS"));
window.Click();
But that moves my mouse to around the center of my screen.
I've seen "menu bar" being wrapped in another control, which you can then use to find what you presumed to be the child element of said menu bar.
In one of my cases, the menu bar was in a window (popup), I then find the "action" in the popup as below.
Window PopUp => Window.ModalWindows().Last(); //Gets the latest popup
var all = PopUp.GetMultiple(SearchCriteria.ByControlType(ControlType.Text)); //Get all the options, most cases, the menu items are in a textbox, use whatever you see in your spy tool
var menu = all.FirstOrDefault(m => m.Name.Equals("actionValue") && m.Visible);
menu?.Click();
Heads up - I've ran into click issue with this type of control before, hopefully that doesn't happen for you..."thread click" on the object to get it to work.
Related
Currently I used this snip code as a result from googling.
var eventArgs = new TextCompositionEventArgs(Keyboard.PrimaryDevice,
new TextComposition(InputManager.Current, Keyboard.FocusedElement, "A"));
eventArgs.RoutedEvent = TextInputEvent;
var flag = InputManager.Current.ProcessInput(eventArgs);
It was working if I used Keyboard.Focus(TxtBox); and the TxtBox will be filled with the Keystroke.
But what I want really achieved is:
1.Drawing a box (for example, I draw box on one of the excel cell)
2.Click on the box coordinate (to change Keyboard Focus)
3.Send Keystroke to clicked excel cell
I have done step 1 and 2.
But I can't find a way to do the third step.
Somehow, the click event (using mouse event) maybe not changing Keyboard Focus automatically.
So, how do I change Keyboard focus, if possible using coordinate ?
Or maybe can I get IInputElement from a coordinate ? and then set keyboard focus to it.
Of course, all of it outside from the main application window of the WPF.
Found it !
At:
Installed InputSimulator via NuGet, no members accessible
It is working in most cases.
I said in most cases, because it is able to type in other window like excel application, but on other custom app window. There might be a case it won't work.
Hope it help for other people, looking for the same thing.
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 relatively new to UWP, but I have good WPF background.
What I need is a simple context menu for the application. User "right taps" anywhere, menu opens, user taps an item and things happen.
It looks basic and simple. First I add MenuFlyout element to my Application.Resources. Then, in MainPage I just show it with ShowAt method. Works.
To my greatest surprise when I tried to add events to menu items, VS told me it's invalid, events cannot be added in App.xaml.
So here's my assignment (in App.xaml.cs):
MainContextMenu = (MenuFlyout)Resources["MainContextMenu"];
MainContextMenu.Items.First(i => i.Name == "NavToCalibration").Tapped += NavToCalibration_Tapped;
The problem is - the handler is never called. I run my app, open the menu, click on the item and nothing happens. The assigned method is not called. What am I doing wrong? Why the handler is not called?
The assignment IS executed on application launch.
I'm also surprised I haven't been able to find any example or tutorial on doing such a simple and basic thing.
There is a good reason I use app-wide context menu instead of other controls. The app displays test images, it has to be full-screen (or maximized window) without interfering elements.
Now I will try to move my menu to the page resources, my pages will have different context menus anyway. But I'm really curious what's wrong in MenuFlyout defined in App.xaml?
Whoa. I tried to move my MenuFlyout to MainPage. I was able to assign Tapped event in XAML. And it also is not triggered! Now I'm completely lost. Any ideas?
i'm try to send click message to (or invoke) a button in another application .
i used UISpy.exe and could find the element which i need.
but it has no id,no clickablePoint and no Invoke pattern.
i tried following code:
var processStartInfo = new ProcessStartInfo(#"tdesktop\Program.exe");
var proc = Process.Start(processStartInfo);
Thread.Sleep(3000);
AutomationElement mainWin = AutomationElement.RootElement.FindChildByProcessId(proc.Id);
List<AutomationElement> elmList= GetChildren(mainWin);
//MessageBox.Show(elmList.Count.ToString());
if (elmList.Count == 7)
{
List<AutomationElement> menubar= GetChildren(elmList[6]);
AutomationElement elementNode = menubar[1];
double x = elementNode.GetClickablePoint().X;
double y = elementNode.GetClickablePoint().Y;
win32 w = new win32();
w.move_left_click((UInt32)x, (UInt32)y);
}
it throws an exception in elementNode.GetClickablePoint().X that the Autumation Element has no clickable point.
i tried also TryGetInvokePattern() but still throws execption it has no InvokePattern.
i use VS2012 and .net 4.5
is there any way to make this?
As was already suggested, I'd strongly recommend pointing the Inspect SDK tool to the UI you're interested in. The tool (inspect.exe) be found in places like "C:\Program Files (x86)\Windows Kits\8.1\bin\x64".
By using the tool, you can see how the UI element of interest is being exposed programmatically. For example, is it exposed as a single UIA element, or it is part of a larger UIA element which represents a set of UI elements shown visually, and what UIA patterns does it support? As a test, I just pointed Inspect to an arrow shape in Paint. The results are shown below.
So I can tell that the arrow is exposed programmatically as a single UIA element, and that it supports the Invoke pattern. This means I can programmatically invoke the button through UIA. (And I can call the pattern methods on the element from inside Inspect’s Action menu, which is pretty handy.) If the UIA element didn't support any patterns that would allow me to programmatically control it, I can find its BoundingRectangle property through UIA, and simulate a mouse click in the middle of that to invoke it. (And I'm assuming the button's not obscured when I simulate the mouse click.)
But if I look at another group of elements shown visually on the screen, using Inspect I can learn that the whole set is exposed through UIA as a single UIA element. So in the image of Inspect shown below, I can learn that I'm not able to programmatically invoke a specific color in that group.
So in that case, I'd probably have to assume I know the size and layout of the UI elements shown visually in that group, and simulate a mouse click at some point which I think is appropriate based on the color I want to invoke.
By using Inspect, I can get a good understanding of what my options are. Ideally a single element shown visually on the screen will be exposed through UIA as a single element that I can control through whatever patterns are relevant, (for example, Invoke, Toggle, SelectionItem etc). But if useful patterns aren't supported, then I could consider simulating mouse clicks instead, based on whatever ClickablePoint or BoundingRectangle data's exposed.
Thanks,
Guy
A menu bar doesn't expose the InvokePattern (see UI Automation Support for the MenuBar Control Type). However, a menu item can be Invoked (see UI Automation Support for the MenuItem Control Type).
The following code illustrates how to generate a list of menu items:
AutomationElementCollection items = menubar.FindAll(
TreeScope.Children,
new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.MenuItem));
Im trying to implement my own popup menu from a UITabBar.
My app allows users to specify which menus are displayed on the tab bar and I'm not keen on the default "More" button that iOS uses when there are a lot of tab bar items so I would like to create some of the tab bar items to be "Sub menus" that pup up a menu of further buttons. I would like it to pop up from the tabbaritem itself and the order of the tabs may not be the same for every user.
So far I can find the tabbaritem the user has selected but next i need to know its location so I can animate a popup menu from that location.
Does anyone know how I could go about finding the frame or position of the selected tabbaritem?
You can iterate trough the subviews of your UITabBar and get only those subviews which are a type of UITabBarButton class. Then you get the frame of the subviews you are interested in.
List<RectangleF> tabBarButtonFrames = new List<RectangleF>();
foreach (var view in this.tabBarController.TabBar.Subviews) {
if (view.ToString().Contains("UITabBarButton")) {
tabBarButtonFrames.Add(view.Frame);
}
Console.WriteLine(view.ToString() + "\t" + view.Frame.ToString());
}
Note: This link contains more ways of getting the Objective-C class names from poupou