Как конфигурация закодированного пользовательского интерфейса всегда работает с родительскими/дочерними объектами?

В качестве примера я буду использовать очень простой пользовательский интерфейс: окно (которое я назову W) с одной кнопкой (B). В UIMap Coded UI B является дочерним элементом W. то есть в спецификации XML карты B появляется в «потомках» W.

Теперь предположим, что у нас одновременно открыто два экземпляра W. Существует свойство поиска, которое будет отличать W1 от W2 (например, у них другое свойство Name), но нет никакого способа отличить B1 от B2, кроме как по их родительскому элементу W.

Я выполняю тест со следующей процедурой:

  1. Откройте два экземпляра окна, W1 и W2.
  2. Установите свойство Name на W UITestControl UIMap, чтобы оно соответствовало имени W1.
  3. Выполните Mouse.Click() на B UITestControl UIMap.
  4. Установите свойство Name в W UITestControl UIMap, чтобы оно соответствовало имени W2.
  5. Выполните Mouse.Click() на B UITestControl UIMap.

Насколько я понимаю, если ни W, ни B не имеют конфигурации «Поиск всегда», то это приведет к тому, что B1 будет нажат на обоих этапах 3 и 5. Итак, мой вопрос заключается в том, что происходит в следующих сценариях:

  • Для B установлен параметр "Искать всегда", а для W — нет.
  • Для W установлен параметр "Искать всегда", а для B — нет.

person Ben Aaronson    schedule 21.05.2014    source источник


Ответы (1)


Без конфигурации Search Always механизм будет кэшировать элемент пользовательского интерфейса после его обнаружения (под кешем я имею в виду сохранение ссылки на COM-объект MSAA, который он получил из этого элемента). Наличие Always Search, как говорится, всегда будет выполнять поиск элемента, как вы сказали. Также UITestControl.Find() делает то же самое, поэтому вы можете использовать это явно, если не хотите устанавливать конфигурацию Always Search.

Когда вы изменяете свойства поиска элемента управления, механизм будет искать элемент при следующем использовании этого элемента управления (поэтому после изменения свойств поиска элемент управления удалит ссылку на элемент пользовательского интерфейса). Однако, если дочерний элемент (кнопка в вашем случае) уже кэширован, и вы изменили свойства поиска его родителя, вам придется вызвать кнопку «Найти» (или установить «всегда искать»), иначе движок будет использовать кэшированный элемент пользовательского интерфейса.

Если вы хотите использовать несколько UITestControls одного и того же класса, вам следует забыть об UIMap и просто создать несколько экземпляров этого класса, а затем отдельно изменить их свойства поиска. UIMap не отвечает за иерархию элементов, это просто способ доступа к элементам.

Итак, в вашем случае:

var W1 = new MyWindowClass();
var W2 = new MyWindowClass();
W1.SearchProperties.Add( ... );
W2.SearchProperties.Add( ... );

Тогда, если все настроено правильно, W1->B будет кнопкой в ​​окне W1, а W2->B будет кнопкой в ​​окне W2.

Если W не является элементом верхнего уровня, вы можете установить для него родителя из UIMap:

var W1 = new MyWindowClass(UIMap.UITopWindow);

Эти вопросы также могут быть вам полезны:

Взаимодействие с несколькими экземплярами приложения в Закодированный пользовательский интерфейс

Метод SwitchTo для закодированного пользовательского интерфейса

person kida    schedule 22.05.2014
comment
Спасибо за информацию. К сожалению, я вынужден использовать некоторый существующий код, включая UIMaps. Я думаю, что второй абзац вашего ответа касается второго сценария в моем вопросе, ответ заключается в том, что он дважды щелкнет B1. Как насчет первого сценария? Сформулируем тот же вопрос по-другому: если я вызову .Find() для элемента управления, будет ли он также снова находить родителей этого элемента управления, или он просто будет искать родителя во всем, что он кэшировал? - person Ben Aaronson; 28.05.2014
comment
Механизм повторит поиск по всей иерархии дочернего элемента управления. Поэтому измените критерии поиска для родителя, вызовите Find() для дочернего элемента. - person kida; 29.05.2014