#android #xpath #appium #children
#Android #xpath #appium #дочерние элементы
Вопрос:
По какой-то причине я не могу получить все прямые дочерние элементы элемента на Android. По-видимому, XPath некорректно работает при поиске подэлементов в элементе или область XPath некорректно реализована в Appium.
parentElement.findElements(By.xpath(...))
Что я пробовал:
*
./*
.//*
.//child::*
./child::*
//*
//child::*
Мои результаты либо равны нулю, все узлы (даже за пределами родительского элемента), либо все дочерние элементы.
Единственное, что сработало для меня, это:
.//*[@resource-id='RESOURCE-ID-OF-PARENT']/child::*
Но это очень плохое решение, потому что может быть несколько элементов с одинаковым идентификатором ресурсов (К вашему сведению, я кодирую оболочку на основе Appium)
Я попытался найти все ответы здесь, но не смог найти ни одного рабочего решения.
Приветствуется любая помощь, спасибо.
Комментарии:
1. Может быть полезна некоторая дополнительная информация. Можете ли вы описать, какие типы дочерних элементов вы ищете? Недоступны ли дочерние элементы иным образом? Я понимаю, что вы, возможно, не сможете поделиться многим, но скриншот дерева иерархии экрана uiautomator может помочь, особенно если вы можете выделить свои «родительские» и потенциальные дочерние элементы, а в идеале свойства родительского и хотя бы одного дочернего элементов.
2. Конечно. Например, я хочу получить все элементы представления recycler. Ну, я не говорю о каком-либо конкретном дереве иерархии. Я хочу создать класс-оболочку, который позволяет мне находить ВСЕ (независимо от того, какого типа) дочерние элементы данного объекта Appium Element (класс WebElement и его подклассы).
Ответ №1:
Это как сказал Йори Хендриккс. Реальный узел и его дерево скрываются под поддельным узлом.
Просто попробуйте напечатать всех потомков вашего элемента; вы увидите всех потомков (очевидно), а также одного, который имеет тот же идентификатор, что и ваш элемент.
Его метод опробован, и он работает; для меня /*/*
тоже работает.
Ответ №2:
Я нашел какой-то обходной путь:
1) Напишите функцию, которая сравнивает два элемента. Поскольку предоставленный метод equals не работает для собственных элементов (Android, iOS), должна быть написана собственная реализация. Я сравниваю наиболее релевантные атрибуты, такие как класс, идентификатор ресурса и описание содержимого, а также размер, местоположение и границы. Это должно сработать в 99% случаев, если только не присутствуют два одинаковых перекрывающихся элемента.
2) Запросите xpath родительского элемента ( findElementsByXpath
) с наиболее точными атрибутами — именем тега, классом, идентификатором ресурса и описанием содержимого. В большинстве случаев будет только один элемент, но если их больше, просмотрите список и используйте сравнение на основе функции равенства.
3) Отметьте индексы элементов в списке и всякий раз, когда будет найдено совпадение, запустите другой запрос в этом формате:
(//tagName[@class=... and @resource-id= ...etc...])[index]/child::*
Помните, что индексация в Xpath начинается с 1. Список результатов — это фактические дочерние элементы родительского элемента.
Обходной путь не самый быстрый, но все же лучше, чем ничего.
Ответ №3:
Это чисто экспериментально, но, похоже, обработка xpath в Appium на самом деле начинается не с выбранного узла в качестве корневого (как можно было бы ожидать), а с поддельного узла, который содержит только этот текущий узел в качестве дочернего (а затем его дерево под ним)
Я попробовал следующее: .//*/child::*
и это, похоже, сработало для меня.