I've been playing around with UI automation. I would like to be able to detect when specific textboxes which are present inside a web page, opened in Internet Explorer.
I've noticed that using the managed libraries for this do not perform in the same as the COM libraries do.
Here, I've made two examples that demonstrate the problem:
Working one, will provide "AutomationId" property value of my edit field:
static void Main_COM(string[] args) { //Automation reference. IUIAutomation automation = new CUIAutomation(); //Desktop Element reference. IUIAutomationElement desktop = automation.GetRootElement(); // Get the IE "Frame Tab" elements. IUIAutomationCondition processIdCondition = automation.CreatePropertyCondition(AutomationElement.ProcessIdProperty.Id, 8948); IUIAutomationCondition frameTabClassNameCondition = automation.CreatePropertyCondition(AutomationElement.ClassNameProperty.Id, "Frame Tab"); IUIAutomationCondition tabFramesCondition = automation.CreateAndCondition(processIdCondition, frameTabClassNameCondition); IUIAutomationElementArray frameElements = desktop.FindAll(interop.UIAutomationCore.TreeScope.TreeScope_Subtree, tabFramesCondition); //get the first Frame Tab element found. IUIAutomationElement frameTabElement = frameElements.GetElement(0); //get the first IE Server Pane element found. IUIAutomationCondition ieServerClassNameCondition = automation.CreatePropertyCondition(AutomationElement.ClassNameProperty.Id, "Internet Explorer_Server"); IUIAutomationTreeWalker ieServerClassNameWalker = automation.CreateTreeWalker(ieServerClassNameCondition); IUIAutomationElement ieServerElement = ieServerClassNameWalker.GetFirstChildElement(frameTabElement); //Locate all the edit fields contain in the ieServerElement. IUIAutomationCondition editControlCondition = automation.CreatePropertyCondition(AutomationElement.ControlTypeProperty.Id, ControlType.Edit.Id); IUIAutomationTreeWalker EditWalker = automation.CreateTreeWalker(editControlCondition); //get the first edit field from the results. IUIAutomationElement editControl = EditWalker.GetFirstChildElement(ieServerElement); //Obtain the AutomationID and ValuePattern.Value of the Edit field. String value = editControl.GetCurrentPropertyValue(ValuePattern.ValueProperty.Id) as String; String id = editControl.CurrentAutomationId; //Write the ID and value to the Console window. Console.WriteLine(String.Format("{0} = {1}", id, value)); }
Now, if I do pretty much the exact same thing using the managed classes (using the code below) the "AutomationId" property is NEVER populated. I've tried several different ways about getting to my edit field, but nothing I try allows me to access the AutomationId via Managed UI Automation library, the COM version works flawlessly.
static void Main_managed(string[] args) { //Desktop Element reference. AutomationElement desktop = AutomationElement.RootElement; // Get the IE "Frame Tab" elements. Condition processIdCondition = new PropertyCondition(AutomationElement.ProcessIdProperty, 8948); Condition frameTabClassNameCondition = new PropertyCondition(AutomationElement.ClassNameProperty, "Frame Tab"); Condition tabFramesCondition = new AndCondition(processIdCondition, frameTabClassNameCondition); AutomationElementCollection frameElements = desktop.FindAll(System.Windows.Automation.TreeScope.Subtree, tabFramesCondition); //get the first Frame Tab element found. AutomationElement frameTabElement = frameElements[0]; //get the first IE Server Pane element found. Condition ieServerClassNameCondition = new PropertyCondition(AutomationElement.ClassNameProperty, "Internet Explorer_Server"); TreeWalker ieServerClassNameWalker = new TreeWalker(ieServerClassNameCondition); AutomationElement ieServerElement = ieServerClassNameWalker.GetFirstChild(frameTabElement); //Locate all the edit fields contain in the ieServerElement. Condition editControlCondition = new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Edit); TreeWalker EditWalker = new TreeWalker(editControlCondition); //get the first edit field from the results. AutomationElement editControl = EditWalker.GetFirstChild(ieServerElement); //Obtain the AutomationID and ValuePattern.Value of the Edit field. String value = editControl.GetCurrentPropertyValue(ValuePattern.ValueProperty) as String; String id = editControl.Current.AutomationId; //Write the ID and value to the Console window. Console.WriteLine(String.Format("{0} = {1}", id, value)); }
This smells like a bug? anyone know of a workaround for this, which is not using the COM interop libraries?