Есть отличная удаленная работа для php+codeception+jenkins+allure+docker спецов. 100% remote! Присоединиться к проекту

Проблема с нахождением webview в гибридном приложении на Android (логин через Salesforce), с использванием Appium

python
webdriver
appium
Теги: #<Tag:0x00007f7b621f29f0> #<Tag:0x00007f7b621f2888> #<Tag:0x00007f7b621f2720>

(Максим Минаков) #1

Всем доброго времени суток!
В попытке автоматизировать PhoneGap приложение, практически со старта наткнулся на одну очень неприятную штуку - не могу работать с webview этого приложения.
Вся хитрость в том, что логин в приложение осуществляется через webview которое создает Salesforce, а само приложение находится в другом webview, переключиться/достучаться/увидеть которое у меня не выходит.

Внизу приведу пару скриншотов и код, которым пытаюсь это сделать, может, уже на этом этапе будут видны ошибки.

Использую: Python 3.4.3, Appium 1.4.12, эмулированный через Genymotion - Nexus 5 - Android 4.4.4

  • Для начала передаю капабилити, ставлю апп и запускаю его:

class LoginAndroidTests(unittest.TestCase):
def setUp(self):
desired_caps = {}
desired_caps[‘platformName’] = ‘Android’
desired_caps[‘platformVersion’] = ‘4.4.4’
desired_caps[‘deviceName’] = ‘Google Nexus 5 - 4.4.4 - API 19 - 1080x1920’
desired_caps[‘app’] = PATH(’./appname.apk’)
desired_caps[‘appPackage’] = ‘com.xxx.app’
desired_caps[‘appActivity’] = ‘com.xxx.app.activities.appname’
desired_caps[‘appWaitActivity’] = ‘com.salesforce.androidsdk.ui.LoginActivity’
self.driver = webdriver.Remote(‘http://localhost:4723/wd/hub’, desired_caps)

  • Дождавшись - вывожу список активити:

print(driver.contexts)

получаю:

[‘NATIVE_APP’, ‘WEBVIEW_com.xxx.app’]

Все что надо - есть, переключаю сервер на тестовый используя нативный контекст и нативные локаторы, тут все ок, потом - переключаю контекст на webview в которой находится логин форма, заполняю ее:

driver.switch_to.context(‘WEBVIEW_com.xxx.app’)
driver.find_element_by_css_selector(“input#username”).send_keys(“login”)
driver.find_element_by_css_selector(“input#password”).send_keys(“Pass”)
driver.find_element_by_css_selector(“input#Login”).submit()

И подтверждаю логин, адрес другой, но webview, с виду, та же.

А вот теперь самое интересное, после логина (контекст по прежнему - webview) отображается первый экран уже непосредственно самого апликейшена, а с ним появляется и новая webview, ее я прекрасно вижу в инспекторе Chrome (1 на скриншоте), но когда я в коде пытаюсь что-то на ней найти, самый банальный инпут - не выходит. Смотрю в чем дело - возвращаю все HTML-элементы из текущего webview и оказывается, что я “нахожусь” на webview страницы аутентификации (2 на скриншоте).

Подытоживая, вопрос: можно ли как-то вручную менять webview, при том что список контекстов ([‘NATIVE_APP’, ‘WEBVIEW_com.xxx.app’]) всегда остается одним и тем же? Разве Appium, само приложение не должно делать видимое webview активным, чтобы тест мог взаимодействовать с ним?
Про то, что может существовать несколько webview-контекстов читал, но имею только то, что выше привел в списке. Нагуглить схожую проблему не удалось, так что даже не знаю куда копать. Заранее спасибо за любой совет или мнение)
P.S. Код не отформатирован, потому что тег этот глючил, не позволяя создать тему %)


(Ray Romanov) #2

А что показывает UI Automator Viewer на этих страницах?


(Максим Минаков) #3

Как-то вот так:


Одна вебвью


(Ray Romanov) #4

Интересное кино, в нашем приложение тоже используется WebView, но в UI Automator Viewer прекрасно инспектируется его содержимое


(Максим Минаков) #5

Похоже, что ой-ой, и последний скрин я делал в версии аппа с отключенным дебагом webview. Сейчас попробую нормальную версию :grinning:

Да, вот правильный:

И если использовать find_element_by_android_uiautomator - то более-менее можно работать, но во-первых это как-то дико, имея webview клацать его нативными локаторами, а во-вторых - там другие подводные камни вылазят.

Повторяя изначальный вопрос - непосредственно эту страницу я в аппиуме не вижу, ни одного HTML элемента я взять с нее не могу, берется та вторая (как на последнем скрине в первом посте) webview, и только лишь ее элементы и доступны.
Даже если я и продвинусь дальше экрана с этими двумя PIN инпутами - ситуация не меняется


(Ray Romanov) #6

XPath в помощь (благо на ведроиде в отличии от огрызка они быстро работают).
Попробуй переключится в натив (NATIVE_APP), а потом назад в веб (WEBVIEW_1), какое окно схватит?


(Максим Минаков) #7

Попробуй переключится в натив (NATIVE_APP), а потом назад в веб (WEBVIEW_1), какое окно схватит?

Пробовал, но так как (если я правильно понимаю) в списке контекстов всегда одно webview - то такой финт ничего не меняет.

XPath в помощь (благо на ведроиде в отличии от огрызка они быстро работают).

Это значит - работать в нативном контексте, чего хотелось бы избежать из-за удобства CSS селекторов в общем и проблемы с блоком кнопок раздельных в HTML, но “склеенных” в один элемент в нативном контексте, в частности.


(Ray Romanov) #8

т.е. хочешь сказать что когда в UI Automator Viewer грабишь содержимое после авторизации то видишь элементы авторизации?


(Максим Минаков) #9

Ноуп, в UI Automator - все чин-чином - приложение и все что надо, но если переключаюсь на котекст WEBVIEW и стягиваю HTML элементы, какие доступны, то стягивается “неправильная” страница.


(Ray Romanov) #10

Может окно подтверждения нативное


(Максим Минаков) #11

Да нет, все прямолинейно - webview и только.

Я тут что подумал - на третьем скрине оригинального поста у меня ведь одно вебвью, но две табы/страницы/окна в ней. Так может, мне надо пытаться переключиться между вкладками/страницами/окнами стандартными методами?


(Ray Romanov) #12

Тогда если рассуждать, то:

  1. Переключится в натив
  2. Кликнуть по нужной табе
  3. Переключится в вебвъю

Пробуй.


(Максим Минаков) #13

Пробовал, я проходил на один экран “вглубь” этой вебвьюшки в нативном контексте, переключался на вебвью - и ситуация не менялась. Хотя, это было давно, надо будет перепроверить.

У меня еще одна гениальная мысль появилась - все “лишние” вебвьюшки пропадают если в апп залогиниться, выгрузить из памяти, а потом заново открыть. Дурацкий workaround, но мне почему-то кажется довольно жизненным. :grinning:


(Максим Минаков) #14

Так да, о чем это я. Вылючить (то есть выгрузить апп из памяти после успешного логина) и включить (запустить апп, не чистя окружение) - помогло, остается одна webview, с которой уже можно безпроблемно работать.

Это костыль, пускай и довольно правильно были разделены тесты, он не решает вопроса про переключение между разными webview при наличии следующих [‘NATIVE_APP’, ‘WEBVIEW_com.xxx.app’] контекстов. Наверное, аппиум сам бы должен был переключаться, но он не стал.

Так что если кто-то поймет, в чем было дело - был бы очень признателен. Отдельное спасибо RayRom за содействие.


(Константин) #15

А нет у вас возможности проверить на реальном девайсе? И пробовали, хотя бы в эмуляторе, другую версию андроида? (5.0 например)


(Максим Минаков) #16

На реальном пробовал, но бегло - в духе “раз свалилось, ну и черт с ним”. Постараюсь сегодня в рамках эксперимента проверить. Касательно версии, я пользовался только API 19, в GUI, например, более высокую выбрать нельзя. Я себе и решил, что более высокая версия не поддерживается аппиумом, что странно, конечно. Это ведь не так?)


(Константин) #17

Ну скорее всего нельзя выбрать, потому что у вас не скачаны другие API, а если это ограничение на уровне вашего эмулятора, то как бы нафиг оно надо)

Не так. У меня все прекрасно работает через Appium и с API 21


(Максим Минаков) #18

Да, по видимому, просто не скачал. Значит дома обязательно с более новыми попробую, спасибо за наводку :wink:


(Константин) #19

Просто у меня были схожие проблемы (не переключался на WEBVIEW, не находил элементы) именно с андроидом 4.4, но с более ранними версиями appium`а

А еще появилась мысль из серии “гениальных”, попробуйте в вашем WEBVIEW получить список окон

dirver.getWindowHandles();

Но это так, пальцем в небо)


(Максим Минаков) #20

Пробовал, одно значение возвращается.