Как проверить элемент, если есть несколько элементов с одинаковым именем класса и не имеет идентификатора ресурса

#android #selenium #appium #android-uiautomator

#Android #selenium #appium #android-uiautomator

Вопрос:

 <?xml version="1.0" encoding="UTF-8" standalone="true"?>

-<hierarchy rotation="0">


-<node bounds="[0,0][720,1280]" selected="false" password="false" long-clickable="false" scrollable="false" focused="false" focusable="false" enabled="true" clickable="false" checked="false" checkable="false" content-desc="" package="com.talentpace.substk" class="android.widget.FrameLayout" resource-id="" text="" index="0">


-<node bounds="[0,0][720,1280]" selected="false" password="false" long-clickable="false" scrollable="false" focused="false" focusable="false" enabled="true" clickable="false" checked="false" checkable="false" content-desc="" package="com.talentpace.substk" class="android.widget.LinearLayout" resource-id="" text="" index="0">


-<node bounds="[0,42][720,1280]" selected="false" password="false" long-clickable="false" scrollable="false" focused="false" focusable="false" enabled="true" clickable="false" checked="false" checkable="false" content-desc="" package="com.talentpace.substk" class="android.widget.FrameLayout" resource-id="android:id/content" text="" index="0">


-<node bounds="[0,42][720,1280]" selected="false" password="false" long-clickable="false" scrollable="false" focused="false" focusable="false" enabled="true" clickable="false" checked="false" checkable="false" content-desc="" package="com.talentpace.substk" class="android.webkit.WebView" resource-id="" text="" index="0">


-<node bounds="[0,42][720,1280]" selected="false" password="false" long-clickable="false" scrollable="true" focused="true" focusable="true" enabled="true" clickable="false" checked="false" checkable="false" content-desc="" package="com.talentpace.substk" class="android.webkit.WebView" resource-id="" text="Ionic App" index="0">


-<node bounds="[0,42][720,1280]" selected="false" password="false" long-clickable="false" scrollable="false" focused="false" focusable="false" enabled="true" clickable="false" checked="false" checkable="false" content-desc="" package="com.talentpace.substk" class="android.view.View" resource-id="" text="" index="0">


-<node bounds="[0,42][720,1280]" selected="false" password="false" long-clickable="false" scrollable="false" focused="false" focusable="false" enabled="true" clickable="false" checked="false" checkable="false" content-desc="" package="com.talentpace.substk" class="android.view.View" resource-id="" text="" index="0">


-<node bounds="[0,42][720,1280]" selected="false" password="false" long-clickable="false" scrollable="false" focused="false" focusable="false" enabled="true" clickable="false" checked="false" checkable="false" content-desc="" package="com.talentpace.substk" class="android.view.View" resource-id="" text="" index="0">


-<node bounds="[0,42][720,1280]" selected="false" password="false" long-clickable="false" scrollable="false" focused="false" focusable="false" enabled="true" clickable="false" checked="false" checkable="false" content-desc="" package="com.talentpace.substk" class="android.view.View" resource-id="" text="" index="0">


-<node bounds="[0,42][720,1280]" selected="false" password="false" long-clickable="false" scrollable="false" focused="false" focusable="false" enabled="true" clickable="false" checked="false" checkable="false" content-desc="" package="com.talentpace.substk" class="android.view.View" resource-id="" text="" index="0">


-<node bounds="[0,42][720,1280]" selected="false" password="false" long-clickable="false" scrollable="false" focused="false" focusable="false" enabled="true" clickable="false" checked="false" checkable="false" content-desc="" package="com.talentpace.substk" class="android.view.View" resource-id="" text="" index="0">

<node bounds="[0,42][720,1280]" selected="false" password="false" long-clickable="false" scrollable="false" focused="false" focusable="false" enabled="true" clickable="false" checked="false" checkable="false" content-desc="" package="com.talentpace.substk" class="android.view.View" resource-id="" text="" index="0"/>


-<node bounds="[0,42][720,1280]" selected="false" password="false" long-clickable="false" scrollable="false" focused="false" focusable="false" enabled="true" clickable="false" checked="false" checkable="false" content-desc="" package="com.talentpace.substk" class="android.view.View" resource-id="" text="" index="1">


-<node bounds="[0,42][720,1280]" selected="false" password="false" long-clickable="false" scrollable="false" focused="false" focusable="false" enabled="true" clickable="false" checked="false" checkable="false" content-desc="" package="com.talentpace.substk" class="android.view.View" resource-id="" text="" index="0">


-<node bounds="[0,42][720,80]" selected="false" password="false" long-clickable="false" scrollable="false" focused="false" focusable="false" enabled="true" clickable="false" checked="false" checkable="false" content-desc="" package="com.talentpace.substk" class="android.view.View" resource-id="" text="" index="0">

<node bounds="[631,42][720,80]" selected="false" password="false" long-clickable="false" scrollable="false" focused="false" focusable="true" enabled="true" clickable="true" checked="false" checkable="false" content-desc="" package="com.talentpace.substk" class="android.widget.Button" resource-id="" text="V 3.5" index="0"/>

</node>

<node bounds="[190,105][530,229]" selected="false" password="false" long-clickable="false" scrollable="false" focused="false" focusable="false" enabled="true" clickable="false" checked="false" checkable="false" content-desc="" package="com.talentpace.substk" class="android.widget.Image" resource-id="" text="Himalaya Image" index="1"/>

<node bounds="[288,262][432,369]" selected="false" password="false" long-clickable="false" scrollable="false" focused="false" focusable="false" enabled="true" clickable="false" checked="false" checkable="false" content-desc="" package="com.talentpace.substk" class="android.widget.Image" resource-id="" text="Leap Image" index="2"/>


-<node bounds="[35,483][687,628]" selected="false" password="false" long-clickable="false" scrollable="false" focused="false" focusable="false" enabled="true" clickable="false" checked="false" checkable="false" content-desc="" package="com.talentpace.substk" class="android.view.View" resource-id="" text="" index="3">


-<node bounds="[131,483][589,565]" selected="false" password="false" long-clickable="false" scrollable="false" focused="false" focusable="false" enabled="true" clickable="false" checked="false" checkable="false" content-desc="" package="com.talentpace.substk" class="android.view.View" resource-id="" text="" index="0">


-<node bounds="[131,483][589,565]" selected="false" password="false" long-clickable="false" scrollable="false" focused="false" focusable="false" enabled="true" clickable="false" checked="false" checkable="false" content-desc="" package="com.talentpace.substk" class="android.view.View" resource-id="" text="" index="0">


-<node bounds="[131,483][589,563]" selected="false" password="false" long-clickable="false" scrollable="false" focused="false" focusable="false" enabled="true" clickable="false" checked="false" checkable="false" content-desc="" package="com.talentpace.substk" class="android.view.View" resource-id="" text="" index="0">


-<node bounds="[131,483][589,563]" selected="false" password="false" long-clickable="false" scrollable="false" focused="false" focusable="false" enabled="true" clickable="false" checked="false" checkable="false" content-desc="" package="com.talentpace.substk" class="android.view.View" resource-id="" text="" index="0">

<node bounds="[145,504][575,539]" selected="false" password="false" long-clickable="false" scrollable="false" focused="false" focusable="true" enabled="true" clickable="true" checked="false" checkable="false" content-desc="" package="com.talentpace.substk" class="android.widget.EditText" resource-id="" text="" index="0" NAF="true"/>

<node bounds="[131,483][589,565]" selected="false" password="false" long-clickable="false" scrollable="false" focused="false" focusable="false" enabled="true" clickable="true" checked="false" checkable="false" content-desc="" package="com.talentpace.substk" class="android.view.View" resource-id="" text="" index="1" NAF="true"/>

</node>

</node>

</node>

</node>


-<node bounds="[35,596][687,628]" selected="false" password="false" long-clickable="false" scrollable="false" focused="false" focusable="false" enabled="true" clickable="false" checked="false" checkable="false" content-desc="" package="com.talentpace.substk" class="android.view.View" resource-id="" text="" index="1">

<node bounds="[224,602][390,628]" selected="false" password="false" long-clickable="false" scrollable="false" focused="false" focusable="false" enabled="true" clickable="true" checked="false" checkable="false" content-desc="" package="com.talentpace.substk" class="android.view.View" resource-id="" text="Register" index="0"/>

<node bounds="[388,596][397,628]" selected="false" password="false" long-clickable="false" scrollable="false" focused="false" focusable="false" enabled="true" clickable="false" checked="false" checkable="false" content-desc="" package="com.talentpace.substk" class="android.view.View" resource-id="" text=" " index="1"/>

<node bounds="[393,602][497,628]" selected="false" password="false" long-clickable="false" scrollable="false" focused="false" focusable="false" enabled="true" clickable="true" checked="false" checkable="false" content-desc="" package="com.talentpace.substk" class="android.view.View" resource-id="" text="Forgot PIN" index="2"/>

</node>

</node>

<node bounds="[101,745][619,1106]" selected="false" password="false" long-clickable="false" scrollable="false" focused="false" focusable="false" enabled="true" clickable="false" checked="false" checkable="false" content-desc="" package="com.talentpace.substk" class="android.widget.Image" resource-id="" text="Lead 2020" index="4"/>

</node>

</node>

</node>

</node>

</node>

</node>

<node bounds="[0,42][720,45]" selected="false" password="false" long-clickable="false" scrollable="false" focused="false" focusable="false" enabled="true" clickable="false" checked="false" checkable="false" content-desc="" package="com.talentpace.substk" class="android.view.View" resource-id="" text="" index="1"/>

</node>

</node>

</node>

</node>

</node>

</node>

<node bounds="[0,0][720,42]" selected="false" password="false" long-clickable="false" scrollable="false" focused="false" focusable="false" enabled="true" clickable="false" checked="false" checkable="false" content-desc="" package="com.talentpace.substk" class="android.view.View" resource-id="android:id/statusBarBackground" text="" index="1"/>

</node>

</hierarchy>  

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

  1. класс android.view.view содержит несколько элементов, идентификатор ресурса и текст равны нулю.
  2. Только 1 элемент с классом android.widget.EditText. Но это также не работает.

Прикрепил дерево, для которого я пытаюсь написать код

UIAutomatorTree — Пользовательское автоматическое дерево

Ниже приведен xpath, который я пробовал

driver.findElementByXPath(«//android.widget.FrameLayout//android.view.View[@index=’3′]//android.widget.Редактировать текст»)

Комментарии:

1. XPath запрашивает XML-скрипты. Чтобы получить лучшую помощь, я бы посоветовал вам также опубликовать исходный код страницы xml. Вы можете сделать это, вызвав driver.PageSource . Смотрите этот ресурс.

2. Прилагается. Для этого мне нужно нажать на элемент класса android.widget. EditText

3. В идеале вам действительно следует попытаться получить некоторые уникальные идентификаторы ресурсов для ваших элементов. Это сделает ситуацию менее сложной. Конечно, для этого вам понадобится доступ к исходному коду.

Ответ №1:

Это не отвечает на вопрос, но может помочь, если у вас есть доступ к исходному коду. Метод setContentDescription помогает справиться с такими проблемами, он должен быть определен в XML, что помогает не только с доступностью, но и во время любого тестирования пользовательского интерфейса. Даже если у вас есть идентификатор / текст, может возникнуть ситуация, когда несколько представлений имеют одинаковый текст и / или идентификаторы

В вашем случае разделение элементов в XPath должно выполняться с помощью одной косой черты «/» Вот пример

 driver.findElement(By.xpath("//android.widget.FrameLayout[1]/android.view.View[3]/android.widget.EditText[0]"));
  

Ответ №2:

В вашем выражении XPath вы пытаетесь получить все <android.widget.FrameLayout[1]> элементы. Глядя на ваш xml, единственные элементы, которые есть в вашем документе, — это один <hierarchy> и несколько <node> элементов. Вот почему вы не получаете никаких результатов.

Предполагая, что вы кодируете на C #, попробуйте что-то вроде этого:

 driver.findElementByXPath(@"//node[@class = ""android.widget.EditText""]));
  
  • С помощью @ вы указываете компилятору использовать строковые литералы, поэтому вы не
    нужно экранировать символы.
  • //node возвращает все <node> элементы в текущем XML-документе.
  • [@class = ""android.widget.EditText""] сообщает вашему выражению XPath, что вам нужны элементы с атрибутом класса со значением, равным «android.widget.Редактировать текст».
  • Двойные кавычки необходимы, чтобы Visual Studio распознала «android.widget.EditText» в виде строкового значения.

Обратите внимание, что использование // — не очень эффективный способ запроса xml. Всегда старайтесь избегать этого и сузить свое выражение XPath. Хороший список примеров XPath шпаргалка от Microsoft здесь. Это должно помочь вам достичь этого.

Комментарии:

1. Спасибо за ответ. Я не кодирую C #. Будут ли регулярные выражения работать в Java-кодировании.

2. Я не настолько знаком с Java, но синтаксис выражения XPath должен быть примерно таким же, да. Поиск того, как экранировать символы в Java, должен привести вас туда, куда вы хотите.

3. Пробовал использовать //node[@class=’android.widget. EditText’] но это не работает. 🙁

4. Попробуйте //node[@class='android.widget.EditText'] в онлайн-тестере XPath , он работает, это правильное выражение XPath. Просто вставьте туда свой XML (убедитесь, что он правильно отформатирован). Я могу придумать 2 возможные проблемы. Ваш синтаксис, специфичный для Java, неверен, или XML, к которому вы применяете выражение, не содержит этого элемента. Попробуйте проверить источник страницы в коде, прежде чем применять выражение XPath.

5. онлайн-тестер XPath дал мне правильный ответ, который я ожидал. Но он все еще не находит элемент в пользовательском интерфейсе. Код зависает, и мне нужно вручную завершить код, не находя элемент каждый раз.