Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
468 views
in Technique[技术] by (71.8m points)

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

Problem: I am using FindMatchingControls() to create a Collection of rows in a WPF table. I have written a loop that will set the ComboBox in each row to a given value. The whole thing works sometimes but more often than not, FindMatchingControls() actually finds about half of the rows. How can I configure timeouts or change settings to make it find all 50 controls every time or perhaps to find the first 10 and then to find the next 10 etc?

Background: I am testing a WPF window and on it, there's a table, each row in the table has a drop down list. There are 50 rows and in future there could be more so it is not feasible for me to record the setting of each one, my recorded test would be out of date with each new version (every month or so).

I have therefore recorded the setting of 1 ComboBox and then I used FindMatchingControls() to create a Collection. I loop through the Collection setting each ComboBox in that collection to the desired selection. The first 23 rows are shown on my current screen resolution. The only problem is that FindMatchingControls() sometimes returns 23, sometimes 26 , sometimes 34 and sometimes it returns all 50 rows! My question is, how do I fix the code below so that it always return all 50 rows (and possibly more in future).

You can see from the code that I found the Parent control twice so pseudo code is below.

Psuedo Code:

1) Find Parent Container (table) 2) Define a row (that is a child of the parent table) 3) Use FindMatchingControls to get a Collection of Rows 4) Loop through the Collection, finding the ComboBox in each row and setting it's selection to a value passed into the method.

CODE:

    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;
        }
    }    
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Instead of trying to find matching controls based on another row, you could use a method that takes the parent (in your case the table) and returns all it's children in a recursive way. It digs all the way down until all available children have been found. It shouldn't matter how much row's your table has, it will try and get all of them. It's usable for any 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;
}

The parent class

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

I just added the Value property for easy access to the name of UITestControl.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...