python+Appium自动化:H5元素定位

问题思考

在混合开发的App中,经常会有内嵌的H5页面。那么这些H5页面元素该如何进行定位操作呢?

 

 

 

解决思路

针对这种场景直接使用前面所讲的方法来进行定位是行不通的,因为前面的都是基于Andriod原生控件进行元素定位,而Web网页是单独的B/S架构,两者的运行环境不同因此需要进行上下文(context)切换,然后对H5页面元素进行定位操作。

context

关于应用程序环境的全局信息的接口。 这是一个抽象类,其实现由Android系统提供。 它允许访问特定于应用程序的资源和类,以及对应用程序级操作的调用,如启动活动、广播和接收意图等。

通俗理解

在程序中context我们可以理解为当前对象在程序中所处的一个环境。 比如前面提到的App一个界面是属于Activity类型,也就是Android界面环境,但是当访问内嵌的网页是属于另外一个环境(网页环境),两者处于不同的一个环境。

例子地址:https://drfone.wondershare.com/backup.html

 

 

WebView

WebView是Android系统提供能显示网页的系统控件,它是一个特殊的View,同时它也是一个ViewGroup,可以有很多其他子View。

 NATIVE_APP:这个就是native,也就是原生的

driver.switch_to.context("NATIVE_APP")

WEBVIEW_com.xxxx :这个就是webview

driver.switch_to.context("WEBVIEW_com.xxxx")

H5元素定位环境搭建

1.PC版谷歌浏览器下载,官网地址下载

2.手机版Chrome浏览器  推荐用Google play去下载

3.Chrome driver 下载  需要根据自己电脑上下载的谷歌版本相匹配,ChromeDriver版本与Chrome版本对应表

下载后放置此路径下C:\Users\XXX\AppData\Local\appium-desktop\app-1.5.0\resources\app\node_modules\appium\node_modules\appium-chromedriver\chromedriver\win

 

操作步骤

  1. 手机与电脑连接,开启USB调试模式,通过adb devices可查看到此设备。(设备系统Android 5.0以上)
  2. 电脑端、移动端必须安装chrome浏览器。(尽量保证移动端chrome版本与PC端一致)根据对应的Chrome浏览器版本安装对应的Chrome driver。
  3. App Webview开启debug模式
  4. 在电脑端Chrome浏览器地址栏输入chrome://inspect/#devices,进入调试模式
  5. 执行测试脚本
  6. 打开app对应的h5页面,在 chrome://inspect/#devices 地址中,检查是否显示对应的webview,如没有,则当前未开启调试模式。
  7. 在自动化脚本中,进入到对应的H5页面,打印输出当前context,如果一直显示为Natvie App,则webview未开启。

Webview 调试模式检查与开启

基础检查方式

开启方式:在app中配置如下代码:

(在WebView类中调用静态方法setWebContentsDebuggingEnabled):

if (Build.VERSION.SDK_INT >=Build.VERSION_CODES.KITKAT) {  

 WebView.setWebContentsDebuggingEnabled(true);

注:此步骤,一般需要App开发人员开启。

 

例子:

场景:启动dr.fone app 进入backup H5页面中的输入邮箱并点击提交,然后返回

测试环境

测试设备:逍遥模拟器 Android 5.1 /Chrome 78.0.3904.96

PC系统环境: Win7 64bit /79.0.3945.79(最好跟手机端的版本保持一致吧)

测试app: dr.fone3.2.0.apk

H5页面地址:https://drfone.wondershare.com/backup.html

需求分析

  1. 先进入到H5页面,然后切换到context,再进行相关元素定位操作。
  2. conetext切换:可以通过contexts()方法来获取到页面的所有context,然后切换到H5页面的context
  3. 在H5页面进行元素定位操作

获取方法实践

contexts=driver.contexts

print(contexts) 

#打印结果

 

 具体代码:

# -*- coding: utf-8 -*-#

from appium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.common.exceptions import NoSuchElementException
import time
desired_caps = {
"platformName": "Android",
"platformVersion": "5.1",
"deviceName": "U4KF9HSK99999999",
"appPackage": "com.wondershare.drfone",
"appActivity": "com.wondershare.drfone.ui.activity.WelcomeActivity",
"unicodeKeyboard":True,
"resetKeyboard":True,
"noReset": True,
#"ANDROID_UIAUTOMATOR":"Uiautomator2",
# "chromeOptions": {"androidProcess": "com.wondershare.drfone"}
}
driver = webdriver.Remote("http://localhost:4723/wd/hub",desired_caps)
driver.implicitly_wait(5)

print("click backipbtn")
driver.find_element_by_id("com.wondershare.drfone:id/btnBackup").click()

element= WebDriverWait(driver,30).until(lambda x:x.find_element_by_id("com.wondershare.drfone:id/btnRecoverData"))
print("click nextbtn")
element.click()
try:
time.sleep(2)
driver.find_element_by_class_name("android.webkit.WebView")
except NoSuchElementException:
#防止网络中断,刷新一下
print("no network")
driver.find_element_by_id("com.wondershare.drfone:id/online_error_btn_retry").click()
contexts=driver.contexts
print(contexts)
else:
contexts=driver.contexts
print(contexts)

print("switch to webview")
time.sleep(2)
driver.switch_to.context('WEBVIEW_com.wondershare.drfone')

print("编辑邮箱,提交")
driver.find_element_by_id("email").send_keys("123456@qq.com")
driver.find_element_by_class_name("btn_send").click()

print("switch to native")
driver.switch_to.context(contexts[0])
driver.find_element_by_class_name("android.widget.ImageButton").click()

 

参考转载:https://www.cnblogs.com/xuzhongtao/p/9723210.html

 

 

posted on 2019-12-18 15:34  bug无处不在  阅读(1912)  评论(0编辑  收藏  举报