К примеру, имею такой локатор XPath, как его переделать в UIAutomation локатор?
//UIAApplication[1]/UIAWindow[4]/UIAAlert[1]/UIAScrollView[1]/UIAStaticText[2]
Может быть это автоматизировано где-то?
К сожалению, пока не существует инструмента, который сделает это за Вас
Вот ссылка на самый расширенный мануал по IosUIAutomation, который имеется в сети.
В Вашем случае это будет что-то типа:
.alerts()[0].scrollViews()[0].staticTexts()[1]
Также нужно сказать, что Ваш xpath - не особо хорош. Вы должны цепляться к каким-нибудь атрибутам элемента, а не сугубо к порядковым номерам. То же самое, и с IosUIAutomation. Тут вся суть в предикатах, которые применяются к атрибутам элемента.
Например:
.staticTexts().firstWithPredicate("name MATCHES 'YOU HAVE \d+ SKIPS LEFT'")
Если верить инструменту Automation на Mac OS, то он выглядит так:
.alert().scrollViews()[0].staticTexts()[1]
но ни так, ни так appium в тесте найти его не может.
А за предикаты спасибо, буду использовать.
Возможно. Попробуйте вообще без алертов, начиная со скролл вью.
.scrollViews()[0].staticTexts()[1]
Вы Аппиум-инспектором пользуетесь?
Аналогично не подошел.
Для поиска локаторов, да. Им и нашел xpath-локатор. В UIAuto-локаторы перевожу сам, проверяю в Instruments-Automation. Читал, что xpath-локаторы тормозят тесты.
Для запуска тестов использую Appium GUI.
В инспекторе тоже можно проверять локаторы IOSUIAutmation.
А можно посмотреть на разметку в XML (Copy XML)?
http://screencast.com/t/U8MXhrVh
Я не очень ему доверяю, половину реальных элементов не видит, если вводить корректный локатор ios UIAuto
Вы уверены, что даете ему правильный локатор?
Что у вас в других window элементах? Есть подозрение, что window с alert-ом - не основное, а Аппиум ищет только в основном окне приложения.
Если бы не русские символы в атрибуте name, я бы посоветовал найти по accesabilityId или name - “Email не найден”.
Попробуйте также такой локатор:
.elements().firstWithName("Authorization error").scrollViews()[0].staticTexts().firstWithPredicate("name BEGINSWITH "Email")
ага
По мимо аллерта еще окно авторизации и главный widow со всем функционалом.
Но по xpath-локатору же правильный элемент находится. Или Вы говорите про Appium Inspector?
так же не прошел.
Не подскажите, где можно найти такой локатор?
И еще, очень интересует вопрос, по каким локатором стоит искать элементы (для максимальной удобности и скорости тестов)? И правильно ли, допустим, искать все элементы только по ios uiautomation локаторам? У меня в наличии такие элементы как name, ios uiautomation и xpath.
accesabilityId - это и есть name для iOS.
В вашем случае:
WebElement element = driver.findElement(MobileBy.AccessibilityId("Email не найден"));
Но я не уверен, что Аппиум правильно отработает с кириллицей.
Аппиумовские локаторы немного отличаются от тех, что используются в IOS UIAutomation инструменте. В них, например, не применяются frontMostApp() и mainWindow(), а поиск начинается именно с главного окна. Я думаю, что проблема именно в этом.
По скорости работы локаторы можно упорядочить так:
id, name, AccessibilityId, className, IOSUIAutomation(AndroidUIAutomator), xpath
Написать правильный локатор без приложения практически нереально
Проверьте отдельные части локатора в инспекторе и от этого уже отталкивайтесь.
Если находит
.elements().firstWithName("Authorization error")
или
.alerts()
значит алерт доступен и вы можете продолжить искать другие элементы в нем, дописывая локатор. Если нет попробуйте зайти с другой стороны:
.staticTexts().firstWithPredicate("name BEGINSWITH "Email")
Возможно, ваш текст будет сразу найден.
Если ни один из них не подошел, значит iOSUIAutomation неприменим в вашем случае.
какой тогда в нем смысл, если всегда можно использовать атрибут name?
Ведь, как я понял, accesabilityId и не будет без name?
огромное спасибо)
похоже только xpath)
Это необъяснимо, но иногда работает только один из них
Кроме этого, AccessibilityId отлично подходит для мультиплатформенного тестирования - он доступен и для iOS, и для Android (в котором ему соответствует атрибут description). То есть вы можете иметь один локатор для двух платформ, что очень удобно.
В приведенном примере - UIAWindow[4]
Попробуйте: target.frontMostApp().windows()[3].alerts()[0].scrollViews()[0].staticTexts()[1]
так тоже не работает
странно, у меня такой подход работает без проблем, а что Аппиум при этом пишет в логах?
[debug] [UIAuto] Got result from instruments: {“status”:0,“value”:""}
[MJSONWP] Responding to client with driver.click() result: null
[HTTP] <-- POST /wd/hub/session/a08e1d2c-007a-4bc9-a608-7db41a95f50a/element/2/click 200 1312 ms - 76
[HTTP] --> POST /wd/hub/session/a08e1d2c-007a-4bc9-a608-7db41a95f50a/element {“using”:"-ios uiautomation",“value”:“target.frontMostApp().windows()[3].alerts()[0].scrollViews()[0].staticTexts()[1]”}
[MJSONWP] Calling AppiumDriver.findElement() with args: ["-ios uiautomation",“target.frontMostApp().windows()[3].alerts()[0].scrollViews()[0].staticTexts()[1]”,“a08e1d2c-007a-4bc9-a608-7db41a95f50a”]
[debug] [iOS] Executing iOS command ‘findElement’
[debug] [BaseDriver] Waiting up to 12000 ms for condition
[debug] [UIAuto] Sending command to instruments: au.getElementByUIAutomation(‘target.frontMostApp().windows()[3].alerts()[0].scrollViews()[0].staticTexts()[1]’)
[debug] [Instruments] [INST] 2016-05-05 14:34:52 +0000 Debug: evaluation finished
[debug] [Instruments] [INST] 2016-05-05 14:34:52 +0000 Debug: responding with:
[debug] [Instruments] [INST] 2016-05-05 14:34:52 +0000 Debug: Running system command #9: /Applications/Appium.app/Contents/Resources/node/bin/node /Applications/Appium.app/Contents/Resources/node_modules/appium/node_modules/appium-ios-driver/node_modules/appium-uiauto/build/lib/bin/command-proxy-client.js /var/folders/sv/fwvlgylj26z757f6hvjgvj3w0000gn/T/instruments_sock 2,{“status”:0,"v…
[debug] [Instruments] [INST] 2016-05-05 14:34:54 +0000 Debug: Got new command 9 from instruments: au.getElementByUIAutomation(‘target.frontMostApp().windows()[3].alerts()[0].scrollViews()[0].staticTexts()[1]’)
[debug] [Instruments] [INST] 2016-05-05 14:34:54 +0000 Debug: evaluating au.getElementByUIAutomation(‘target.frontMostApp().windows()[3].alerts()[0].scrollViews()[0].staticTexts()[1]’)
[debug] [Instruments] [INST] 2016-05-05 14:34:54 +0000 Debug: byUIAutomation: evaluating code: target.frontMostApp().windows()[3].alerts()[0].scrollViews()[0].staticTexts()[1]
[debug] [UIAuto] Socket data received (195 bytes)
[debug] [UIAuto] Got result from instruments: {“status”:17,“value”:“target.frontMostApp().windows()[3].alerts is not a function. (In ‘target.frontMostApp().windows()[3].alerts()’, ‘target.frontMostApp().windows()[3].alerts’ is undefined)”}
мда… Проблема в .alerts()[0], должно быть просто .alert()
[INST] 2016-05-06 07:16:38 +0000 Error: TypeError: target.frontMostApp().windows()[3].alert is not a function. (In 'target.frontMostApp().windows()[3].alert()', 'target.frontMostApp().windows()[3].alert' is undefined)
как последний вариант можно еще попробовать убрать windows()[3] из пути:
target.frontMostApp().alert().scrollViews()[0].staticTexts()[1]