基于UiAutomator+Chromedriver,native部分则uiautomator,webview部分走chromedrive。二者结合,要求
- android 4.4+
- webview 必须为debug版本
获取webview页面的三种方式:
-
chrome://inspect,需要FQ,真机上打开的app,有网页,然后再网址上输入。如图就有webview。
image.png 使用driver.page_source获取html页面
找开发人员要源文件
-
uc-devtools不需要FQ
https://plus.ucweb.com/download/?spm=ucplus.11213647.0.0.6a0d2604YWBDwi#DevTool
image.png
自己用了模拟器上的浏览器,登陆后,uc-devtools是可以获取到的,也找到了classname为"Android.webkit.WebView"的
image.png
常见问题
contexts只能获取NATIVE_APP,无法获取WEBVIEW
- 使用uiautomator定位元素,显示class值为:android.webkit.WebView,但是driver.contexts只打印出了“NATIVE_APP”。
解决方法
- app打包的时候需要打开webview的debug属性,setWebContentDebuggingEnabled(true),直接开发打开。
-
模拟器的contexts中有webview但有些手机没有,官方答案需要将手机root,再去获取
image.png
上下文切换,原生到webview页面切换
可用的上下文(contexts)
列出所有可用的上下文driver.contexts
driver.window.handles
当前上下文(context):列出当前的上下文(context)
driver.current_context
切换至默认的上下文,原生上下文"NATIVE_APP"
driver.switch_to.context(None)
当前activity:获取当前的Activity,仅支持android
driver.current_activity
当前包名(package),仅支持android
driver.current_package
from appium import webdriver
from appium.webdriver.common.mobileby import MobileBy #appium特有的定位
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time
desired_caps = {}
#平台类型
desired_caps["platformName"] = "Android"
#平台版本号
desired_caps["platfromVersion"] = "5"
#设备名称
desired_caps["deviceName"] = "Android Emulator"
#app包名
desired_caps["appPackage"] = "cn.com.open.mooc"
#app入口acitivity
desired_caps["appActivity"] = "com.imooc.component.imoocmain.splash.MCSplashActivity"
driver = webdriver.Remote("http://127.0.0.1:4723/wd/hub",desired_caps)
loc = 'new UiSelector().text("全程班")'
WebDriverWait(driver,20).until(EC.visibility_of_element_located(MobileBy.ANDROID_UIAUTOMATOR,loc))
driver.find_element_by_android_uiautomator(loc).click()
#等待WebView元素出现
WebDriverWait(driver,20).until(EC.visibility_of_element_located((MobileBy.CLASS_NAME,"Android.webkit.WebView")))
time.sleep(2)
#前提:代码可以识别到webview 需要开启app的webview_debug属性。
#context:原生控件 webview
#1.先列出所有的context
cons = driver.contexts #列表
#2.切换至webview,要确保chromedriver的版本要与webView的版本匹配,也要放置在对应的位置。
driver.switch_to.context(cons[-1])
#3.切换后当前的操作对象,html页面。。uc-devtool工具识别html页面,定位元素
#等待元素可见
WebDriverWait(driver,20).until(EC.visibility_of_element_located((MobileBy.XPATH,'//button[@class="bottom-btn"]')))
driver.find_element_by_xpath('//button[@class="bottom-btn"]').click()
指定chromedriver的路径
from time import sleep
from appium import webdriver
from appium.webdriver.common.mobileby import MobileBy
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from appium.webdriver.common.multi_action import MultiAction
desired_caps = {
"platformName": "Android",
"platformVersion": "7.1.2",
"deviceName": "emulator-5554",
"appPackage": "com.lemon.lemonban",
"appActivity": "com.lemon.lemonban.activity.WelcomeActivity",
"noReset": True,
"noSign": True,
# 切换到webview时,使用指定路径下的chromedriver
"chromedriverExecutable": r'E:\软件目录\chromedrivers\68\chromedriver.exe'
}
# 跟appium之间建立会话
driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', desired_caps)
wait = WebDriverWait(driver,10)
# 柠檬社区元素定位、点击进入柠檬社区
loc = (MobileBy.XPATH, '//*[@text="柠檬社区"]')
wait.until(EC.visibility_of_element_located((loc)))
driver.find_element(*loc).click()
# 进入了混合页面当中。 即有原生控件,又有html
# 需要进入html当中,去操作html的元素。
sleep(2)
# 获取所有的上下文 - 列表
cons = driver.contexts
print("当前上下文:", cons)
# 切换
driver.switch_to.context('WEBVIEW_com.lemon.lemonban')
sleep(2)
# ==================== web自动化操作 ========================
# 获取当前的窗口数
print("当前窗口数:", driver.window_handles)
# 文章链接元素
article_link = (MobileBy.XPATH, '//a[contains(text(),"Web 自动化测试神器之 Headless browser")]')
wait.until(EC.visibility_of_element_located((article_link)))
driver.find_element(*article_link).click()
sleep(4)
# swipe滑屏 - 可以
# 请输入回帖内容
loc = (MobileBy.XPATH, '//li[contains(text(),"请输入回帖内容")]')
wait.until(EC.visibility_of_element_located((loc)))
driver.find_element(*loc).click()