CodedUI "FindMatchingControls()" 在 10% 的时间内工作,但通常 returns 大约一半的控件

CodedUI "FindMatchingControls()" works 10% of the time but usually returns about half of the controls

问题: 我正在使用 FindMatchingControls() 在 WPF table 中创建行集合。我编写了一个循环,将每行中的 ComboBox 设置为给定值。整个过程有时会起作用,但通常情况下,FindMatchingControls() 实际上会找到大约一半的行。我如何配置超时或更改设置以使其每次都能找到所有 50 个控件,或者找到前 10 个然后再找到下 10 个等等?

背景:我正在测试一个 WPF window,上面有一个 table,table 中的每一行都有一个下拉列表。有 50 行,将来可能会更多,所以我无法记录每一行的设置,我记录的测试在每个新版本(每个月左右)中都会过时。

因此我记录了 1 ComboBox 的设置,然后我使用 FindMatchingControls() 创建了一个 Collection。我循环遍历 Collection,将该集合中的每个 ComboBox 设置为所需的选择。前 23 行显示在我当前的屏幕分辨率上。唯一的问题是 FindMatchingControls() 有时 returns 23,有时 26,有时 34,有时 returns 全部 50 行!我的问题是,如何修复下面的代码,使其始终 return 所有 50 行(将来可能更多)。

从代码中可以看出,我找到了两次Parent控件,下面是伪代码。

伪代码:

1) 查找父容器 (table) 2)定义一行(即父行table的子行) 3) 使用 FindMatchingControls 获取行的集合 4) 遍历集合,在每一行中找到 ComboBox 并将其选择设置为传递到方法中的值。

代码:

    public void PlaceAnOrderScreen_SelectItems_List(String item /*Value to set all 50 ComboBoxes to*/)
    {
        WpfControl rowOfOrderItems = new WpfControl(this.UIOptimalOrderSystemClientShWindow.UIItemCustom22.UIListViewAutoID37Table);
        rowOfOrderItems.SearchProperties[WpfControl.PropertyNames.ControlType] = "DataItem";
        rowOfOrderItems.SearchProperties[WpfControl.PropertyNames.ClassName] = "Uia.ListViewItem";
        rowOfOrderItems.WindowTitles.Add("Order Management System");

        rowOfOrderItems.Find();
        rowOfOrderItems.DrawHighlight();  //Visible diagnostic

        //should get a collection of 50 controls ...
        //... but this is dodgy, it sometimes finds 23, 26, 34 or ocassionaly all 50 controls.
        //There are 23 visible controls and the rest, you have to scroll down to see.
        UITestControlCollection itemRows = rowOfOrderItems.FindMatchingControls();

        int c = 0;
        int i = 1;
        string label = String.Empty;

        foreach (var auditSelectionBox in itemRows)
        {
            //After the top 15 drop down selections have been made, strat scrolling down.
            //This is because setting the Value for a list box that is off the screen
            //causes it to complain the control is blocked...
            if (c >= 15)
            {
                if (i >= 3) //The scroll wheel moves 3 rows at a time, so only scroll once for every 3 rows...
                {
                    Mouse.MoveScrollWheel(-1);
                    i = 0;
                }                    
            }
            i++;
            c++;

            WpfCell auditDDL1 = new WpfCell(auditSelectionBox);
            auditDDL1.SearchProperties[WpfCell.PropertyNames.ColumnHeader] = "Total";
            auditDDL1.WindowTitles.Add("OrderSystem 5");

            //Works but takes 5 - 16 seconds per drop down list
            auditDDL1.Value = item;
        }
    }    

您可以使用一种采用 parent(在您的例子中是 table)和 returns 的方法,而不是尝试根据另一行查找匹配的控件 children以递归的方式。它一直向下挖掘,直到找到所有可用的 children。您的 table 有多少行并不重要,它会尝试获取所有行。它可用于任何 UITestControl。

public ParentControl GetChildControls(UITestControl parentControl)
{
    ParentControl parent = new ParentControl();

    if (parentControl != null)
    {
        List<ParentControl> children = new List<ParentControl>();

        foreach (UITestControl childControl in parentControl.GetChildren())
        {
            children.Add(GetChildControls(childControl));
        }

        parent.Children = new KeyValuePair<UITestControl, List<ParentControl>>(parentControl, children);
    }

    return parent;
}

parentclass

public class ParentControl
{
    public KeyValuePair<UITestControl, List<ParentControl>> Children { get; set; }
    public string Value
    {
        get
        {
            return Children.Key.Name;
        }
    }
}

我刚刚添加了 Value 属性 以便于访问 UITestControl 的名称。

PixelPlex(上图)提供了最佳答案。我必须在 PixelPlex 的代码中添加一个 If 语句,以便在找到 ComboBox 时将其设置为一个值。因此,在我的例子中,foreach 如下所示 ...

            foreach (UITestControl childControl in parentControl.GetChildren())
            {
                children.Add(GetChildControls(childControl));

                //Added below If statement to set ComboBox selected item to "Carrots"...
                if (childControl.ClassName == "Uia.ComboBox")
                {
                    WpfComboBox cb = (WpfComboBox)childControl; 
                    cb.SelectedItem = "Carrots";
                }
            }

这将从我的 ComboBox 中选择 Carrots...所有不满足我的 If 语句的内容都不相关,因此我不对其进行任何操作。