Toast

含义

  • 为了给当前视图显示一个浮动的显示块,与dialog不同它永远不会获得焦点
  • 显示时间有限,根据用户设置的显示时间后自动消失
  • 本身是个系统级别的控件,它归属系统settings,当一个app发送消息的时候,不是自己造出来的这个弹框,它是发给系统,由系统统一进行弹框,这类的控件不在app内、需要特殊的控件识别方法

toast定位

  • appium使用uiautomator底层的机制来分析抓取toast,并且把toast放到控件树里面,但本身并不属于控件
  • automationName:uiautomator2 这个是appium本身的设置就自带的,不需要额外添加,默认就是uiautomator2
  • getPageSource是无法找到toast的
  • 必须使用xpath去查找
    • //*[@class=“android.widget.Toast”]
    • //*[contains(@text,“xxxxx”)]

实例:appium自带的app测试toast

  • adb shell dumpsys window | findstr mCurrent 这个命令可以找到当前的activity,不知道Android高版本是不是还ok,由于api demo权限高,可直接跳到这个activity运行,其他app就不ok了
  • driver.page_source可以打印当前的页面,可以找到toast的伪控件
  • 打印toast的text出来
driver.page_source打印出来的东西,包含toast

<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
<hierarchy index="0" class="hierarchy" rotation="3" width="810" height="1440">
<android.widget.FrameLayout index="0" package="io.appium.android.apis" class="android.widget.FrameLayout" text="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focused="false" long-clickable="false" password="false" scrollable="false" selected="false" bounds="[0,0][810,1440]" displayed="true">
<android.view.ViewGroup index="0" package="io.appium.android.apis" class="android.view.ViewGroup" text="" resource-id="android:id/decor_content_parent" checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focused="false" long-clickable="false" password="false" scrollable="false" selected="false" bounds="[0,0][810,1440]" displayed="true">
<android.widget.FrameLayout index="0" package="io.appium.android.apis" class="android.widget.FrameLayout" text="" resource-id="android:id/action_bar_container" checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focused="false" long-clickable="false" password="false" scrollable="false" selected="false" bounds="[0,41][810,136]" displayed="true">
<android.view.ViewGroup index="0" package="io.appium.android.apis" class="android.view.ViewGroup" text="" resource-id="android:id/action_bar" checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focused="false" long-clickable="false" password="false" scrollable="false" selected="false" bounds="[0,41][810,136]" displayed="true">
<android.widget.TextView index="0" package="io.appium.android.apis" class="android.widget.TextView" text="Views/Popup Menu" checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focused="false" long-clickable="false" password="false" scrollable="false" selected="false" bounds="[27,65][324,111]" displayed="true" />
</android.view.ViewGroup>
</android.widget.FrameLayout>
<android.widget.FrameLayout index="1" package="io.appium.android.apis" class="android.widget.FrameLayout" text="" resource-id="android:id/content" checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focused="false" long-clickable="false" password="false" scrollable="false" selected="false" bounds="[0,136][810,1440]" displayed="true">
<android.widget.LinearLayout index="0" package="io.appium.android.apis" class="android.widget.LinearLayout" text="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focused="false" long-clickable="false" password="false" scrollable="false" selected="false" bounds="[0,136][810,1440]" displayed="true">
<android.widget.Button index="0" package="io.appium.android.apis" class="android.widget.Button" text="Make a Popup!" content-desc="Make a Popup!" checkable="false" checked="false" clickable="true" enabled="true" focusable="true" focused="false" long-clickable="false" password="false" scrollable="false" selected="false" bounds="[297,136][513,217]" displayed="true" />
</android.widget.LinearLayout>
</android.widget.FrameLayout>
</android.view.ViewGroup>
</android.widget.FrameLayout> #这里就找到了Tast的控件了
<android.widget.Toast index="1" package="com.android.settings" class="android.widget.Toast" text="Clicked popup menu item Search" checkable="false" checked="false" clickable="false" enabled="false" focusable="false" focused="false" long-clickable="false" password="false" scrollable="false" selected="false" bounds="[0,0][0,0]" displayed="false" />
</hierarchy>

from appium import webdriver
from selenium.webdriver.support import expected_conditions
from selenium.webdriver.support.wait import WebDriverWait
from appium.webdriver.common.mobileby import MobileBy as By class TestFind():
def setup(self):
self.desire_cap= {
"platformName":"android",
"deviceName":"127.0.0.1:7555",
"appPackage":"io.appium.android.apis",
"appActivity":"io.appium.android.apis.view.PopupMenu1",
"noReset":"true",
"unicodeKeyboard":True
}
self.driver=webdriver.Remote("http://127.0.0.1:4723/wd/hub",self.desire_cap)
self.driver.implicitly_wait(5) def test_search(self):
"""
1.打开appium的演示app
2.直接进入到测试toast的界面
3.点击显示toast的按钮,然后通过driver.page_source获取页面
4.找到toast的伪控件
5.打印出toast的值出来
:return:
"""
#点击Make a Popup的控件
self.driver.find_element(By.XPATH,'//*[@text="Make a Popup!"]').click()
#点击search的控件
self.driver.find_element(By.XPATH, '//*[@text="Search"]').click()
#打印整个布局页面的xml出来
print(self.driver.page_source)
#打印出toast的值
print(self.driver.find_element(By.XPATH, '//*[contains(@text,"popup menu")]').text)

对应的python脚本代码

参数化

一些小细节

  • 参数化要解决的是一个用例可以复用的问题,比如一个用例重复使用不同的数据,就可以使用参数化,比如同一个用例,有搜索股价,比较股价,都是同一个方法,只是数据不太一样
  • @pytest.mark.parametrize(‘searchkey,type,price’,[
    (‘alibaba’,‘BABA’,180),
    (‘xiaomi’,‘01810’,10)
  • 用上面的方法去使用参数化
  • def test_search(self,searchkey,type,price) 函数的参数要和参数化的参数的数量一样,字符串也要一样
  • 一个用例,有2组参数化,就会运行两次setup和teardown的方法
  • 使用self.driver.find_element(By.ID,“com.xueqiu.android:id/search_input_text”).send_keys(f"{searchkey}"),使用f"{searchkey}"是一个好东西,可以搭配参数化使用

from appium import webdriver
from appium.webdriver.common.mobileby import MobileBy as By
from selenium.webdriver.support import expected_conditions
from selenium.webdriver.support.wait import WebDriverWait
import pytest class TestFind():
#设置caps的值
def setup(self):
self.desire_cap= {
#默认是Android
"platformName":"android",
#adb devices的sn名称
"deviceName":"127.0.0.1:7555",
#包名
"appPackage":"com.xueqiu.android",
#activity名字
"appActivity":".view.WelcomeActivityAlias",
"noReset":"true",
"unicodeKeyboard":True
}
#运行appium,前提是要打开appium server
self.driver=webdriver.Remote("http://127.0.0.1:4723/wd/hub",self.desire_cap)
self.driver.implicitly_wait(5) #这个加不加都行,因为参数化运行都会有setup的,setup就是启动app的过程了,这个就显得有点多余了
#但好像setup并不会初始化整个app,还会停留在前一个页面上,所以还是加上比较好
def teardown(self):
self.driver.find_element(By.XPATH,'//*[@text="取消"]').click() #这是参数化的函数,第一部分是参数化的名字,得和下面的函数参数一模一样,用字符串包含进去
#列表里面的元祖接受具体的参数化的数据,用逗号隔开,和list一样
@pytest.mark.parametrize('searchkey,type,price',[
('alibaba','BABA',180),
('xiaomi','01810',10)
])
#参数哈的函数的参数要和上面的参数名字保持一致
def test_search(self,searchkey,type,price):
"""
1.打开雪球app
2.点击搜索输入框
3.向搜索输入框输入“阿里巴巴”
4.在搜索的结果里选择阿里巴巴,然后点击
5.获取这只上香港 阿里巴巴的股价,并判断这只股价的价格>200
6.通过参数化的方法,用一个用例判断阿里巴巴和小米的股价
:return:
"""
#显示等待进入主页,等主页的元素都加载好了
WebDriverWait(self.driver, 15).until(expected_conditions.element_to_be_clickable((By.XPATH,'//*[@text="我的"]')))
#点击搜索框
self.driver.find_element(By.ID,"com.xueqiu.android:id/tv_search").click()
#向搜索框输入阿里巴巴,小米等参数化的东西f"{searchkey}"是一个好用的东西
self.driver.find_element(By.ID,"com.xueqiu.android:id/search_input_text").send_keys(f"{searchkey}")
#找到搜索框预览结果的阿里巴巴,并点击
self.driver.find_element(By.XPATH,f"//*[@text='{type}']").click()
#选择HK股价的元素,这里是通过父类的方法去定位的
current_price=self.driver.find_element(By.XPATH,f"//*[@text='{type}']/../../..//*[@resource-id='com.xueqiu.android:id/current_price']")
#提取股价的text属性
current_price=float(current_price.text) #判断股价是否大于200
assert current_price > price

对应代码

获取小程序toast控件的更多相关文章

  1. 微信小程序地图控件篇 ---自定义图标被地图覆盖的问题

    今天在做微信小程序的时候遇到这个这样的问题  需要在地图上加个一个自定义的图标控件 类似这样的 刚开始的时候怎图片一直会被地图组件覆盖  ,要怎么解决这个问题  我去翻了下小程序的文档 有个cover ...

  2. 关于小程序button控件上下边框的显示和隐藏问题

    问题: 小程序的button控件上下有一条淡灰色的边框,在空件上加上了样式 border:(none/0); 都没办法让button上下的的边框隐藏: 代码如下 <button class=&q ...

  3. 基于 mpvue 框架的小程序选择控件,支持单列,多列,联动

    最近在学着写mpvue小程序,在做选择控件时候遇到了点问题,按照微信小程序方法picker,很不方便! 在网上搜到一个很好用的组件下面给大家分享: 组件说明文档链接:https://go.ctolib ...

  4. 微信小程序 Button控件 点击传值给JavaScript

    直接看例子吧: WXML:直接看Button,用“data-”(data-total)传值,后台如何获取,继续看下面JS代码. <view class="infothird" ...

  5. Clean小程序(控件消息)

    一 . 准备工作 创建一个基于对话框的MFC项目 删除对话框上的工具 二 . 实现将seven图片贴到上面,按一下则换一张图片 1.在资源视图中添加位图资源,通过属性修改图片ID 2.将对话框拉长,防 ...

  6. 微信小程序常用控件汇总

    1.图片标签: <image src="/images/aaa.png"></image> 2.文本标签: <text>Hello</te ...

  7. 微信小程序设置控件权重

    项目中最常用的两种布局方式,水平布局和垂直布局,在微信小程序中实现起来也比较简单.       1.横向水平布局:         实现水平布局,需要四个view容器组件,其中一个是父容器.如下: & ...

  8. C++ 一个程序获取另一个程序Edit控件的内容

    //一个程序获取另一个程序Edit控件的内容 //根据指定程序的标题名获取改程序窗口的句柄 HWND hWnd=::FindWindow(NULL,"zhang001"); if( ...

  9. Atitit.获取swing ui 按钮控件的id 与名字 与JPDA 调试体系

    Atitit.获取swing ui 按钮控件的id 与名字 与JPDA 调试体系 1. Swing Inspector是一个Java Swing/AWT用户界面分析和调试工具,功能与firebug类似 ...

  10. 在WPF程序中将控件所呈现的内容保存成图像(转载)

    在WPF程序中将控件所呈现的内容保存成图像 转自:http://www.cnblogs.com/TianFang/archive/2012/10/07/2714140.html 有的时候,我们需要将控 ...

随机推荐

  1. 实践GoF的23种设计模式:命令模式

    摘要:命令模式可将请求转换为一个包含与请求相关的所有信息的对象, 它能将请求参数化.延迟执行.实现 Undo / Redo 操作等. 本文分享自华为云社区<[Go实现]实践GoF的23种设计模式 ...

  2. CVE-2020-13933

    漏洞名称 Apache Shiro 身份验证绕过漏洞复现CVE-2020-13933 利用条件 Apache Shiro < 1.6.0 漏洞原理 Apache Shiro是一个强大且易用的Ja ...

  3. 腾讯出品小程序自动化测试框架【Minium】系列(三)元素定位详解

    写在前面 昨天转发这篇文章时,看到群里有朋友这样说: 这么卷吗?这个框架官方已经不维护了. 姑且不说卷不卷的问题,要是能卷明白,别说还真不错: 不维护又怎样?我想学习,想会,分享给很期待这系列的文章的 ...

  4. 新下载了一个框架,然后npm install时候报错npm ERR! Maximum call stack size exceeded

    今天遇到这个npm ERR! Maximum call stack size exceeded报错 解决方案如下: 1.更新npm版本 //查看版本 npm -v //更新 npm install - ...

  5. yarn使用 以及和npm对比

    yarn是facebook发布的一款取代npm的包管理工具. yarn的特点: 速度超快. Yarn 缓存了每个下载过的包,所以再次使用时无需重复下载. 同时利用并行下载以最大化资源利用率,因此安装速 ...

  6. 同类型芯片资源对比-CH32x芯片快速应用说明

    CH32Fx 系列芯片是基于 Cortex-M3 内核设计的微控制器,所以与大部分 ARM 工具和软件兼容. 此外,其外设和硬件设计兼容市场上一些主流微控制器,并在性能和功能上有所增强, 方便用户快速 ...

  7. 真正“搞”懂HTTPS协议18之TLS特性解析

    上一篇,我们讲了TLS的握手过程,我们参照的版本其实是TLS1.2.这个协议是2008年的老协议了,虽然它的价值不言而喻,但是毕竟年纪大了,不太能跟得上时代了.所以,经历了诸多磨难的TLS1.3在20 ...

  8. 祝 .NET 20周年生日快乐

    活动官网:https://dotnet.microsoft.com/zh-cn/

  9. axios实现跨域的问题 vue实现跨域

    第一次写博客,主要是记录自己的一些新的,不好的地方忘各位多多指点,请不要吐槽: 按踩坑顺序叙述.本人对http了解太少,所以坑踩得较多. 1.开始进行跨域时,知道vue2.0官方推荐axios进行aj ...

  10. Cesium给3dtileset中的每个瓦片添加一个billboard/label(六)

    2023-01-14 改了下思路,直接根据点击的位置转换为世界坐标系再添加label console.log(`鼠标点击位置为:${click.position}`); var cartesian = ...