Как найти объект Silvlerlight на странице Asp.Net с помощью тестирования автоматизации пользовательского интерфейса Microsoft? - PullRequest
0 голосов
/ 04 августа 2010

У меня есть объект на моей странице asp.net, содержащий xap Silverlight (в моем конкретном случае это IFrame, но мне также любопытно, что такое обычные объекты).Я могу найти этот элемент в UI Spy, но название просто говорит «Silverlight Control».Попытка обнаружить, что AutomationElement в моем автоматическом тесте не удалась (контроль каждый раз равен нулю).Есть ли настройка в коде Silverlight или в HTML, который поможет?Как я могу отличить его, если на одной странице есть несколько элементов управления Silverlight?

<object id="silverlightClient" style="display:none;" data="data:application/x-silverlight-2," type="application/x-silverlight-2">
    <param name="source" value="../../ClientBin/SilverlightApplication.xap"/>
    <param name="onerror" value="onSilverlightError" />
    <param name="background" value="#00000000" /> 
    <param name="minRuntimeVersion" value="4.0.41019.0" />
    <param name="autoUpgrade" value="true" />
    <param name="windowless" value="false" />
</object>

   TreeWalker tw = new TreeWalker(new System.Windows.Automation.PropertyCondition(AutomationElement.NameProperty, "Silverlight Control));
   AutomationElement control = tw.GetFirstChild(ancestor);

UI Spy

Identification
    ClassName: "MicrosoftSilverlight"
    ControlType: "ControlType.Window"
    Culture: "(null)"
    AutomationId: "71857844"
    LocalizedControlType: "window"
    Name: "Silverlight Control"
    ProcessId: "7636 (iexplore)"
    RuntimeId: "42 2163886"
    IsPassword: "False"
    IsControlElement: "True"
    IsContentElement: "True"

РЕДАКТИРОВАТЬ: добавленное изображение, я также понялчто объект находится внутри IFrame. UISpyImage - имя заголовка удалено

1 Ответ

0 голосов
/ 05 августа 2010

Я создал несколько методов расширения, чтобы несколько упростить работу с AutomationElement. Я вставил соответствующие ниже, но вы можете прочитать больше о них здесь .

Я предполагаю, что у вас есть ссылка на корневое окно IE. Если нет, но вы знаете, что это Process Id, вы можете найти его так:

var ieWindow = AutomationElement.RootElement.FindChildByCondition(new PropertyCondition(AutomationElement.ProcessIdProperty, ieProcessId));

Предполагая, что в IE открыт только один фрейм, и один элемент управления Silverlight, вы можете сделать:

var silverlightControl = ieWindow.FindDescendentByClassPath(
                         new[]{
                               "Frame Tab",
                                 "TabWindowClass",
                                   "Shell DocObject View",
                                     "Internet Explorer_Server",
                                       "MicrosoftSilverlight",
                               });

Если у вас есть несколько элементов управления Silverlight, я не знаю, как их отличить с помощью UIAutomation. Я бы попытался удалить запись «MicrosoftSilverlight» из пути к классу выше, чтобы вы получили ссылку на страницу проводника. Тогда используйте

AutomationElement.FindAll(TreeScope.Children, new PropertyCondition(AutomationElement.ClassNameProperty, "MicrosoftSilverlight"))

, чтобы найти все SilverlightControls, затем проверять их, каждый из которых по очереди находит какой-то элемент внутри них, который позволяет вам различать их.

Вот методы расширения:

public static class AutomationExtensions
{
    public static AutomationElement FindDescendentByClassPath(this AutomationElement element, IEnumerable<string> classNames)
    {
        var conditionPath = CreateClassNameConditionPath(classNames);

        return element.FindDescendentByConditionPath(conditionPath);
    }

    public static AutomationElement FindDescendentByConditionPath(this AutomationElement element, IEnumerable<Condition> conditionPath)
    {
        if (!conditionPath.Any())
        {
            return element;
        }

        var result = conditionPath.Aggregate(
            element,
            (parentElement, nextCondition) => parentElement == null
                                                  ? null
                                                  : parentElement.FindChildByCondition(nextCondition));

        return result;
    }

    public static AutomationElement FindChildByCondition(this AutomationElement element, Condition condition)
    {
        var result = element.FindFirst(
            TreeScope.Children,
            condition);

        return result;
    }

    public static IEnumerable<Condition> CreateClassNameConditionPath(IEnumerable<string> classNames)
    {
        return classNames.Select(name => new PropertyCondition(AutomationElement.ClassNameProperty, name, PropertyConditionFlags.IgnoreCase)).ToArray();
    }
}
...