原生定位
https://blog.csdn.net/weixin_43665351/article/details/113524637?spm=1001.2014.3001.5501
H5页面(webdriver)
简介:H5页面这种其实就是和PC上的方式一样,只是这里的浏览器放在了手机上,其他的运行逻辑、定位方式和PC上完全一直。
环境准备
手机端
被测浏览器:(不可以是第三方浏览器)“safari” for IOS 和 “Chrome”,“Chromium”,or “Browser” for Android.
PC端
安装Chrome浏览器(或者chromium),并且能登录https://www.google.com
下载对应手机浏览器对应的driver版本
国内镜像地址:https://npm.taobao/mirrors/chromedriver
安装:
npm install appium-chromedriver --chromedriver_cdnurl = http://npm.taobao.org/mirrors/chromedriver
appium github:https://github.com/appium/appium/blob/master/docs/en/writing-running-appium/web/chromedriver.md
下载时注意对应版本:
1、获取对应手机浏览器的版本
adb shell pm list package 获取所有包的包名
adb shell pm list package | grep browser 使用管道符直接获取对应浏览器的包名
2、adb shell pm dump com.android.browser | grep version 获取对应手机浏览器的版本
adb shell pm dump com.android.chrome | grep version 获取手机chrome的版本
XXXXXXXXXdeMacBook-Air:~ XXXXXXXXX$ adb shell pm list package | grep browser
package:com.android.browser
XXXXXXXXXdeMacBook-Air:~ XXXXXXXXX$ adb shell pm dump com.android.browser | grep version
versionCode=23 targetSdk=23
versionName=6.0.1
安装:
npm install appium --chromedriver_version="2.16"
或者
CHROMEDRIVER_VERSION=LATEST npm install appium
客户端代码:
desirecapability
“browser” = “Browser” 或者 “browser” = “Chrome” (与appPackage和appActivity添加一个即可,不要共存)
“chromedriverExecutable” = “指定driver地址”
测试脚本运行是否正常
from asyncio import sleep
from appium import webdriver
import pytest
class Test_Android():
def setup(self):
self.desire_cap= {
"platformName":"android",
"deviceName":"emulator-5554",
"browserName":"Browser",
"platformVersion":"6.0",
"noReset":True,
"chromedriverExecutable": "/Applications/chromedriver"
}
self.driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub',self.desire_cap)
self.driver.implicitly_wait(10)
def teardown(self):
self.driver.quit()
def test_1_baidu(self):
self.driver.get("http://m.baidu.com")
sleep(5)
if __name__ == '__main__':
pytest.main()
系统默认的chromedriver位置:/Applications/Appium 2.app/Contents/Resources/app/node_modules/appium/node_modules/appium-chromedriver/chromedriver/mac/
也是可以指定对应chromedriver的路径:“chromedriverExecutable” = “指定driver地址”
定位H5页面
前提:所有环境都准备好之后,启动appium、模拟器
第一步:打开chrome浏览器,地址栏输入:chrome://inspect
第二步:点击 inspect (这里要可以访问:https://www.google.com),就会出现以下的界面,我们就可以定位PC一样的方式定位
混合应用定位
识别混合应用:
1、加载页面的时候,会出现加载条
2、嵌套在原生页面中的标签为<android.webkit.WebView>
3、当无网络时,页面加载出现失败(原生的应用的页面会有缓存,不会出现明显的错误页面)
4、看顶部是否有有关闭按钮(微信小程序就是代表)
5、往下拉当前页面的时候,是否有网页提供网址
WebView简介
WebView:android系统提供能显示网页的系统控件(特殊的view)。在Android 4.4以前使用的是WebKit内核,以后Goole采用了chromium作为系统WebView底层支持,API没变,支持HTML5,CSS3,JavaScript。
当一个应用中出现多个浏览器版本时,我要使用多个driver时,可以使用Mapping.json文件
self.desire_cap= {
"platformName":"android",
"deviceName":"emulator-5554",
"browserName":"Browser",
"platformVersion": "6.0",
"noReset": True,
# "chromedriverExecutable": "/Applications/chromedriver"
"chromedriverExecutableDir": "/Applications/chromedriver/all",
"chromedriverChromeMappingFile": "Mapping文件地址"
}
Mapping.json
{
"2.42":"63.0.3239",
"2.41":"62.0.3202"
}
注意:
设备:
android模拟器6.0默认支持webview操作,(mumu不可以,genimotion和SDK自带的emulator可以)
其他模拟器和物理机需要打开app内开关(webview调试开关)
webview开关:
1、文档:https://developers.google.com/web/tools/chrome-devtools/remote-debugging/webviews?hl=zh-cn
2、Android6.0不打开也能查看页面结构 通过appium catlog获取对应的webview地址,然后直接访问定位
3、要启用WebView调试,请在WebView类上调用静态方法 setWenContentsDebuggingEnabled
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT){
WebView. setWenContentsDebuggingEnabled(true);
}
此设置适用于应用的所有WebView
PC:浏览器定位元素
chrome浏览器-Chrome 62才可以更好的看见webview的内部,其他版本都有BUG。
也换成chromium浏览器也可以避免很多坑,展示效果和速度比chrome要快
代码:
有的设置可以直接使用find_element_by_accessibility_id(),不同的设备渲染的页面不同,兼容性不适合
switch_to.context()
switch_to,window()
**重点:**原生应用中嵌套webView,当原生应用到webView页面时,要进行切换switch_to.context(self.driver.switch_to.contexts[-1])。(操作类似windows中的句柄切换)。当切换到webView中时,也有可能会遇到句柄切换的时候,由于手机页面看不到新开的窗口,容易忽略,导致找不到对应的元素。这个时候可以通过浏览器打开的chrome.inspect页面中,查看是否有新的webView生产来判断。
总结:
原生的应用:可以通过对应的定位工具(Appium desktop等)使用原生的定位方式进行定位
wenView页面(H5页面):我们要使用手机端的浏览器与PC端的浏览器关联起来(chrome://inspect/)进入到inspect中进行定位,这时的到位原则和web中的定位方式一致。
混合应用:使用原生的应用方式和H5页面方式,只要在原生应用和webView页面中注意切换既可。要进行切换switch_to.context(self.driver.switch_to.contexts[-1])