Toast简介
Android中的Toast是一种简易的消息提示框。 当视图显示给用户,在应用程序中显示为浮动。和Dialog不一样的是,它永远不会获得焦点,无法被点击。
Toast类的思想就是尽可能不引人注意,同时还向用户显示信息,希望他们看到。而且Toast显示的时间有限,一般3秒左右就消失了。因此使用传统的元素定位工具,我们是无法定位到Toast元素的(传说中低调奢华有内涵)。
Appium Toast内容获取
Add ability to verify TOAST messages (these can't be interacted with, only text retrieval allowed)
1.Appium 1.6.3开始支持识别Toast内容,主要是基于UiAutomator2,因此需要在Capablity配置如下参数:
'automationName':'uiautomator2' 或者: desired_caps['automationName']='uiautomator2'
2.安装appium-uiautomator2-driver: 安装命令如下:
cnpm install appium-uiautomator2-driver
安装成功后可以在 C:\Users\Administrator\node_modules看到对应的文件:
[email protected]@appium-uiautomator2-driver [email protected]@appium-uiautomator2-server
代码实现
步骤一:初始化
在capability配置内部增加:desired_caps[‘uiautomationName’]=’ uiautomator2’
步骤二:定位toast元素
(1)定义toast文本内容
(2)定义路径
(3)组合文本内容和路径进行定位:用format()连接路径和文本内容
参考代码
导入模块 11 from appium import webdriver 12 from selenium.common.exceptions import NoSuchElementException 13 from selenium.webdriver.support.ui import WebDriverWait 14 from selenium.webdriver.support import expected_conditions as EC 15 16 desired_caps = {'platformName': 'Android', 17 'platforVersion': '5.1.1', 18 'automationName': 'Uiautomator2', 19 'deviceName': '127.0.0.1:62001', 20 'app': r'C:\Users\DELL\Downloads\kaoyanbang.apk', 21 'appPackage': 'com.tal.kaoyan', 22 'appActivity': 'com.tal.kaoyan.ui.activity.SplashActivity', 23 'noReset': 'True'} 24 25 driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps) 26 driver.implicitly_wait(9) 27 try: 28 driver.find_element_by_id("android:id/button2").click() 29 except NoSuchElementException: 30 print(1) 31 try: 32 driver.find_element_by_id('com.tal.kaoyan:id/tv_skip').click() 33 except NoSuchElementException: 34 print(2) 35 driver.find_element_by_id('com.tal.kaoyan:id/login_email_edittext').clear() 36 driver.find_element_by_id('com.tal.kaoyan:id/login_email_edittext').send_keys('bjhongge') 37 38 driver.find_element_by_id('com.tal.kaoyan:id/login_password_edittext').send_keys('1213213') 39 driver.find_element_by_id('com.tal.kaoyan:id/login_login_btn').click() 40 41 error_message = "用户名或密码错误,你还可以尝试3次" 42 limit_message = "验证失败次数过多,请15分钟后再试" 43 44 message = '//*[@text=\'{}\']'.format(error_message) 45 #message='//*[@text=\'{}\']'.format(limit_message) 46 47 toast_element = WebDriverWait(driver, 15).until(lambda x:x.find_element_by_xpath(message)) 48 print(toast_element.text)
说明:
连接不同的类型的变量或内容format()
显示等待:webdriver(driver,5)
driver是webdriver的驱动程序,5是超时时间,以秒为单位
WebDriverWait()一般由 until()或 until_not()方法配合使用,下面是 until()和 until_not()方法的说明。
until(method, message=’’)
调用该方法提供的驱动程序作为一个参数,直到返回值不为 False。
until_not(method, message=’’)
调用该方法提供的驱动程序作为一个参数,直到返回值为 False。
动态函数:lambda x:x+5
X是函数的参数,冒号后面是函数的返回值
封装toast判断
1.单独写一个函数来封装判断是否存在toast消息,存在返回True,不存在返回False
1 def is_toast_exist(driver,text,timeout=30,poll_frequency=0.5):
2
3 '''is toast exist, return True or False
4
5 :Agrs:
6
7 - driver - 传driver
8
9 - text - 页面上看到的文本内容
10
11 - timeout - 最大超时时间,默认30s
12
13 - poll_frequency - 间隔查询时间,默认0.5s查询一次
14
15 :Usage:
16
17 is_toast_exist(driver, "看到的内容")
18
19 '''
20
21 try:
22
23 toast_loc = ("xpath", ".//*[contains(@text,'%s')]"%text)
24
25 WebDriverWait(driver, timeout, poll_frequency).until(EC.presence_of_element_located(toast_loc))
26 27 return True 28 29 except: 30 31 return False
#
WebDriverWait 方法后面有两种等待方式
until
-
method: 在等待期间,每隔一段时间(__init__中的poll_frequency)调用这个传入的方法,直到返回值不是False
-
message: 如果超时,抛出TimeoutException,将message传入异常
until_not
-
与 until相反,until是当某元素出现或什么条件成立则继续执行,
-
until_not是当某元素消失或什么条件不成立则继续执行,参数也相同,不再赘述。
WebDriverWait(driver, 超时时长, 调用频率, 忽略异常).until(可执行方法, 超时时返回的信息)
这里需要特别注意的是until或until_not中的可执行方法method参数,很多人传入了WebElement对象,如下:
WebDriverWait(driver, 10).until(driver.find_element_by_id('kw')) # 错误
以下两个条件类验证title,验证传入的参数title是否等于或包含于driver.title
title_is
title_contains
以下两个条件验证元素是否出现,传入的参数都是元组类型的locator,如(By.ID, ‘kw’)
顾名思义,一个只要一个符合条件的元素加载出来就通过;另一个必须所有符合条件的元素都加载出来才行
presence_of_element_located
presence_of_all_elements_located
以下三个条件验证元素是否可见,前两个传入参数是元组类型的locator,第三个传入WebElement
第一个和第三个其实质是一样的
visibility_of_element_located
invisibility_of_element_located
visibility_of
以下两个条件判断某段文本是否出现在某元素中,一个判断元素的text,一个判断元素的value
text_to_be_present_in_element
text_to_be_present_in_element_value
以下条件判断frame是否可切入,可传入locator元组或者直接传入定位方式:id、name、index或WebElement
frame_to_be_available_and_switch_to_it
以下条件判断是否有alert出现
alert_is_present
以下条件判断元素是否可点击,传入locator
element_to_be_clickable
以下四个条件判断元素是否被选中,第一个条件传入WebElement对象,第二个传入locator元组
第三个传入WebElement对象以及状态,相等返回True,否则返回False
第四个传入locator以及状态,相等返回True,否则返回False
element_to_be_selected
element_located_to_be_selected
element_selection_state_to_be
element_located_selection_state_to_be
最后一个条件判断一个元素是否仍在DOM中,传入WebElement对象,可以判断页面是否刷新了
staleness_of
确认新窗口打开
new_window_is_opened
上面是所有17个condition,与until、until_not组合能够实现很多判断,如果能自己灵活封装,将会大大提高脚本的稳定性
封装后参考代码
1 # coding=utf-8 2 # 1.先设置编码,utf-8可支持中英文,如上,一般放在第一行 3 4 # 2.注释:包括记录创建时间,创建人,项目名称。 5 ''' 6 Created on 2019-7-31 7 @author: 北京-宏哥 QQ交流群:707699217 8 Project:学习和使用appium自动化测试-toast提示 9 ''' 10 # 3.导入模块 11 from appium import webdriver 12 from selenium.common.exceptions import NoSuchElementException 13 from selenium.webdriver.support.ui import WebDriverWait 14 from selenium.webdriver.support import expected_conditions as EC 15 16 desired_caps = {'platformName': 'Android', 17 'platforVersion': '5.1.1', 18 'automationName': 'Uiautomator2', 19 'deviceName': '127.0.0.1:62001', 20 'app': r'C:\Users\DELL\Downloads\kaoyanbang.apk', 21 'appPackage': 'com.tal.kaoyan', 22 'appActivity': 'com.tal.kaoyan.ui.activity.SplashActivity', 23 'noReset': 'True'} 24 25 def is_toast_exist(driver,text,timeout=30,poll_frequency=0.5): 26 27 '''is toast exist, return True or False 28 29 :Agrs: 30 31 - driver - 传driver 32 33 - text - 页面上看到的文本内容 34 35 - timeout - 最大超时时间,默认30s 36 37 - poll_frequency - 间隔查询时间,默认0.5s查询一次 38 39 :Usage: 40 41 is_toast_exist(driver, "看到的内容") 42 43 ''' 44 45 try: 46 47 toast_loc = ("xpath", ".//*[contains(@text,'%s')]"%text) 48 49 WebDriverWait(driver, timeout, poll_frequency).until(EC.presence_of_element_located(toast_loc)) 50 51 return True 52 53 except: 54 55 return False 56 if __name__ == "__main__": 57 58 driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps) 59 driver.implicitly_wait(9) 60 try: 61 driver.find_element_by_id("android:id/button2").click() 62 except NoSuchElementException: 63 print(1) 64 try: 65 driver.find_element_by_id('com.tal.kaoyan:id/tv_skip').click() 66 except NoSuchElementException: 67 print(2) 68 driver.find_element_by_id('com.tal.kaoyan:id/login_email_edittext').clear() 69 driver.find_element_by_id('com.tal.kaoyan:id/login_email_edittext').send_keys('bjhongge') 70 71 driver.find_element_by_id('com.tal.kaoyan:id/login_password_edittext').send_keys('1213213') 72 driver.find_element_by_id('com.tal.kaoyan:id/login_login_btn').click() 73 74 error_message = "用户名或密码错误,你还可以尝试3次" 75 limit_message = "验证失败次数过多,请15分钟后再试" 76 77 print is_toast_exist(driver, error_message)
原文链接:https://www.cnblogs.com/du-hong/p/11175517.html
https://www.cnblogs.com/fcc-123/p/10942883.html