文章出处 http://blog.csdn.net/niubitianping/article/details/52612211

一、为什么需要封装?

封装的本意就是为了方便、简洁。

二、Android的显式等待封装

1. AndroidDriverWait.java

package com.example.base;

/**
* Created by LITP on 2016/9/8.
*/ import org.openqa.selenium.NotFoundException;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.ui.Clock;
import org.openqa.selenium.support.ui.FluentWait;
import org.openqa.selenium.support.ui.Sleeper;
import org.openqa.selenium.support.ui.SystemClock; import java.util.concurrent.TimeUnit; import io.appium.java_client.android.AndroidDriver; public class AndroidDriverWait extends FluentWait<AndroidDriver> {
public final static long DEFAULT_SLEEP_TIMEOUT = 500;
private final WebDriver driver; public AndroidDriverWait(AndroidDriver driver, long timeOutInSeconds) {
this(driver, new SystemClock(), Sleeper.SYSTEM_SLEEPER, timeOutInSeconds, DEFAULT_SLEEP_TIMEOUT);
} public AndroidDriverWait(AndroidDriver driver, long timeOutInSeconds, long sleepInMillis) {
this(driver, new SystemClock(), Sleeper.SYSTEM_SLEEPER, timeOutInSeconds, sleepInMillis);
} public AndroidDriverWait(AndroidDriver driver, Clock clock, Sleeper sleeper, long timeOutInSeconds,
long sleepTimeOut) {
super(driver, clock, sleeper);
withTimeout(timeOutInSeconds, TimeUnit.SECONDS);
pollingEvery(sleepTimeOut, TimeUnit.MILLISECONDS);
ignoring(NotFoundException.class);
this.driver = driver;
} @Override
protected RuntimeException timeoutException(String message, Throwable lastException) {
TimeoutException ex = new TimeoutException(message, lastException);
ex.addInfo(WebDriverException.DRIVER_INFO, driver.getClass().getName());
if (driver instanceof RemoteWebDriver) {
RemoteWebDriver remote = (RemoteWebDriver) driver;
if (remote.getSessionId() != null) {
ex.addInfo(WebDriverException.SESSION_ID, remote.getSessionId().toString());
}
if (remote.getCapabilities() != null) {
ex.addInfo("Capabilities", remote.getCapabilities().toString());
}
}
throw ex;
}
}

2.ExpectedCondition.java

接口

package com.example.base;

import com.google.common.base.Function;

import io.appium.java_client.android.AndroidDriver;

/**
* Created by LITP on 2016/9/8.
*/
public interface ExpectedCondition<T> extends Function<AndroidDriver, T> {}

3. 使用

 /**
* 显示等待,等待Id对应的控件出现time秒,一出现马上返回,time秒不出现也返回
*/
public AndroidElement waitAuto(By by, int time) {
try {
return new AndroidDriverWait(driver, time)
.until(new ExpectedCondition<AndroidElement>() {
@Override
public AndroidElement apply(AndroidDriver androidDriver) {
return (AndroidElement) androidDriver.findElements(by);
}
});
} catch (TimeoutException e) {
Assert.fail("查找元素超时!! " + time + " 秒之后还没找到元素 [" + by.toString() + "]", e);
return null;
}
}

三、Assert断言的封装

封装了 出现错误输出了异常信息但不终止程序的运行,会继续往下执行。

1.Assertion.java

package com.example.base;

import org.testng.Assert;

import java.util.ArrayList;
import java.util.List; /**
* Created by LITP on 2016/9/21.
*/ public class Assertion { public static boolean flag = true; //是否有错误 public static List<Error> errors = new ArrayList<>(); //错误集合 /**
* 验证值是否相等
* @param actual 第一个值
* @param expected 要对比的值
*/
public static void verifyEquals(Object actual, Object expected){
try{
Assert.assertEquals(actual, expected);
}catch(Error e){
errors.add(e);
flag = false;
}
} /**
* 验证值是否相等
* @param actual 第一个值
* @param expected 要对比的值
* @param message 出错时候的提示消息
*/
public static void verifyEquals(Object actual, Object expected, String message){
try{
Assert.assertEquals(actual, expected, message);
}catch(Error e){
errors.add(e);
flag = false;
}
}
}

2.AssertionListener.java

package com.example.base;

import org.testng.ITestResult;
import org.testng.TestListenerAdapter; import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; import static javafx.scene.input.KeyCode.T; /**
* Created by LITP on 2016/9/21.
*/ public class AssertionListener extends TestListenerAdapter { /**
* 测试方法开始的时候回调
* @param result
*/
@Override
public void onTestStart(ITestResult result) {
Assertion.flag = true;
Assertion.errors.clear();
} /**
* 测试终止时候回调
* @param tr
*/
@Override
public void onTestFailure(ITestResult tr) {
this.handleAssertion(tr);
} /**
* Test跳过 的时候执行
* @param tr
*/
@Override
public void onTestSkipped(ITestResult tr) {
this.handleAssertion(tr);
} /**
* Test运行完毕时候执行
* @param tr
*/
@Override
public void onTestSuccess(ITestResult tr) {
this.handleAssertion(tr);
} private int index = 0; //错误行号 /**
* 处理断言,每个Test执行完毕回调
* @param tr 测试结果
*/
private void handleAssertion(ITestResult tr){
if(!Assertion.flag){ //为假,就是断言出错了就执行下面的
//获取异常
Throwable throwable = tr.getThrowable();
if(throwable==null){
throwable = new Throwable();
}
//获取异常堆栈信息
StackTraceElement[] traces = throwable.getStackTrace(); //创建要输出的所有堆栈信息
StackTraceElement[] alltrace = new StackTraceElement[0]; //循环获取断言的异常信息,
for (Error e : Assertion.errors) {
//获取错误的堆栈数组信息
StackTraceElement[] errorTraces = e.getStackTrace();
//
StackTraceElement[] et = getKeyStackTrace(tr, errorTraces);
//设置异常信息堆栈内容
StackTraceElement[] message = handleMess(e.getMessage(),tr); //行号初始化为0
index = 0;
//堆栈信息合并
alltrace = merge(alltrace, message);
alltrace = merge(alltrace, et);
} //如果异常信息不为空
if(traces!=null){
traces = getKeyStackTrace(tr, traces);
alltrace = merge(alltrace, traces);
} //保存异常信息
throwable.setStackTrace(alltrace);
tr.setThrowable(throwable); //清空
Assertion.flag = true;
Assertion.errors.clear(); //输出异常信息
tr.setStatus(ITestResult.FAILURE);
}
} /**
* 获取堆栈信息
* @param tr
* @param stackTraceElements
* @return
*/
private StackTraceElement[] getKeyStackTrace(ITestResult tr, StackTraceElement[] stackTraceElements){ List<StackTraceElement> ets = new ArrayList<>();
//循环获取信息
for (StackTraceElement stackTraceElement : stackTraceElements) {
//返回测试类的堆栈信息
if(stackTraceElement.getClassName().equals(tr.getTestClass().getName())){
ets.add(stackTraceElement);
index = stackTraceElement.getLineNumber(); //错误行号
}
}
return ets.toArray(new StackTraceElement[ets.size()]); } /**
* 合并两个堆栈信息
* @param traces1 第一个
* @param traces2
* @return
*/
private StackTraceElement[] merge(StackTraceElement[] traces1, StackTraceElement[] traces2){ StackTraceElement[] result = Arrays.copyOf(traces1, traces1.length + traces2.length);
System.arraycopy(traces2, 0, result, traces1.length, traces2.length);
return result;
} /**
* 处理消息提示内容
* @param mess 报错信息
* @param tr 结果描述
* @return
*/
private StackTraceElement[] handleMess(String mess,ITestResult tr){
String message = "\n报错信息: "+mess;
String method = "\n报错方法名:"+tr.getMethod().getMethodName();
String className = "\n报错类:"+tr.getTestClass().getRealClass().getSimpleName();
return new StackTraceElement[]{
new StackTraceElement(message, //内容
method, //方法名
className+"\n报错行号", //文件名
index)};
}
}

四、Appium java的封装

1. Builder.java

构建器,在每个用例上都可以很方便设置app的属性

package com.example.base;

/**
* Created by LITP on 2016/9/7.
*/
public class Builder {
String deviceName = BaseAppium.deviceName;
String platformVersion = BaseAppium.platformVersion;
String path = System.getProperty("user.dir") + "/src/main/java/apps/";
String appPath = BaseAppium.appPath;
String appPackage = BaseAppium.appPackage;
String noReset = BaseAppium.noReset;
String noSign = BaseAppium.noSign;
String unicodeKeyboard = BaseAppium.unicodeKeyboard;
String resetKeyboard = BaseAppium.resetKeyboard;
String appActivity = BaseAppium.appActivity; public Builder setAppPath(String appPath) {
this.appPath = path + appPath;
return this;
} public Builder setDeviceName(String deviceName) {
this.deviceName = deviceName;
return this;
} public Builder setPlatformVersion(String platformVersion) {
this.platformVersion = platformVersion;
return this;
} public Builder setApp(String appPath) {
this.appPath = appPath;
return this;
} public Builder setAppPackage(String appPackage) {
this.appPackage = appPackage;
return this;
} public Builder setNoReset(String noReset) {
this.noReset = noReset;
return this;
} public Builder setNoSign(String noSign) {
this.noSign = noSign;
return this;
} public Builder setUnicodeKeyboard(String unicodeKeyboard) {
this.unicodeKeyboard = unicodeKeyboard;
return this;
} public Builder setResetKeyboard(String resetKeyboard) {
this.resetKeyboard = resetKeyboard;
return this;
} public Builder setAppActivity(String appActivity) {
this.appActivity = appActivity;
return this;
} public BaseAppium build() {
return new BaseAppium(this);
}
}

2. BaseAppium.java

父类,里面封装了一堆方法,只管用,传id、name那些就行了。当然这只是一部分,仅供参考,可以自己修改添加。这个封装没有利用po模式,仅供参考,接下来的文章继续优化封装。

package com.example.base;

import org.apache.http.util.TextUtils;
import org.openqa.selenium.By;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.testng.Assert;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeSuite;
import org.testng.annotations.Listeners; import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;
import java.util.concurrent.TimeUnit; import io.appium.java_client.MultiTouchAction;
import io.appium.java_client.TouchAction;
import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.android.AndroidElement; /**
* Created by LITP on 2016/9/7.
*/
@Listeners({com.example.base.AssertionListener.class})
public class BaseAppium {
//调试设备名字
public static String deviceName = "minote";
//调试设备系统版本
public static String platformVersion = "4.4.2";
//app路径
public static String appPath = System.getProperty("user.dir") + "/src/main/java/apps/shouhu2.2.3.apk"; //包名
public static String appPackage = "com.minstone.mdoctor"; //是否需要重新安装
public static String noReset = "True"; //是否不重新签名
public static String noSign = "True"; //是否使用unicode输入法,真是支持中文
public static String unicodeKeyboard = "True"; //是否祸福默认呢输入法
public static String resetKeyboard = "True"; //要启动的Activity
public static String appActivity = appPackage + ".activity.login.WelcomeActivity"; public AndroidDriver<AndroidElement> driver = null; //单个触摸操作类
TouchAction touchAction; //多个触摸操作时间
MultiTouchAction multiTouchAction; private static int WAIT_TIME = 10; //默认的等待控件时间
private static int SWIPE_DEFAULT_PERCENT = 5; //默认滑动比例 //构造方法
public BaseAppium() {
this(new Builder());
} public BaseAppium(Builder builder) {
print("基类初始化!");
appActivity = builder.appActivity;
appPackage = builder.appPackage;
appPath = builder.appPath;
deviceName = builder.deviceName;
noReset = builder.noReset;
noSign = builder.noSign;
unicodeKeyboard = builder.unicodeKeyboard;
resetKeyboard = builder.resetKeyboard;
} /**
* appium启动参数
*
* @throws MalformedURLException
*/
@BeforeSuite
public void beforeSuite() throws MalformedURLException { DesiredCapabilities capabilities = new DesiredCapabilities(); capabilities.setCapability("deviceName", deviceName);
capabilities.setCapability("platformVersion", platformVersion);
capabilities.setCapability("app", new File(appPath).getAbsolutePath());
capabilities.setCapability("appPackage", appPackage);
//支持中文
capabilities.setCapability("unicodeKeyboard", unicodeKeyboard);
//运行完毕之后,变回系统的输入法
capabilities.setCapability("resetKeyboard", resetKeyboard);
//不重复安装
capabilities.setCapability("noReset", noReset);
//不重新签名
capabilities.setCapability("noSign", noSign);
//打开的activity
capabilities.setCapability("appActivity", appActivity);
//启动Driver
driver = new AndroidDriver<>(new URL("http://127.0.0.1:4723/wd/hub"), capabilities); } @AfterTest
public void afterTest() {
//结束这次测试
driver.quit();
} public boolean isIdElementExist(String id) {
return isIdElementExist(id, false);
} /**
* 根据id判断当前界面是否存在并显示这个控件
*
* @param id 要查找的id
* @param isShow 是否判断控件显示
* @return 返回对应的控件
*/
public boolean isIdElementExist(String id, boolean isShow) {
AndroidElement ae;
try {
if (driver != null) {
ae = driver.findElementById(appPackage + ":id/" + id);
if (isShow) {
return ae.isDisplayed();
} else {
return ae != null;
}
} else {
print("driver为空");
}
} catch (NoSuchElementException e) {
print("找不到控件" + e.getMessage());
} return false; } /**
* 选择当前界面的有这个文字的控件
*
* @param name
* @param hasShow 是否显示
* @return
*/
public boolean isNameElementExist(String name, boolean hasShow) {
try {
AndroidElement ae = driver.findElement(By.name(name));
if (hasShow) {
return ae.isDisplayed();
} else return ae != null;
} catch (NoSuchElementException e) {
return false;
} } public boolean isNameElementExist(String name) {
return isNameElementExist(name, false);
} /**
* 判断控件时候存在
*
* @param by By
* @param timeout 等待的事件
* @return
*/
public boolean isElementExist(By by, int timeout) {
try {
waitAuto(by, timeout);
return true;
} catch (Exception e) {
return false;
}
} /**
* 根据id获取当前界面的一个控件
*
* @param id 要查找的id
* @return 返回对应的控件
*/
public AndroidElement findById(String id) {
try {
if (driver != null) {
return driver.findElementById(appPackage + ":id/" + id);
} else {
print("driver为空");
}
} catch (NoSuchElementException e) {
print("找不到控件" + e.getMessage());
}
return null;
} /**
* 选择当前界面的有这个文字的控件
*
* @param name 内容
* @return 找到的控件
*/
public AndroidElement findByName(String name) {
return driver.findElement(By.name(name));
} /**
* 根据id获取当前界面的一个控件
*
* @param name 要查找的控件的类名
* @return 返回对应的控件
*/
public AndroidElement findByClassName(String name) {
try {
if (driver != null) {
return driver.findElementByClassName(name);
} else {
print("dricer为空");
}
} catch (NoSuchElementException e) {
print("找不到控件" + e.getMessage());
}
return null;
} /**
* 打印字符
*
* @param str 要打印的字符
*/
public <T> void print(T str) {
if (!TextUtils.isEmpty(String.valueOf(str))) {
System.out.println(str);
} else {
System.out.println("输出了空字符");
}
} /**
* Click点击空格键
*
* @param ae 要点击的控件
* @return 返回是否点击
*/
public boolean clickView(AndroidElement ae) {
return clickView(ae, "");
} /**
* Click点击控件
*
* @param ae 控件
* @param str 控件的文字描述,供错误时候输出
* @return 返回是否存在控件
*/
public boolean clickView(AndroidElement ae, String str) {
if (ae != null) {
ae.click();
return true;
} else {
print(str + "为空,点击错误");
}
return false;
} /**
* Click点击指定id的View
*
* @param id 要点击的控件的id
* @return 点击了返回真
*/
public boolean clickView(String id) {
AndroidElement ae = findById(id);
if (ae != null) {
ae.click();
return true;
} else {
print(id + "为空,点击错误");
}
return false;
} /**
* 线程休眠秒数,单位秒
*
* @param s 要休眠的秒数
*/
public void sleep(long s) throws InterruptedException {
Thread.sleep(s);
} /**
* 获取触摸实例
*
* @return
*/
public TouchAction getTouch() {
if (driver == null) {
print("单点触摸时候driver为空");
return null;
} else {
if (touchAction == null) {
return new TouchAction(driver);
} else {
return touchAction;
} }
} /**
* 获取多点触摸实例
*
* @return
*/
public MultiTouchAction getMultiTouch() {
if (driver == null) {
print("多点触摸时候driver为空");
return null;
} else {
if (multiTouchAction == null) {
return new MultiTouchAction(driver);
} else {
return multiTouchAction;
} }
} /**
* 往控件输入字符串
*
* @param ae 要输入的控件
* @param str 要输入的字符串
*/
public void input(AndroidElement ae, String str) {
if (ae == null) {
print("控件为空,输入内容失败:" + str);
} else {
ae.sendKeys(str);
} } public void swipeToUp(int during){
swipeToUp(during,SWIPE_DEFAULT_PERCENT);
}
/**
* 向上滑动,
*
* @param during
*/
public void swipeToUp(int during,int percent) {
int width = getScreenWidth();
int height = getScreenHeight();
driver.swipe(width / 2, height * (percent - 1) / percent, width / 2, height / percent, during);
} public void swipeToDown(int during){
swipeToDown(during,SWIPE_DEFAULT_PERCENT);
} /**
* 向下滑动,
*
* @param during 滑动时间
*/
public void swipeToDown(int during,int percent) {
int width = getScreenWidth();
int height = getScreenHeight();
driver.swipe(width / 2, height / percent, width / 2, height * (percent - 1) / percent, during);
} public void swipeToLeft(int during){
swipeToLeft(during,SWIPE_DEFAULT_PERCENT);
} /**
* 向左滑动,
*
* @param during 滑动时间
* @param percent 位置的百分比,2-10, 例如3就是 从2/3滑到1/3
*/
public void swipeToLeft(int during, int percent) {
int width = getScreenWidth();
int height = getScreenHeight();
driver.swipe(width * (percent - 1) / percent, height / 2, width / percent, height / 2, during);
} public void swipeToRight(int during) {
swipeToRight(during, SWIPE_DEFAULT_PERCENT);
} /**
* 向右滑动,
*
* @param during 滑动时间
* @param percent 位置的百分比,2-10, 例如3就是 从1/3滑到2/3
*/
public void swipeToRight(int during, int percent) {
int width = getScreenWidth();
int height = getScreenHeight();
driver.swipe(width / percent, height / 2, width * (percent - 1) / percent, height / 2, during);
} /**
* 显示等待,等待Id对应的控件出现time秒,一出现马上返回,time秒不出现也返回
*/
public AndroidElement waitAuto(By by, int time) {
try {
return new AndroidDriverWait(driver, time * 1000)
.until(new ExpectedCondition<AndroidElement>() {
@Override
public AndroidElement apply(AndroidDriver androidDriver) {
return (AndroidElement) androidDriver.findElement(by);
}
});
} catch (TimeoutException e) {
Assert.fail("查找元素超时!! " + time + " 秒之后还没找到元素 [" + by.toString() + "]", e);
return null;
}
} public AndroidElement waitAutoById(String id) {
return waitAutoById(id, WAIT_TIME);
} public AndroidElement waitAutoById(String id, int time) {
return waitAuto(By.id(id), time);
} public AndroidElement waitAutoByName(String name) {
return waitAutoByName(name, WAIT_TIME);
} public AndroidElement waitAutoByName(String name, int time) {
return waitAuto(By.name(name), time);
} public AndroidElement waitAutoByXp(String xPath) {
return waitAutoByXp(xPath, WAIT_TIME);
} public AndroidElement waitAutoByXp(String xPath, int time) {
return waitAuto(By.xpath(xPath), time);
} public void waitAuto() {
waitAuto(WAIT_TIME);
} /**
* ,隐式等待,如果在指定时间内还是找不到下个元素则会报错停止脚本
* 全局设定的,find控件找不到就会按照这个事件来等待
*
* @param time 要等待的时间
*/
public void waitAuto(int time) {
driver.manage().timeouts().implicitlyWait(time, TimeUnit.SECONDS);
} /**
* 打开Activity
*
* @param activityName activity的名字
*/
public void startActivity(String activityName) {
driver.startActivity(appPackage, activityName);
} /**
* 获取当前的activity,返回文件名
*
* @return
*/
public String getCurrActivity() {
String str = driver.currentActivity();
return str.substring(str.lastIndexOf(".") + 1);
} /**
* 获取当前界面的所有EditText,并依次输入内容
*
* @param str 要输入的数组
*/
public void inputManyText(String... str) {
List<AndroidElement> textFieldsList = driver.findElementsByClassName("android.widget.EditText");
for (int i = 0; i < str.length; i++) {
textFieldsList.get(i).sendKeys(str[i]);
//textFieldsList.get(i).setValue(str[i]); }
} /**
* 点击某个控件
*
* @param ae 要点击的控件
*/
public void press(AndroidElement ae) {
try {
getTouch().tap(ae).perform();
} catch (Exception e) {
print("tab点击元素错误" + e.getMessage());
e.printStackTrace();
}
} /**
* 点击某个坐标
*
* @param x
* @param y
*/
public void press(int x, int y) {
try {
getTouch().tap(x, y).perform();
} catch (Exception e) {
print("tab点击元素错误" + e.getMessage());
e.printStackTrace();
}
} /**
* 长按某个控件
*
* @param ae 要点击的控件
*/
public void longPress(AndroidElement ae) {
try {
getTouch().longPress(ae).release().perform();
} catch (Exception e) {
print("长按点击元素错误" + e.getMessage());
e.printStackTrace();
}
} /**
* 长按某个坐标
*
* @param x
* @param y
*/
public void longPress(int x, int y) {
try {
getTouch().longPress(x, y).release().perform();
} catch (Exception e) {
print("长按点击元素错误" + e.getMessage());
e.printStackTrace();
}
} /**
* 在控件上滑动
*
* @param element 要滑动的控件
* @param direction 方向,事件不设置默认1秒
*/
public void swipOnElement(AndroidElement element, String direction) {
swipOnElement(element, direction, 1000); //不设置时间就为2秒
} /**
* 在某一个控件上滑动
*
* @param element 在那个元素上滑动
* @param direction 方向,UP DOWN LEFT RIGHT
*/
public void swipOnElement(AndroidElement element, String direction, int duration) {
//获取元素的起初xy,在左上角
int x = element.getLocation().getX();
int y = element.getLocation().getY();
//获取元素的宽高
int width = element.getSize().getWidth();
int height = element.getSize().getHeight(); switch (direction) {
case "UP":
int startX = x + width / 2;
//在4/5的底部的中间向上滑动
driver.swipe(startX, y + height * 4 / 5, startX, y + height / 5, duration);
break;
case "DOWN":
startX = x + width / 2;
//在4/5的底部的中间向上滑动
driver.swipe(startX, y + height / 5, startX, y + height * 4 / 5, duration);
break; case "LEFT":
int startY = y + width / 2;
driver.swipe(x + width * 4 / 5, startY, x + width / 5, startY, duration);
break;
case "RIGHT":
startY = y + width / 2;
driver.swipe(x + width / 5, startY, x + width * 4 / 5, startY, duration);
break;
}
} /**
* 在某个方向上滑动
*
* @param direction 方向,UP DOWN LEFT RIGHT
* @param duration 持续时间
*/
public void swip(String direction, int duration) {
switch (direction) {
case "UP":
swipeToUp(duration);
break;
case "DOWN":
swipeToDown(duration);
break;
case "LEFT":
swipeToLeft(duration);
break;
case "RIGHT":
swipeToRight(duration);
break;
}
} /**
* 在指定次数的条件下,某个方向滑动,直到这个元素出现
*
* @param by 控件
* @param direction 方向,UP DOWN LEFT RIGHT
* @param duration 滑动一次持续时间
* @param maxSwipNum 最大滑动次数
*/
public void swipUtilElementAppear(By by, String direction, int duration, int maxSwipNum) {
int i = maxSwipNum;
Boolean flag = true;
while (flag) {
try {
if (i <= 0) {
flag = false;
}
driver.findElement(by);
flag = false;
} catch (Exception e) {
i--;
swip(direction, duration);
}
}
} /**
* 在某个方向滑动直到这个元素出现
*
* @param by 控件
* @param direction 方向,UP DOWN LEFT RIGHT
* @param duration 滑动一次持续时间
*/
public void swipUtilElementAppear(By by, String direction, int duration) {
Boolean flag = true;
while (flag) {
try {
driver.findElement(by);
flag = false;
} catch (Exception e) {
swip(direction, duration);
}
}
} /**
* 获取屏幕的宽高
*
* @return 返回宽高的数组
*/
public int[] getScreen() {
int width = driver.manage().window().getSize().getWidth();
int height = driver.manage().window().getSize().getHeight();
return new int[]{width, height};
} /**
* 获取屏幕宽度
*
* @return
*/
public int getScreenWidth() {
return driver.manage().window().getSize().getWidth();
} /**
* 获取屏幕高度
*
* @return
*/
public int getScreenHeight() {
return driver.manage().window().getSize().getHeight();
} /**
* 逐字删除编辑框中的文字
* @param element 文本框架控件
*/
public void clearText(AndroidElement element){
String text = element.getText();
//跳到最后
driver.pressKeyCode(KEYCODE_MOVE_END);
for (int i = 0; i < text.length(); i ++){
//循环后退删除
driver.pressKeyCode(BACKSPACE);
} } }

Appium的Java封装的更多相关文章

  1. 【原创】中文分词系统 ICTCLAS2015 的JAVA封装和多线程执行(附代码)

    本文针对的问题是 ICTCLAS2015 的多线程分词,为了实现多线程做了简单的JAVA封装.如果有需要可以自行进一步封装其它接口. 首先ICTCLAS2015的传送门(http://ictclas. ...

  2. java封装的方法

    java封装是由Java是面向对象程序设计语言的性质决定的,面向对象程序设计语言的三大特性之一就是封装.封装其实就是包装的意思,从专业的角度来看,就是把对象的所有组成部分组合在一起,保护私有属性. 如 ...

  3. Java - 24 Java 封装

    Java 封装 在面向对象程式设计方法中,封装(英语:Encapsulation)是指,一种将抽象性函式接口的实作细节部份包装.隐藏起来的方法. 封装可以被认为是一个保护屏障,防止该类的代码和数据被外 ...

  4. Echarts 的 Java 封装类库 转自 https://my.oschina.net/flags/blog/316920

    转自: https://my.oschina.net/flags/blog/316920 Echarts 的 Java 封装类库:http://www.oschina.net/p/echarts-ja ...

  5. Appium(JAVA)Windows 7系统搭建及示例运行

    Appium(JAVA)Windows 7系统搭建及示例运行 分类: Appium 2014-11-14 17:44 4323人阅读 评论(2) 收藏 举报 1.搭建Android环境 http:// ...

  6. Java-Runoob-面向对象:Java 封装

    ylbtech-Java-Runoob-面向对象:Java 封装 1.返回顶部 1. Java 封装 在面向对象程式设计方法中,封装(英语:Encapsulation)是指一种将抽象性函式接口的实现细 ...

  7. java封装的优点

    在面向对象程式设计方法中,封装(英语:Encapsulation)是指一种将抽象性函式接口的实现细节部份包装.隐藏起来的方法. 封装可以被认为是一个保护屏障,防止该类的代码和数据被外部类定义的代码随机 ...

  8. 乐字节Java|封装JavaBean、继承与权限修饰

    本文继续讲Java封装.上一篇:乐字节Java|GC垃圾回收机制.package和import语句 这次讲述JavaBean.继承与权限修饰 一. 封装javaBean 封装(Encapsulatio ...

  9. Java 封装 继承 多态

    Java 继承 继承的概念 继承是java面向对象编程技术的一块基石,因为它允许创建分等级层次的类. 继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法 ...

随机推荐

  1. Solr 多字段、打分规则、权重和实时索引同步

    1.字段 Filed:<field name="_id" type="text_ik" indexed="true" stored=& ...

  2. linux2.6内核netfilter架构分析

    1.2.6内核的netfilter与2.4的有很大不同: ChangeLog-2.6.15 中有下面这样的描述: commit 9fb9cbb1082d6b31fb45aa1a14432449a0df ...

  3. Golang并发原理及GPM调度策略(一)

    其实从一开始了解到go的goroutine概念就应该想到,其实go应该就是在内核级线程的基础上做了一层逻辑上的虚拟线程(用户级线程)+ 线程调度系统,如此分析以后,goroutine也就不再那么神秘了 ...

  4. Java反射小结

    一.什么是反射? 在运行状态中,对于任意一个类,都能够获取到这个类的所有属性和方法,对于任意一个对象,都能够调用它的任意一个方法和属性(包括私有的方法和属性),这种动态获取的信息以及动态调用对象的方法 ...

  5. Tensorflow之合并tensor

    https://www.tensorflow.org/versions/r0.12/api_docs/python/array_ops.html#concat 例子: t1 = [[1, 2, 3], ...

  6. Yii2 选择布局的方式

    方案1:控制器内成员变量 public $layout = false; //不使用布局 public $layout = "main"; //设置使用的布局文件 方案2:控制器成 ...

  7. ARM汇编语言(3)(寄存器读写控制外设)

    DAY4:ARM汇编(4) 一,GPIO编程     连接内存(二级cache),用来寻址:连接外设,用来控制:   1,GPIO,General-Purpose IO ports,通用输入输出端口, ...

  8. c++11小计

    [capture] (parameters) mutable -> return-type { statement } " (parameters)" 和 "-&g ...

  9. 【原】storm源码之巧用java反射反序列化clojure的defrecord获取属性值

    storm源码是clojure.java.python的混合体.在解决storm-0.8.2的nimbus单点问题的过程中需要从zookeeper上读取目前storm集群中正在运行的assignmen ...

  10. AtCoder Tak and Hotels

    题目链接:传送门 题目大意:有 n 个点排成一条直线,每次行动可以移动不超过 L 的距离,每次行动完成必须停在点上, 数据保证有解,有 m 组询问,问从 x 到 y 最少需要几次行动? 题目思路:倍增 ...