I am trying to get the value of the URL in Firefox using the following code. The problem is it only returns "Search or enter address" (see tree structure with Inspect.exe below). It looks like I need to go one level down. Can someone show me how to do this.
public static string GetFirefoxUrl(IntPtr pointer) {
AutomationElement element = AutomationElement.FromHandle(pointer);
if (element == null)
return null;
AutomationElement tsbCtrl = element.FindFirst(TreeScope.Subtree, new PropertyCondition(AutomationElement.NameProperty, "Search or enter address"));
return ((ValuePattern)tsbCtrl.GetCurrentPattern(ValuePattern.Pattern)).Current.Value as string;
}
For the tree structure, see:
It's not clear which element you are starting the search from, but you've got two elements with that name. One is a combo box control the other is an edit control. Try using using an AndCondition to combine multiple PropertyCondition objects:
var nameCondition = new PropertyCondition(AutomationElement.NameProperty, "Search or enter address");
var controlCondition = new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Edit);
var condition = new AndCondition(nameCondition, controlCondition);
AutomationElement editBox = element.FindFirst(TreeScope.Subtree, condition);
// use ValuePattern to get the value
If the search starts from the combo box, you could instead change TreeScope.Subtree to TreeScope.Descendants since Subtree includes the current element in the search.
Related
I'm trying to use automation to find a tree item in an instance of a WinForms FolderBrowserDialog
I show the dialog in one process and then call the following in another test process:
var dlg = AutomationElement.RootElement.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.NameProperty, "Browse For Folder"));
var treectrl = dlg.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.ClassNameProperty, "SHBrowseForFolder ShellNameSpace Control"));
var treeview = treectrl.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.ClassNameProperty, "SysTreeView32"));
var item = treeCtrl.FindFirst(TreeScope.Descendants, new AndCondition(
new PropertyCondition(AutomationElement.NameProperty, "Desktop"),
new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.TreeItem)));
dlg, treectrl, and treeview come back with valid AutomationElements but item ends up being null even though, when I use the Inspect app, it shows that item with the name "Desktop" as an immediate child of the treeview.
When I tried to use a TreeWalker to walk through the tree control children, all I see are the scrollbar and its children.
Is there something else I need to do to be able to find tree items in a shell tree control?
I used the UIAutomationClient API to retrieve an AutomationElement t:
AutomationElement t = AutomationElement.RootElement.FindFirst(...);
The WPF counterpart of t is a TabItem inside a TabControl. I want to activate the tab that t represents (i.e. bring t into foreground). How do I do that?
I tried t.SetFocus();, but it did not have any (visible) effect at all.
If I had the TabItem (let's call it tabItem), I would just call
tabItem.IsSelected = true;
So I thought by using the select pattern I could achieve the same:
var p = t.GetCurrentPattern(SelectionItemPattern.Pattern) as SelectionItemPattern;
p.Select();
It turned out that the IsSelected property of p already is true prior to selecting it - so calling Select still does not select/activate the tab. But in the GUI, the TabItem is clearly not selected/activated.
I encountered the same problem, This is my solution below hope it helps even though it's already late.
Example UI:
Sample Code:
AutomationElement aeDesktop = AutomationElement.RootElement;
AutomationElement aeForm = aeDesktop.FindFirst(TreeScope.Descendants, new PropertyCondition(AutomationElement.NameProperty, "davinceleecode"));
AutomationElement aeTabControl = aeForm.FindFirst(TreeScope.Descendants, new PropertyCondition(AutomationElement.AutomationIdProperty, "tabControl1"));
aeTabControl.SetFocus();
AutomationElement aeTabPage = aeTabControl.FindFirst(TreeScope.Descendants, new PropertyCondition(AutomationElement.NameProperty, "tabPage2"));
SelectionItemPattern changeTab_aeTabPage = aeTabPage.GetCurrentPattern(SelectionItemPattern.Pattern) as SelectionItemPattern;
changeTab_aeTabPage.Select();
Please check the IsKeyboardFocusable properties and make sure this is set to true.
I'm trying to identify a windows static text control using a partial NameProperty. Here's the code I have:
// Get a reference to the window
AutomationElement epoWindow = AutomationElement.RootElement.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.ClassNameProperty, "MsiDialog"));
// Get a reference to the control
AutomationElement epoControl = epoWindow.FindFirst(TreeScope.Descendants, new PropertyCondition(AutomationElement.NameProperty, controlText));
I currently need the full controlText string for this to work but I'd like to search for a part of that string and return any controls found.
How do I do this?
Thanks,
John
You can iterate on a child collection with the prefefined TrueCondition, like this:
foreach(AutomationElement child in epoWindow.FindAll(TreeScope.Subtree, Condition.TrueCondition))
{
if (child.Current.Name.Contains("whatever"))
{
// do something
}
}
PS: You want to carefully choose the TreeScope if you don't want to kill the performance of your app (if it has a big children hierarchy) or wait indefinitely...
I am trying to automate sharepoint 2010 people picker, but it is very difficult even to highlight any control inside the window.
I have used hand coding to find the window but the controls inside the window are not highlighting.
WinWindow pp = new WinWindow(browserWindow);
pp.TechnologyName = "MSAA";
pp.SearchProperties[WinWindow.PropertyNames.ClassName] = "Internet Explorer_TridentDlgFrame";
pp.SearchProperties[WinWindow.PropertyNames.ControlType] = "Window";
pp.SearchProperties[WinWindow.PropertyNames.Name] = "Select People -- Webpage Dialog";
pp.Find();
pp.DrawHighlight();
Microsoft.VisualStudio.TestTools.UITesting.HtmlControls.HtmlDocument doc = new Microsoft.VisualStudio.TestTools.UITesting.HtmlControls.HtmlDocument(pp);
doc.TechnologyName = "Web";
doc.SearchProperties[Microsoft.VisualStudio.TestTools.UITesting.HtmlControls.HtmlDocument.PropertyNames.TagName] = "BODY";
doc.SearchProperties[Microsoft.VisualStudio.TestTools.UITesting.HtmlControls.HtmlDocument.PropertyNames.FrameDocument] = "False";
doc.SearchProperties[Microsoft.VisualStudio.TestTools.UITesting.HtmlControls.HtmlDocument.PropertyNames.RedirectingPage] = "False";
doc.SearchProperties[Microsoft.VisualStudio.TestTools.UITesting.HtmlControls.HtmlDocument.PropertyNames.ControlType] = "Document";
doc.SearchProperties[Microsoft.VisualStudio.TestTools.UITesting.HtmlControls.HtmlDocument.PropertyNames.Title] = "Select People";
doc.SearchProperties[Microsoft.VisualStudio.TestTools.UITesting.HtmlControls.HtmlDocument.PropertyNames.PageUrl] = PAGE_URL_Here;
doc.SearchProperties[Microsoft.VisualStudio.TestTools.UITesting.HtmlControls.HtmlDocument.PropertyNames.AbsolutePath] = AbsolutePath_Here;
doc.SearchProperties[Microsoft.VisualStudio.TestTools.UITesting.HtmlControls.HtmlDocument.PropertyNames.ClassName] = "HtmlBody";
doc.SearchProperties[Microsoft.VisualStudio.TestTools.UITesting.HtmlControls.HtmlDocument.PropertyNames.FriendlyName] = "Select People";
doc.SearchProperties[Microsoft.VisualStudio.TestTools.UITesting.HtmlControls.HtmlDocument.PropertyNames.HasFocus] = "False";
doc.SearchProperties[Microsoft.VisualStudio.TestTools.UITesting.HtmlControls.HtmlDocument.PropertyNames.Exists] = "True";
doc.SearchProperties[Microsoft.VisualStudio.TestTools.UITesting.HtmlControls.HtmlDocument.PropertyNames.Enabled] = "True";
doc.SearchProperties[Microsoft.VisualStudio.TestTools.UITesting.HtmlControls.HtmlDocument.PropertyNames.IsTopParent] = "False";
doc.Find();
doc.DrawHighlight();
Above code easily highlights people picker window and used this object to find the control inside it is not finding any.
It is showing this error...
The playback failed to find the control with the given search properties. Additional Details:
TechnologyName: 'Web'
TagName: 'BODY'
FrameDocument: 'False'
RedirectingPage: 'False'
ControlType: 'Document'
Am i doing it right.
I found the answer for this,..
Well using crosshair or recording show the control on peoplepicker as separeate control but while finding through code all the control in it are shown as Edit box.
so need to store all control in a UITestControlCollection and use loop to find the control needed using its name property.
Then do the mouse or keyboard action.
//write ur code here to find the parent control
UITestControlCollection controlFound = matching.FindMatchingControls();
//use loop to find the control
We are using the code below to get a list of items out of a ComboBox inside another application's window. This code works (correctly retrieves the list of items) for ComboBoxes in any other application we've tested this code on, however for this particular application the Name property retrieved for each ListItem is garbled.
Here is the code:
using System.Windows.Automation;
var condition = new PropertyCondition(AutomationElement.NameProperty, "Change/Add/Delete Setting");
var condition2 = new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Window);
var condition3 = new AndCondition(new Condition[] {condition, condition2});
var window = AutomationElement.RootElement.FindFirst(TreeScope.Subtree, condition3);
condition = new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.ComboBox);
var combo = window.FindFirst(TreeScope.Subtree, condition);
condition = new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.ListItem);
AutomationElementCollection children = combo.FindAll(TreeScope.Subtree, condition);
var comboItems = new List<string>();
foreach (AutomationElement child in children)
{
comboItems.Add(child.Current.Name);
}
And here is a screenshot of what we end up with for this one app.
What could cause the Name property to be garbled like this? Could this be an encoding problem?
How can we get the correct text for each item?
If this combobox has the CBS_OWNERDRAWFIXED or CBS_OWNERDRAWVARIABLE style, or the contained listbox has the LBS_OWNERDRAWFIXED or LBS_OWNERDRAWVARIABLE style. then the text isn't known by the control at all. When an app uses one of these styles, it gets WM_DRAWITEM messages whenever the control needs to draw, then it pulls the text from it's pocket and draws it wherever it was asked to.
This is a trick that allows an application to quickly and easily change the contents of a listbox or combobox on the fly, it's mostly used when the contents are volatile or when there are LOTS of items. It's one way to get around the limit on the number of items an listbox/combobox can hold.
Use Spy++ to check the styles on these windows.