0
\$\begingroup\$

I wrote a method that finds a child item in a menu based on some condition. The code works but in the cases when I'm searching for more items which are way down in the tree structure it will take a long time to do it.

Usually, when I'm writing some tests that use this method, the items that I'm searching for are in close proximity, so I think it's no point to start the search again from the top. I want to somehow start again from the position of the last element found and do a search in close proximity(meaning look first at the parent node of the item that was found and the other children of the parent node ) of that position and if that fails run the method that I wrote which starts from the root.

The code looks like this:

public abstract class TmUIElementBase {

    protected readonly AutomationElement Element;

    protected virtual AutomationElement SearchFrom => Element;

    private AutomationElement vParent;

    protected AutomationElement Parent =>
        vParent ??
        (vParent = TreeWalker.ControlViewWalker.GetParent(Element));

    protected TmUIElementBase(AutomationElement element) {
        Element = element;
    }

    protected static AutomationElement FindAutomationElement(TmUIElementBase parent, Condition condition) {
        var walker = TreeWalker.ControlViewWalker;
        var worklist = new Queue<AutomationElement>();
        worklist.Enqueue(parent.SearchFrom);
        while (worklist.Any()) {
            var element = worklist.Dequeue();
            var child = walker.GetFirstChild(element);
            while (child != null) {
                var result = child.FindFirst(TreeScope.Element, condition);
                if (result != null) {
                    return result;
                }
                worklist.Enqueue(child);
                child = walker.GetNextSibling(child);
            }
        }
        throw new Exception("FindAutomationElement: Element not found");
    }
}
\$\endgroup\$
  • \$\begingroup\$ What's the definition of TmUIElementBase? And how do you use this method in practice? Do subsequent calls use the same condition? \$\endgroup\$ – Pieter Witvoet May 29 at 14:00
  • \$\begingroup\$ I edited the question and included the whole TmUIElementBase class. As I said in the description is a method that I use for testing different element from the UI such as a button or a checkbox. There are no subsequent calls using the condition. \$\endgroup\$ – andreiy05 May 29 at 14:06
  • 2
    \$\begingroup\$ I'm not all that familiar with the UI Automation framework, but it looks like this is essentially a breadth-first variant of parent.SearchElement.FindFirst(TreeScope.Descendants, new AndCondition(Automation.ControlViewCondition, condition))? \$\endgroup\$ – Pieter Witvoet May 29 at 15:27
  • 1
    \$\begingroup\$ Like @PeterWitvoet commented you should use the FindFirst() method. In the docs you will find "Navigating the UI Automation tree using TreeWalker can result in cross-process calls and is not as efficient as locating an element using the FindAll or FindFirst methods." \$\endgroup\$ – Heslacher May 29 at 16:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.