常见控件交互方法
常见的交互方法
简介
与 Web 元素操作一样(参考 Selenium Web 元素操作),定位到 APP 控件元素后,可以对控件进行一系列的操作,实现与 APP 交互,比如点击、文本输入、元素属性获取等。
控件交互常用方法
常见操作
- 点击元素:
element.click()
。 - 点击坐标:
driver.tap([(x, y)], 1000)
- 元素中输入内容:
element.send_keys('appium')
。 - 清除元素中内容:
element.clear()
。
状态判断
- 是否可见
element.is_displayed()
返回 True/False。 - 是否可用
element.is_enabled()
返回 True/False。 - 是否被选中
element.is_selected()
返回 True/False。
获取元素属性
- 获取元素属性:
element.get_attribute()
- resource-id - text - class - content-desc - checkable、checked、clickable、enabled、focusable、focused 等 - 获取元素文本:
element.text
- 获取元素坐标:
- 格式:
element.location
- 结果:{'y': 19,'x: 498}
- 获取元素尺寸(高和宽):
- 格式:
element.size
- 结果:{'width':500,'height':22}
控件操作交互示例
- 使用 appium 官方 Demo apk 进行练习,apk 网盘地址。
- 打开 ApiDemos.apk。
- 点击 Animation 进入下个页面。
- 点击 Seeking 进入下个页面。
- 查看【RUN】按钮是否显示/是否可点击。
- 查看【滑动条】是否显示/是否可点击。
- 获取【滑动条】长度。
- 点击【滑动条】中心位置。
Python 代码示例
from appium import webdriver
from appium.options.android import UiAutomator2Options
from appium.webdriver.common.appiumby import AppiumBy
class TestEleOper:
def setup_class(self):
'''
完成 capability 设置
初始化 driver
:return:
'''
# 设置 cpability
caps = {
# 设置 app 安装的平台(Android,iOS)
"platformName": "Android",
# 设置 appium 驱动
"appium:automationName": "uiautomator2",
# 设置设备名称
"appium:deviceName": "emulator-5554",
# 设置被测 app 的包名
"appium:appPackage": "io.appium.android.apis",
# 设置被测 app 启动页面的 Activity
"appium:appActivity": ".ApiDemos"
}
# 初始化 driver
self.driver = webdriver.Remote(
"http://127.0.0.1:4723",
options=UiAutomator2Options().load_capabilities(caps)
)
# 设置全局隐式等待
self.driver.implicitly_wait(5)
def teardown_class(self):
'''
关闭 driver
:return:
'''
self.driver.quit()
def test_ele_oper(self):
'''
点击滑动条中心位置
:return:
'''
# 点击 Animation
self.driver.find_element(
AppiumBy.ACCESSIBILITY_ID, "Animation"
).click()
# 点击 Seeking
self.driver.find_element(
AppiumBy.ACCESSIBILITY_ID, "Seeking"
).click()
# 查看【RUN】按钮是否显示/是否可点击
run_btn_ele = self.driver.find_element(
AppiumBy.ID, "io.appium.android.apis:id/startButton"
)
print(f"RUN 按钮是否显示 {run_btn_ele.is_displayed()}")
print(f"RUN 按钮是否可用 {run_btn_ele.is_enabled()}")
print(f"RUN 按钮是否可点击 {run_btn_ele.get_attribute('clickable')}")
# 查看【滑动条】是否显示/是否可点击
seek_bar_ele = self.driver.find_element(
AppiumBy.ID, "io.appium.android.apis:id/seekBar"
)
print(f"滑动条是否显示 {seek_bar_ele.is_displayed()}")
print(f"滑动条是否可点击 {seek_bar_ele.get_attribute('clickable')}")
# 查看【滑动条】的属性
print(f"滑动条的 resource-id 属性为 {seek_bar_ele.get_attribute('resource-id')}")
print(f"滑动条的 text 属性为 {seek_bar_ele.get_attribute('text')}")
print(f"滑动条的 class 属性为 {seek_bar_ele.get_attribute('class')}")
print(f"滑动条的 content-desc 属性为 {seek_bar_ele.get_attribute('content-desc')}")
# 获取【滑动条】长度
seek_bar_ele_width = seek_bar_ele.size.get('width')
print(f"滑动条长度为 {seek_bar_ele_width}")
# 获取【滑动条】起始位置坐标
seek_bar_ele_start = seek_bar_ele.location
print(f"滑动条起始位置坐标为 {seek_bar_ele_start}")
# 获取【滑动条】中间位置坐标
seek_bar_center_x = seek_bar_ele_start.get("x") + seek_bar_ele_width / 2
seek_bar_center_y = seek_bar_ele_start.get("y")
seek_bar_center = (seek_bar_center_x, seek_bar_center_y)
print(f"滑动条中间位置坐标为 {seek_bar_center}")
# 点击【滑动条】中间位置
self.driver.tap([seek_bar_center], 1000)
Java 代码示例
package org.example;
import io.appium.java_client.AppiumBy;
import io.appium.java_client.TouchAction;
import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.remote.MobileCapabilityType;
import io.appium.java_client.touch.WaitOptions;
import io.appium.java_client.touch.offset.PointOption;
import org.openqa.selenium.Point;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Test;
import java.net.MalformedURLException;
import java.net.URL;
import java.time.Duration;
import java.util.Collections;
public class TestEleOper {
private static AndroidDriver driver;
@BeforeAll
public static void setUp() throws MalformedURLException {
// 初始化capability
DesiredCapabilities caps = new DesiredCapabilities();
// 设置 app 安装的平台(Android、iOS)
caps.setCapability(MobileCapabilityType.PLATFORM_NAME, "Android");
// 设置 appium 驱动
caps.setCapability(MobileCapabilityType.AUTOMATION_NAME, "UiAutomator2");
// 设置设备名称
caps.setCapability(MobileCapabilityType.DEVICE_NAME, "emulator-5554");
// 设置 app 的包名
caps.setCapability("appPackage", "io.appium.android.apis");
// 设置 app 的启动页
caps.setCapability("appActivity", ".ApiDemos");
// 设置 app 不清空缓存
caps.setCapability("appium:noReset", true);
// 设置 app 不重启
caps.setCapability("appium:shouldTerminateApp", true);
// 设置启动url
URL remoteUrl = new URL("http://127.0.0.1:4723");
// 初始化driver
driver = new AndroidDriver(remoteUrl, caps);
}
@AfterAll
public static void teardownClass() {
if (driver != null) {
driver.quit();
}
}
@Test
public void testEleOper() {
// 点击 Animation
driver.findElement(AppiumBy.accessibilityId("Animation")).click();
// 点击 Seeking
driver.findElement(AppiumBy.accessibilityId("Seeking")).click();
// 查看【RUN】按钮是否显示/是否可点击
WebElement runBtnEle = driver.findElement(AppiumBy.id("io.appium.android.apis:id/startButton"));
System.out.println("RUN 按钮是否显示: " + runBtnEle.isDisplayed());
System.out.println("RUN 按钮是否可用: " + runBtnEle.isEnabled());
System.out.println("RUN 按钮是否可点击: " + runBtnEle.getAttribute("clickable"));
// 查看【滑动条】是否显示/是否可点击
WebElement seekBarEle = driver.findElement(AppiumBy.id("io.appium.android.apis:id/seekBar"));
System.out.println("滑动条是否显示: " + seekBarEle.isDisplayed());
System.out.println("滑动条是否可点击: " + seekBarEle.getAttribute("clickable"));
// 查看【滑动条】的属性
System.out.println("滑动条的 resource-id 属性为: " + seekBarEle.getAttribute("resource-id"));
System.out.println("滑动条的 text 属性为: " + seekBarEle.getAttribute("text"));
System.out.println("滑动条的 class 属性为: " + seekBarEle.getAttribute("class"));
System.out.println("滑动条的 content-desc 属性为: " + seekBarEle.getAttribute("content-desc"));
// 获取【滑动条】长度
int seekBarEleWidth = seekBarEle.getSize().getWidth();
System.out.println("滑动条长度为: " + seekBarEleWidth);
// 获取【滑动条】起始位置坐标
Point seekBarEleStart = seekBarEle.getLocation();
System.out.println("滑动条起始位置坐标为: " + seekBarEleStart);
// 获取【滑动条】中间位置坐标
int seekBarCenterX = seekBarEleStart.getX() + seekBarEleWidth / 2;
int seekBarCenterY = seekBarEleStart.getY();
System.out.println("滑动条中间位置坐标为: (" + seekBarCenterX + ", " + seekBarCenterY + ")");
// 点击【滑动条】中间位置
PointerInput finger = new PointerInput(PointerInput.Kind.TOUCH, "finger");
Sequence sequence = new Sequence(finger, 1)
.addAction(finger.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), seekBarCenterX, seekBarCenterY))
.addAction(finger.createPointerDown(PointerInput.MouseButton.LEFT.asArg()))
.addAction(finger.createPointerUp(PointerInput.MouseButton.LEFT.asArg()));
driver.perform(Collections.singletonList(sequence));
}
}
总结
- 常见操作
- 状态判断
- 获取元素属性