特殊控件toast识别
特殊控件 Toast
简介
Toast
是一种轻量级的消息提示,常常以小弹框的形式出现,一般出现 1 到 2 秒会自动消失,可以出现在屏幕上中下任意位置。
Toast
具有如下的特点:
- 无法被点击,不同于
Dialog
,永远不会获得焦点。 Toast
显示的时间有限,Toast
会根据用户设置的显示时间后自动消失- 是系统级别的控件,属于系统
settings
Toast 的思想:尽可能不引人注意,同时还向用户显示信息,希望用户看到。
如下图,就是一种 Toast 消息框类型:
Toast 定位
Appium
在抓取 Toast
时,使用的是 uiautomator
底层,然后将 Toast
元素放入控件树中。需要注意的是,Toast
本身并不属于常规的用户界面控件,而是一种短暂的消息提示,在这个过程中,Appium
使用的是 uiautomator2
。
Toast
出现的时间一般比较短,可以通过等待或者打印页面元素的方式判断是否存在,并且通过 Xapth
或者 class name
(在Android
里 class name
相当于 组件的路径名称:android.widget.Toast
) 的定位方式找到 Toast
元素。在页面结构中,Toast
元素大致如下所示:
<!-- 在这里可以看到Toast消息提示框的
class是android.widget.Toast,
且一个页面一般只有一个 -->
<android.widget.Toast
index="1"
package="com.android.settings"
class="android.widget.Toast"
text="Clicked popup menu item Search"
displayed="true"
/>
示例
- 使用
appium
官方Demo apk: API DEMO
进行练习,apk 网盘地址。 - 进入试验
toast
页面:view-> make a popup
- 配置
driver
的初始化和关闭driver
的步骤。
Python 示例:
class TestToast:
def setup_class(self):
caps = {
'platformName': 'android',
'appium:appPackage': 'io.appium.android.apis',
'appium:appActivity': 'io.appium.android.apis.view.PopupMenu1',
"appium:noReset": True,
"appium:shouldTerminateApp": True
}
self.driver = webdriver.Remote(
"http://127.0.0.1:4723",
options=UiAutomator2Options().load_capabilities(caps)
)
self.driver.implicitly_wait(15)
def teardown_class(self):
self.driver.quit()
Java 示例:
class TestToast {
public static AndroidDriver driver;
@BeforeAll
public static void setUp() throws MalformedURLException {
// 初始化capability
DesiredCapabilities caps = new DesiredCapabilities();
// 设置 app 安装的平台(Android、iOS)
caps.setCapability(MobileCapabilityType.PLATFORM_NAME, "Android");
// 设置 app 的包名
caps.setCapability("appPackage", "io.appium.android.apis");
// 设置 app 的启动页
caps.setCapability("appActivity", "io.appium.android.apis.view.PopupMenu1");
// 设置 app 不清空缓存
caps.setCapability("appium:noReset", true);
// 设置 app 不重启
caps.setCapability("appium:shouldTerminateApp", true);
URL remoteUrl = new URL("http://127.0.0.1:4723");
driver = new AndroidDriver(remoteUrl, caps);
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(15));
}
@AfterAll
public static void tearDown() {
if (driver != null) {
driver.quit();
}
}
}
- 定位 toast 消息提示框
Python 示例:
class TestToast:
def test_get_toast(self):
# 定位到 Make a Popup! 按钮并点击
self.driver.find_element(
AppiumBy.ACCESSIBILITY_ID,
"Make a Popup!"
).click()
# 消息框类型选择search
self.driver.find_element(
AppiumBy.XPATH,
"//*[@text='Search']"
).click()
# 获取 Toast 弹框文本信息
result = self.driver.find_element(
AppiumBy.XPATH,
"//*[contains(@text, 'Clicked popup')]"
).text
assert result == "Clicked popup menu item Search"
Java 示例:
@Test
public void testGetToast() {
// 定位到 Make a Popup! 按钮并点击
WebElement buttonMakeAPopup = driver.findElement(AppiumBy.accessibilityId("Make a Popup!"));
buttonMakeAPopup.click();
// 消息框类型选择search
WebElement checkbox = driver.findElement(AppiumBy.xpath("//*[@text='Search']"));
checkbox.click();
// 获取 Toast 弹框文本信息
WebElement toastPopupEle = driver.findElement(AppiumBy.xpath("//*[contains(@text, 'Clicked popup')]"));
String result = toastPopupEle.getText();
assert result.equals("Clicked popup menu item Search");
}
总结
- Toast 定位方法