混合应用WebView自动化经验总结

一、概述

EufySecurity App,除了原生App的应用模块外,还有一些Html页面功能模块,主要包括有Explore商城模块、H5提示等,是一款由原生App+WebView组成的混合应用。
下面主要介绍Explore商城模块自动化实现过程遇到的一些经验和坑,如何在原有自动化框架上实现混合应用之间的App Webview自动化。

二、Web元素定位

1、Android

google提供了webview组件的调试工具devtools,通过devtools可以直接在pc端的chrome上直接调试app上的html内容,前提是webview必须打开debug模式。
debug模式可以让App开发在webview的对象实例添加调试模式即可,这里略过。
一切就绪后,PC端USB连接安卓手机,使用谷歌浏览器打开如下页面即可。
chrome://inspect/#devices

2、IOS

1. IOS直接使用Mac Safari浏览器进行调试。

  1. 在手机设置里,找到Safair浏览器,在高级里启用Web检查器;
  2. Mac上Safair浏览器,在偏好设置高级选项底部勾选“在菜单栏中显示开发菜单”;
  3. 手机连接Mac,点击Mac上的Safair浏览器,在开发选项下拉菜单中,找到手机名称对应的html页面即可进入调试器;

2. Google Chrome浏览器调试方法

  1. 使用brew安装 ios-webkit-debug-proxy
brew install ios-webkit-debug-proxy

若上面的命令不有效,尝试下面的命令安装

brew uninstall --force libimobiledevice ios-webkit-debug-proxy
brew install --HEAD libimobiledevice ios-webkit-debug-proxy
  1. 安装成功后,在终端输入下面的命令
ios_webkit_debug_proxy -f chrome-devtools://devtools/bundled/inspector.html

若有问题,报错Could not connect to lockdownd. Exiting.: Permission denied,可输入下面的命令,再次尝试

sudo chmod -R 777 /var/db/lockdown/
  1. 保持终端命令连接状态,在chrome浏览器中打开 localhost:9221,点击真机选项;
  2. 作App跳转到JS页面,下面两种方式均可进入调试器:
    (1)在Mac的chrome中刷新页面,选中要打开的html连接,右键点击“复制链接地址”,新建标签页,在地址栏粘贴地址,按enter键进入;
    (2)直接在谷歌浏览器地址栏中输入chrome://inspect/#devices,点击Target下方的inspect进入;

备注:

(1)手机上也要安装谷歌浏览器,否则终端可能无法连接到真机;
(2)复制JS页面地址时,不要用cmd+c快捷键,要右键单击“复制链接地址”,然后新建标签页,粘贴地址打开;

总结:

两种浏览器相比较,虽然Safair调试器打开方便,但容易卡住,有时无法查看JS的变量值,甚至打断点会闪退,建议使用Google Chrome浏览器调试方法。

三、WebView自动化

1、Appium Webview相关链接

http://appium.io/docs/cn/writing-running-appium/web/hybrid/

2、appium desired_capabilities

Android

'chromeOptions': {
   'androidProcess': 'com.oceanwing.battery.cam',    # 驱动H5自动化, 防止卡住
   'w3c': False
},
'recreateChromeDriverSessions': True,    # 移动至非web程序时,是否杀掉chromeDriver

IOS

'startIWDP': True,    # 使用ios-webkit-debug-proxy
# 'nativeWebTap': True,     # 添加这个webview点击元素会错乱,坑之一
'webkitResponseTimeout': 10000,    # webkit 超时时间设置

3、切换上下文

webview

contexts = self.driver.contexts    # 获取所有context
webview = contexts[-1]    # 一般新webview为list最后一个
self.driver.switch_to.context(webview)    # 切换到webview

NATIVE_APP

self.driver.switch_to.context('NATIVE_APP')    # 一般原生的都为NATIVE_APP

四、坑路

1、IOS获取Contexts存在延时

解决办法:等待获取多几次才会拿到

for i in range(5):
   contexts = self.driver.contexts
   webview = contexts[-1]
   if webview != 'NATIVE_APP':
       self.driver.switch_to.context(webview)
       break
   else:
       time.sleep(2)

2、处于Webview模式下,无法用appium原生方法截图

解决办法:切出Webview再截图

def get_screenshot(self):
   """兼容h5截图"""
   src = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
   path = src.replace("/src", "")
   image_floder = '{}/image'.format(path)
   if not os.path.exists(image_floder):
       os.makedirs(image_floder)
   name = datetime.now().strftime('%m%d%H%M%S')
   path_name = u'{}/{}.png'.format(image_floder, name)
   current_c = self.driver.current_context
   if 'NATIVE_APP' not in current_c:  # 如果不是NATIVE_APP,切换成NATIVE_APP截图, 截完图再还原context
       webview = self.driver.contexts
       lenght = len(webview)
       for i in range(lenght):
           if webview[i] == 'NATIVE_APP':
               self.driver.switch_to.context(webview[i])
       self.driver.get_screenshot_as_file(path_name)
       self.driver.switch_to.context(current_c)
   else:
       self.driver.get_screenshot_as_file(path_name)
   return path_name

3、IOS webview页面部分元素点击无效

网上也有一堆这样问题,逐一尝试任无效
解决办法一:刷新按钮使用NATIVE_APP元素DOM中可以获取到,切回NATIVE_APP点击
解决办法二:使用鼠标方法点击

def click_h5_back(self):
   """H5页面返回按钮点击"""
   try:
       if self.platform == GlobalVar.IOS:
           self.switch_to_native_app()
           self.click_element(LOCATOR.h5_back_btn)
           self.switch_to_webview()
       else:
           self.click_element(LOCATOR.h5_back_btn)
       return True
   except NoSuchElementException:
       return False



def tap_h5(self, locator):
   el = self.get_element(locator)
   tas = TouchActions(self.driver)
   tas.tap(el).perform()

4、webview页面嵌套frame需切换页面进去

解决办法:

self.driver.switch_to.frame(el)  # 切到frame页面
self.click_element(LOCATOR.video_play)
self.driver.switch_to.parent_frame()    # 退出frame页面

5、webview页面无法实现滑动动作

解决办法:切回NATIVE_APP进行滑动操作

self.switch_to_native_app()     # 用原生app才能滑动
self.swipe_by_element('left', 0.8, 0.2, 0.25)
self.switch_to_webview()

6、IOS 刷新按钮值存在3秒,Appium获取元素存在时延,display:false无法点击

解决办法:获取相关元素坐标,推演坐标点击

def drop_page(self):
   """刷新页面"""
   self.switch_to_native_app()
   if self.platform == GlobalVar.IOS:
       scroll_l = self.driver.find_element(By.XPATH, '//XCUIElementTypeOther[@name="Horizontal scroll bar, 1 page"]/preceding-sibling::XCUIElementTypeOther').location
       scroll_h = self.driver.find_element(By.ID, 'Horizontal scroll bar, 1 page').location
       update_x = scroll_l['x']
       update_y = scroll_h['y'] - 15
       self.tap(self.top_x, self.top_y)
       print(update_x, update_y)
       self.tap(update_x, update_y)
   else:
       self.swipe_by_element('down', 0.38, 0.68, 0.5)
   self.switch_to_webview()

原 Google 链接:

https://docs.google.com/document/d/1I4C3a4ao3X9K-7Qzdu6F_fAKc1TwvlrETNRQo9rGNvw/view

posted @ 2022-05-09 15:39  MC-Blog  阅读(360)  评论(0编辑  收藏  举报