Bootstrap

Appium(四)

一、app页面元素定位

  1、通过id定位元素: resrouce-id
  2、通过ClassName定位:classname
  3、通过AccessibilityId定位:content-desc
  4、通过AndroidUiAutomator定位
  5、通过xpath定位

  xpath、id、class、accessibility id、android uiautomator



  UI Automator
  UI自动化测试框架,安卓移动端app
  要求:Android 4.3以上
  提供了一系列API:执行UI测试在系统或者第三方app上面
  允许在被测设备上执行操作,比如打开系统设置菜单
  适合编写黑盒自动化测试

  UI Automator框架的主要特点:
  1、元素定位:UI Automator Viewer:扫描、分析待测应用的UI组件的图像工具。
  2、元素操作:Accessing device state:在目标设备和app上的各种操作
  3、元素识别:UI Automator APIs:在多个应用程序中捕获和操作UI组件
  
  使用UIAutomator中的UiSeletor类来处理元素定位
  在python客户端appium库中通过,uiautomator来获取元素的方法为:
  driver.find_elements_by_android_uiautomator()

  该方法的参数为UiSeletor类定位元素的表达式:
  new UiSelector().函数名称("定位表达式")
  实例化一个UiSeltctor对象,然后通过示例调用接口
  示例:
  需要导入包:
  from appium.webdriver.common.appiumby import AppiumBy
  driver.find_element(AppiumBy.ANDROID_UIAUTOMATOR,'new UiSelector().resourceId("com.tencent.mobileqq:id/dialogLeftBtn")')

二、滑动屏幕

滑动接口:
swipe(起始X,起始Y,结束X,结束Y)
结束X-起始X:X轴滑动的距离
结束Y-起始Y:Y轴滑动的距离

手机的屏幕尺寸有很多,如何兼容?
get_window_size()  获取屏幕大小,返回的是一个字典
如:
size=driver.get_window_size()
print(size)
返回的结果为:
{'width': 1080, 'height': 1920}
# 滑屏操作
# get_window_size()  获取屏幕大小,返回的是一个字典
size=driver.get_window_size()
# 向右滑屏
driver.swipe(size["width"]*0.8,size["height"]*0.5,size["width"]*0.2,size["height"]*0.5,100)
sleep(2)
print("滑屏到热点")

三、appium----模拟触屏

TouchAction类(从Appium2.0 TouchAction被弃用)
将一些列的动作放在一个链条中,然后将该链条传递给服务器。服务器接收到该链条后,解析各个动作,逐个执行。
短按(press)
长按(longPress)
点击(tap)
移动到(move_to)  x,y为相对上一个坐标的移动距离
等待(wait)
释放(release)
执行(perform)
取消(cancel)

在这里插入图片描述

from appium.webdriver.common.touch_action import TouchAction
ele=driver.get_element(AppiumBy.ID,"")
# 元素的大小  返回的是一个字典{"width":xxx,"height":xxx}
size=ele.size
# 正方形 所以宽高的步长一样
step=size["width"]/6
# 元素的起始坐标-左上角
ori=ele.location
point1=(ori["x"]+step,ori["y"]+step)
point2=(point1[0]+step*2,point1[1]) # 相对于point1,x轴增加了2*step
point3=(point2[1]+step*2,point2[1]) # 相对于point2,x轴增加了2*step
point4=(point3[1]-step*2,point3[1]+step*2) # 相对于point3,x轴减少了2*step,y轴增加了2*step
point5=(point4[1],point4[1]+step*2) # 相对于point3,x轴不变,y轴增加了2*step

TouchAction(driver).press(x=point1[0],y=point1[1]).wait(200).\
    move_to(x=point2[0],y=point2[1]).wait(200).\
    move_to(x=point3[0],y=point3[1]).wait(200).\
    move_to(x=point4[0],y=point4[1]).wait(200).\
    move_to(x=point5[0],y=point5[1]).wait(200).\
    release().\
    perform()

appium-python-client的版本为4.0.1,这个版本中,好像没有touchaction的包,因此,使用w3c来代替操作
from selenium.webdriver import ActionChains
1、实例化:
从之前的action = TouchAction(driver)改为
action = ActionChains(driver)
2、按压操作
从之前的action.press()改为:
action.w3c_actions.pointer_action.click_and_hold()
3、等待操作
从之前的action.wait()改为:
action.w3c_actions.pointer_action.pause(2)
4、释放操作:
从之前的action.release()改为:
action.w3c_actions.pointer_action.release()
5、执行操作不变,依旧为action.perform()。

四、Toast消息提示框

Toast是一种简易的消息提示框,通常用于向用户显示信息。Toast消息不能被用户点击,并且会根据所设置的显示时间自动消失。
不会获得焦点,无法被点击,并且显示时间有限,一般会在几秒内自动消失。
Toast消息通常用于提示用户某些操作的结果或状态,例如密码输错后的提示。

 要获取Toast信息要满足
Appium对Toast的支持‌:
(1)Appium从1.6.3版本开始支持识别Toast内容,这主要是基于UiAutomator2的。因此,在使用Appium获取Toast消息时,需要在Capability配置中添加参数'automationName': 'UIAutomator2'
(2)UIAutomator2只支持安卓5.0以上的版本

xpath表达式:
xpath="//*[contains(@text,'文本内容')]"
注意:driverWait方法中,请用presence_of_element_located,不要用visibility_of_element_located,对toast的可见处理并不支持,会直接报错命令无法执行

在这里插入图片描述

from appium import webdriver
from appium.webdriver.common.appiumby import AppiumBy
from time import sleep
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
desired_caps={
  "deviceName": "127.0.0.1:5555",
  "platformName": "Android",
  "platformVersion": "7.1.2",
  "appPackage": "com.ss.android.article.news",
  "appActivity": ".activity.MainActivity",
  "automationName":"UiAutomator2"
}
# 连接appium server。前提:appium desktop要启动。有监听窗口
# 将desired_caps发送给appium server。打开app

driver=webdriver.Remote("http://127.0.0.1:4723/wd/hub",desired_caps)
# 运行代码之前:
# 1、appium server启动成功。处于监听状态;
# 2:模拟器/真机必须能够被电脑识别。即adb devices能够识别到要操作的设备。
# 通过resource-id定位
# 等待进入首页,看到推荐
WebDriverWait(driver,20).until(
    EC.visibility_of_element_located((AppiumBy.ACCESSIBILITY_ID,"推荐"))
)
print("可以看到推荐")
# 进行登录操作
driver.find_element(AppiumBy.ANDROID_UIAUTOMATOR,'new UiSelector().text("未登录").resourceId("com.ss.android.article.news:id/ctd")').click()
sleep(0.5)
# 等待登录页面出现
WebDriverWait(driver,20).until(
    EC.visibility_of_element_located((AppiumBy.ID,"com.ss.android.article.news:id/ctb"))
)
driver.find_element(AppiumBy.ID,"com.ss.android.article.news:id/c04").click()
sleep(0.5)
# 找到账号密码登录
WebDriverWait(driver,20).until(
    EC.visibility_of_element_located((AppiumBy.ID,"com.ss.android.article.news:id/ro"))
)
driver.find_element(AppiumBy.ANDROID_UIAUTOMATOR,'new UiSelector().text("密码登录").resourceId("com.ss.android.article.news:id/bhu")').click()
sleep(0.5)
# 进入账号密码登录页面
WebDriverWait(driver,20).until(
    EC.visibility_of_element_located((AppiumBy.ID,"com.ss.android.article.news:id/bhh"))
)
driver.find_element(AppiumBy.ID,"com.ss.android.article.news:id/bhh").send_keys("18435990207")
driver.find_element(AppiumBy.ID,"com.ss.android.article.news:id/bhp").send_keys("123")
driver.find_element(AppiumBy.ID,"com.ss.android.article.news:id/qa").click()
sleep(0.5)
xpath='//*[contains(@text,"访问太")]'
try:
    WebDriverWait(driver,10,0.02).until(
    EC.presence_of_element_located((AppiumBy.XPATH,xpath))
    )
    print(driver.find_element(AppiumBy.XPATH,xpath).text)
except:
    print("没有找到Toast")


运行结果:访问太频繁,请稍后再试

五、混合应用-H5

目前主流用用程序分为三类:Web App(网页应用)、Hybrid App(混合应用)、Native App(原生应用)

怎么样分辨一个app页面究竟是native还是web的?
1、在手机/模拟器中点击手机号的版本号5下,进入开发者选项
2、在开发者选项中勾选上显示布局边界,再返回到App界面
3、如果App是web的界面,那界面不会有布局边界显示,如有则说明是native的界面
或者通过定位工具  点中间没有原生部件的地方,看class值

在这里插入图片描述

基于UIAutomator+Chromedriver
native部分则uiautomator,webview部分走chromedriver,二者结合要求:
android 4.4+
webview必须为debug版本

获取webview页面的三种方式:
1、chrome://inspect,需要翻墙
2、使用driver.page_source获取html页面
3、找开发人员要源文件
4、uc-devtools   不需要翻墙(推荐)

常见问题:
contexts只能获取NATIVE_APP ,无法获取WEBVIEW
使用uiautomatorviewer定位元素,显示class值为:android.webkit.WebView
但是driver.contexts只打印出‘NATIVE_APP’

解决方法:
1、app打包的时候需要开发webview的debug属性setWebContentDebuggingEnableed(true),这个直接让开发加上就好
2、模拟器的有些contexts中有webdriver,但有些手机没有。
官方给出的答案是:需要将手机root,然后再去获取。

开启webview可见:
https://developers.google.com/web/tools/chrome-devtools/remote-debugging/webviews

上下文切换:
可用的上下文(Contexts)
列出所有可用的上下文(contexts)
driver.contexts

driver.window_handles
当前上下文(Context):列出当前的上下文
driver.current_context

切换到默认的上下文(Context)
切换回默认的上下文(Context)。(一般就是原生上下文"NATIVE_APP")
driver.switch_to.context(None)

当前Activity:获取当前的Activity。仅支持Android
driver.current_activity

当前包名(package):获取当前包名(package)。仅支持Android
driver.current_package

在这里插入图片描述
在这里插入图片描述

如果出现这种情况,这好换Appium版本
在这里插入图片描述

关注:https://www.cnblogs.com/yyoba/p/9455519.html

小程序

在这里插入图片描述

;