编码的UI无法在扩展行中找到控件

时间:2015-08-29 20:25:32

标签: c# wpf coded-ui-tests

this question类似,我正在尝试开发一个Coded UI测试,该测试需要对位于WPF行(行详细信息)中的某些控件执行一些断言。遗憾的是,Coded UI检查器似乎无法找到扩展行中的任何控件,因为它将这些控件标识为自定义控件(Uia.DataGridDetailsPresenter)的子项,该控件是该行的子项。

此网格的应用程序的xaml非常简单,如下所示。

<DataGrid.RowDetailsTemplate>
    <DataTemplate>
        <TextBlock Text="{Binding Details}" Margin="10" />
    </DataTemplate>
</DataGrid.RowDetailsTemplate>

有没有人设法在之前使用Coded UI测试访问行详细信息?

2 个答案:

答案 0 :(得分:1)

我遇到了同样的问题,Coded UI检查员看到了Uia.DataGridDetailsPresenter和它的孩子,但是在测试运行期间无法使用它们。

嗯,您的应用可能存在问题,此DataGrid未针对编码的ui自动化发布。 TabPage内容也遇到了同样的问题。

如果您想知道Coded UI在Wpf应用程序中看到的代码执行此代码,您将在输出中获得一些元素映射 - 复制到excel。如果找到您需要的控件,您的测试也应该找到它们。

    /*
     *  Method used for get map of element and it's children
     *  element - element whose children you want to explore
     *  comma - use empty string - ""
    */

    public void getMap(WpfControl element, String comma)
    {
        comma = comma + "\t";

        foreach (Object child in element.GetChildren())
        {
            WpfControl childAsWpf = child as WpfControl;
            if (childAsWpf != null && !(element is WpfListItem))
            {
                logElementInfo(childAsWpf, comma);
                getMap(childAsWpf, comma);
            }
            else
            {
                System.Diagnostics.Debug.WriteLine("--------- object: {0}; type: {1}", child, child.GetType());
            }
        }
    }

    // logs element info in Output
    private void logElementInfo(WpfControl element, String comma)
    {
        System.Diagnostics.Debug.WriteLine("{0}AutomationId: {1}, ClassName: {2}, ControlType: Wpf{3}", comma, element.AutomationId, element.ClassName, element.ControlType);
    }

答案 1 :(得分:1)

我最后通过编写自己的DataGrid控件来解决这个问题,该控件暴露了所需的自动化同行。

通用自动化同行

class GenericAutomationPeer : UIElementAutomationPeer
{
    public GenericAutomationPeer(UIElement owner)
        : base(owner)
    {

    }

    protected override List<AutomationPeer> GetChildrenCore()
    {
        List<AutomationPeer> list = base.GetChildrenCore();
        list.AddRange(GetChildPeers(Owner));
        return list;
    }

    private List<AutomationPeer> GetChildPeers(UIElement element)
    {
        List<AutomationPeer> automationPeerList = new List<AutomationPeer>();
        for (int i = 0; i < VisualTreeHelper.GetChildrenCount(element); i++)
        {
            UIElement child = VisualTreeHelper.GetChild(element, i) as UIElement;
            if (child != null)
            {
                AutomationPeer childPeer = UIElementAutomationPeer.CreatePeerForElement(child);
                if (childPeer != null)
                {
                    automationPeerList.Add(childPeer);
                }
                else
                {
                    automationPeerList.AddRange(GetChildPeers(child));
                }
            }
        }

        return automationPeerList;
    }
}

自定义DataGrid

public class CustomDataGrid : DataGrid
{
    //Override automation peer that the base class provides as it doesn't expose automation peers for the row details
    protected override AutomationPeer OnCreateAutomationPeer()
    {
        return new GenericAutomationPeer(this);
    }
}