Appium 点击控件某个位置(相对位置)方法封装
问题: 实际项目中自动化会碰到点击某个控件的某个位置问题, appium 点击不到, 如何自定义方法能在项目中复用?
Android UI 定位 坐标分析
/**
* Android:
* (left, top) Point
* ↖ --->x
* ┌────────┐
* │ │ │
* ↓ │ │
* y └────────┘
* ↘
* (right, bottom) Point
*/
Appium 中获取控件的定位坐标的方法为
// 获取控件开始位置的坐标轴
start = new AndroidDriver(
new URL("http://127.0.0.1:4724/wd/hub"), desiredCapabilities).findElement(locator).getLocation();
// 获取控件坐标轴差
q = new AndroidDriver(
new URL("http://127.0.0.1:4724/wd/hub"), desiredCapabilities);.findElement(locator).getSize();
//起始坐标(x1,y1), 结束坐标 (x2,y2)
x1=start.x;
y1=start.y;
x2=q.x;
y2=q.y;
坐标实例:
获取逍遥模拟器中的 WI-FI 控件的起始坐标/结束坐标
已知起始坐标,结束坐标, 请对控件的某个位置 点击要如何做到了?
方法: 只有对这个控件的空间(面积)进行比例分计算出相对的坐标,然后在点击就好了
创建一个 枚举enum (对控件的面积进行比例分) (左,左上,左下,中间,右边,右上,右下) :安项目情况具体分析
public enum Location {
LEFT_TOP(0.1, 0.1),
LEFT_CENTER(0.1, 0.5),
LEFT_BOTTOM(0.1, 0.9),
CENTER_TOP(0.5, 0.1),
CENTER(0.5, 0.5),
CENTER_BOTTOM(0.5, 0.9),
RIGHT_TOP(0.9, 0.1),
RIGHT_CENTER(0.9, 0.5),
RIGHT_BOTTOM(0.9, 0.9);
Location() {
}
private double xProportion;
private double yProportion;
public final double getXProportion() {
return this.xProportion;
}
public final double getYProportion() {
return this.yProportion;
}
private Location(double xProportion, double yProportion) {
this.xProportion = xProportion;
this.yProportion = yProportion;
}
}
计算控件的起始坐标/结束坐标
public static int[] getPoint(By locator,WebElement element){
int[] coordinate = new int[4];
Point start = null;
Dimension q = null;
if (locator != null){
// 获取控件开始位置的坐标轴
start = DriverInit.driver.findElement(locator).getLocation();
// 获取控件坐标轴差
q = DriverInit.driver.findElement(locator).getSize();
}else if (element != null){
// 获取控件开始位置的坐标轴
start = element.getLocation();
// 获取控件坐标轴差
q = element.getSize();
}
// 获取控件开始位置的坐标轴
assert start != null;
int startX = start.x;
int startY = start.y;
int x = q.getWidth();
int y = q.getHeight();
// 计算出控件结束坐标
int endX = x + startX;
int endY = y + startY;
coordinate[0] = startX;
coordinate[1] = startY;
coordinate[2] = endX;
coordinate[3] = endY;
return coordinate;
}
public static int[] getLongAndHigh(int[] arr){
/**
* (x1,y1)=(100,1193)
* (x2,y2)=(619,1229)
* Y high=y2-y1=1229-1193=36 rect[1]
* X long=x2-x1=619-100=519 rect[0]
*/
int right;
int bottom;
int[] longAndHigh = new int[2];
bottom=arr[3]-arr[1];
right=arr[2]-arr[0];
longAndHigh[0]=right;
longAndHigh[1]=bottom;
return longAndHigh;
}
//创建点击控件某个位子 ((左,左上,左下,中间,右边,右上,右下)
public static void click_control(By locator, WebElement element, Location location) throws InterruptedException {
int[] coordinate = getPoint(locator,element);
int[] rect = getLongAndHigh(coordinate);
switch (location) {
// 左上 点击
case LEFT_TOP:
new TouchAction<>(DriverInit.driver).press(PointOption.point(
(int)(coordinate[0]+(rect[0]*Location.LEFT_TOP.getXProportion())),
(int)(coordinate[1]+(rect[1]*Location.LEFT_TOP.getYProportion()))))
.release().perform();
Thread.sleep(2);
break;
// 右上 点击
case RIGHT_TOP:
new TouchAction<>(DriverInit.driver).press(PointOption.point(
(int)(coordinate[0]+(rect[0]*Location.RIGHT_TOP.getXProportion())),
(int)(coordinate[1]+(rect[1]*Location.RIGHT_TOP.getYProportion()))))
.release().perform();;
Thread.sleep(2);
break;
// 左下 点击
case LEFT_BOTTOM:
new TouchAction<>(DriverInit.driver).press(PointOption.point(
(int)(coordinate[0]+(rect[0]*Location.LEFT_BOTTOM.getXProportion())),
(int)(coordinate[1]+(rect[1]*Location.LEFT_BOTTOM.getYProportion()))))
.release().perform();;
Thread.sleep(2);
break;
// 右下 点击
case RIGHT_BOTTOM:
new TouchAction<>(DriverInit.driver).press(PointOption.point(
(int)(coordinate[0]+(rect[0]*Location.RIGHT_BOTTOM.getXProportion())),
(int)(coordinate[1]+(rect[1]*Location.RIGHT_BOTTOM.getYProportion()))))
.release().perform();;
Thread.sleep(2);
break;
// 中间 点击
case CENTER:
new TouchAction<>(DriverInit.driver).press(PointOption.point(
(int)(coordinate[0]+(rect[0]*Location.CENTER.getXProportion())),
(int)(coordinate[1]+(rect[1]*Location.CENTER.getYProportion()))))
.release().perform();;
Thread.sleep(2);
break;
case LEFT_CENTER:
new TouchAction<>(DriverInit.driver).press(PointOption.point(
(int)(coordinate[0]+(rect[0]*Location.LEFT_CENTER.getXProportion())),
(int)(coordinate[1]+(rect[1]*Location.LEFT_CENTER.getYProportion()))))
.release().perform();;
Thread.sleep(2);
break;
case RIGHT_CENTER:
System.out.println( "x="+(int)(coordinate[0]+(rect[0]*Location.RIGHT_CENTER.getXProportion())));
System.out.println( "y="+(int)(coordinate[1]+(rect[1]*Location.RIGHT_CENTER.getYProportion())));
new TouchAction<>(DriverInit.driver).press(PointOption.point(
(int)(coordinate[0]+(rect[0]*Location.RIGHT_CENTER.getXProportion())),
(int)(coordinate[1]+(rect[1]*Location.RIGHT_CENTER.getYProportion()))))
.release().perform();;
Thread.sleep(2);
break;
}
}
测试结果
@Test
public void test1() throws MalformedURLException, InterruptedException {
System.out.println("user launch xxx app from device");
System.out.println(deviceName);
//单设备
DesiredCapabilities cap = DriverInit.setCapabilities(
deviceName,
platFormName,
platFormVersion,
appPackage,
appActivity);
DriverInit.setDriver(platFormName, cap);
//点击控件的右边
DriverWait.click_control(ONBPage.login_option,null, Location.RIGHT_CENTER);
//等待Username控件出现
DriverWait.wait_until_present(ONBPage.username_box);
DriverInit.driver.quit();
}