How to select an item in combobox in F# for UI automation
-
Friday, March 30, 2012 6:43 AM
invalid operation at
let pattern : SelectionPattern = LoginNameComboBox.GetCachedPattern(SelectionPattern.Pattern) :?> SelectionPattern <- error when run
let LoginNameComboBox : AutomationElement = LoginWin.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.AutomationIdProperty, "cboUserID")); if LoginNameComboBox = null then Console.WriteLine("No LoginNameComboBox") else Console.WriteLine("Got LoginNameComboBox") let pattern : SelectionPattern = LoginNameComboBox.GetCachedPattern(SelectionPattern.Pattern) :?> SelectionPattern <- error when run let selectedItems = pattern.Cached.GetSelection(); let selectedItem = selectedItems.[0]
All Replies
-
Friday, March 30, 2012 12:34 PM
What kind of runtime exception do you have there?
I suppose that casting operator gives you an error, so maybe you should cast to different pattern (ex. SelectionItemPattern etc.) I think you can find out real object type in debugger.
Petr
-
Tuesday, April 03, 2012 6:30 AM
do not know why null reference error
http://stackoverflow.com/questions/5814779/selecting-combobox-item-using-ui-automation
let GetSpecifiedPattern(element : AutomationElement, patternName : string) : AutomationPattern = let supportedPattern = element.GetSupportedPatterns() <--- error let mutable p : AutomationPattern = null for pattern in supportedPattern do if pattern.ProgrammaticName = patternName then p <- pattern p let SetSelectedComboBoxItem(comboBox : AutomationElement, item : string) = let automationPatternFromElement : AutomationPattern = GetSpecifiedPattern(comboBox, "ExpandCollapsePatternIdentifiers.Pattern") let expandCollapsePattern : ExpandCollapsePattern = comboBox.GetCurrentPattern(automationPatternFromElement) :?> ExpandCollapsePattern expandCollapsePattern.Expand() expandCollapsePattern.Collapse() let listItem : AutomationElement = comboBox.FindFirst(TreeScope.Subtree, new PropertyCondition(AutomationElement.NameProperty, item)) automationPatternFromElement = GetSpecifiedPattern(listItem, "SelectionItemPatternIdentifiers.Pattern") let selectionItemPattern : SelectionItemPattern = listItem.GetCurrentPattern(automationPatternFromElement) :?> SelectionItemPattern selectionItemPattern.Select() let process = Process.Start("..\\..\\..\\FinancialReportWPF\\bin\\Release\\FinancialReportWPF.exe") let processId = process.Id; let Desktop : AutomationElement = AutomationElement.RootElement if Desktop = null then Console.WriteLine("Unable to get Desktop") else Console.WriteLine("Found Desktop\n") let mutable numWaits = 0; let mutable LoginWin : AutomationElement = null while LoginWin = null && numWaits < 50 do Console.WriteLine("Looking for Login window. . . ") LoginWin <- Desktop.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.NameProperty, "Test Financial Reporting")); numWaits <- numWaits + 1 Thread.Sleep(200) if LoginWin = null then Console.WriteLine("Failed to find Login window") else Console.WriteLine("Found Login window") let LoginNameComboBox : AutomationElement = LoginWin.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.AutomationIdProperty, "cboUserID")); if LoginNameComboBox = null then Console.WriteLine("No LoginNameComboBox") else Console.WriteLine("Got LoginNameComboBox") SetSelectedComboBoxItem(LoginNameComboBox, "MASTER") -
Wednesday, April 04, 2012 12:42 PMWell, from your listing it seems that your 'LoginNameComboBox' is null. Do you have any output in Console window?
Petr
-
Thursday, April 05, 2012 1:07 AM
Console said got all the controls
AutomationElement.NameProperty <- error said this is null result in element null in the following function
let GetSpecifiedPattern(element : AutomationElement, patternName : string) : AutomationPattern =
// Learn more about F# at http://fsharp.net open System.Windows.Automation open System.Diagnostics open System.Threading open System (* let FindWindowByProcessId(processId : int) : AutomationElement = let targetWindow : AutomationElement= null let mutable count = 0; let p : Process = Process.GetProcessById(processId); let targetWindow = AutomationElement.FromHandle(p.MainWindowHandle); targetWindow //let FindElementById(processId : int, automationId : string) : AutomationElement = //let aeForm : AutomationElement = FindWindowByProcessId(processId) let FindElementById(processId : AutomationElement, automationId : string) : AutomationElement = let aeForm : AutomationElement = processId let tarFindElement : AutomationElement = aeForm.FindFirst(TreeScope.Descendants, new PropertyCondition(AutomationElement.AutomationIdProperty, automationId)) tarFindElement let GetSelectionItemPattern(element : AutomationElement) : SelectionItemPattern = let mutable currentPattern : obj = null //p./ProgrammaticName <- "MASTER" if element.TryGetCurrentPattern(SelectionItemPattern.Pattern, ¤tPattern) = false then Console.WriteLine("Element with AutomationId '{0}' and Name '{1}' does not support the SelectionItemPattern.", element.Current.AutomationId, element.Current.Name); currentPattern :?> SelectionItemPattern *) let GetSpecifiedPattern(element : AutomationElement, patternName : string) : AutomationPattern = let supportedPattern = element.GetSupportedPatterns() let mutable p : AutomationPattern = null for pattern in supportedPattern do if pattern.ProgrammaticName = patternName then p <- pattern p let SetSelectedComboBoxItem(comboBox : AutomationElement, item : string) = let automationPatternFromElement : AutomationPattern = GetSpecifiedPattern(comboBox, "ExpandCollapsePatternIdentifiers.Pattern") let expandCollapsePattern : ExpandCollapsePattern = comboBox.GetCurrentPattern(automationPatternFromElement) :?> ExpandCollapsePattern expandCollapsePattern.Expand() expandCollapsePattern.Collapse() let listItem : AutomationElement = comboBox.FindFirst(TreeScope.Subtree, new PropertyCondition(AutomationElement.NameProperty, item)) automationPatternFromElement = GetSpecifiedPattern(listItem, "SelectionItemPatternIdentifiers.Pattern") let selectionItemPattern : SelectionItemPattern = listItem.GetCurrentPattern(automationPatternFromElement) :?> SelectionItemPattern selectionItemPattern.Select() let process = Process.Start("..\\..\\..\\FinancialReportWPF\\bin\\Release\\FinancialReportWPF.exe") let processId = process.Id; let Desktop : AutomationElement = AutomationElement.RootElement if Desktop = null then Console.WriteLine("Unable to get Desktop") else Console.WriteLine("Found Desktop\n") let mutable numWaits = 0; let mutable LoginWin : AutomationElement = null while LoginWin = null && numWaits < 50 do Console.WriteLine("Looking for Login window. . . ") LoginWin <- Desktop.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.NameProperty, "Test Financial Reporting")); numWaits <- numWaits + 1 Thread.Sleep(200) if LoginWin = null then Console.WriteLine("Failed to find Login window") else Console.WriteLine("Found Login window") let mutable LoginButton = LoginWin.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.NameProperty, "Login")) if LoginButton = null then Console.WriteLine("No LoginButton"); else Console.WriteLine("Got LoginButton"); let mutable QuitButton = LoginWin.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.NameProperty, "Quit")) if QuitButton = null then Console.WriteLine("No QuitButton"); else Console.WriteLine("Got QuitButton"); let LoginNameComboBox : AutomationElement = LoginWin.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.AutomationIdProperty, "cboUserID")); if LoginNameComboBox = null then Console.WriteLine("No LoginNameComboBox") else Console.WriteLine("Got LoginNameComboBox") let PasswordTextBox : AutomationElement = LoginWin.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.AutomationIdProperty, "txtPassword")); if PasswordTextBox = null then Console.WriteLine("No txtPassword") else Console.WriteLine("Got txtPassword") let vpLoginTextBox : ValuePattern = PasswordTextBox.GetCurrentPattern(ValuePattern.Pattern) :?> ValuePattern vpLoginTextBox.SetValue("testtest") //let element : AutomationElement = FindElementById(processId, "cboUserID") SetSelectedComboBoxItem(LoginNameComboBox, "MASTER") //let element : AutomationElement = FindElementById(LoginNameComboBox, "5") //let selectionItemPattern : SelectionItemPattern = GetSelectionItemPattern(element) //selectionItemPattern.Select() //selectionItemPattern.Select() (* // Set up the CacheRequest. let comboCacheRequest = new CacheRequest() comboCacheRequest.Add(SelectionPattern.Pattern) comboCacheRequest.Add(SelectionPattern.SelectionProperty) comboCacheRequest.Add(AutomationElement.NameProperty) comboCacheRequest.TreeScope <- TreeScope.Element // TreeScope.Descendants; // Activate the CacheRequest and get the element. //use comboCacheRequest.Activate() // Load the combo box element and cache the specified properties and patterns. let propCondition : PropertyCondition = new PropertyCondition(AutomationElement.AutomationIdProperty, "cboUserID", PropertyConditionFlags.IgnoreCase) let mutable elementCombo = LoginWin.FindFirst(TreeScope.Descendants, propCondition); let propCondition1 : PropertyCondition = new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.List) let listElement : AutomationElement = elementCombo.FindFirst(TreeScope.Children, propCondition1); *) // Register for ElementSelectedEvent on list items. (* if listElement <> null then Automation.AddAutomationEventHandler(SelectionItemPattern.ElementSelectedEvent, listElement, TreeScope.Children, selectHandler = new AutomationEventHandler(OnListItemSelect)) else7 Console.WriteLine("No listElement") *) //let pattern : SelectionPattern = LoginNameComboBox.GetCachedPattern(SelectionPattern.Pattern) :?> SelectionPattern //let selectedItems = pattern.Cached.GetSelection(); //let selectedItem = selectedItems.[1] //let ipClickLoginButton : InvokePattern =(InvokePattern)LoginButton.GetCurrentPattern(InvokePattern.Pattern); //ipClickLoginButton.Invoke(); //Thread.Sleep(1500) (* let ipClickQuitButton : InvokePattern = QuitButton.GetCurrentPattern(InvokePattern.Pattern) :?> InvokePattern ipClickQuitButton.Invoke(); Thread.Sleep(1500) *) Console.ReadKey()

