文章出处 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. Error occurred whiLe getting the data source contents for the report

    Web service request GetDataSourceContents to Report Server http://crm-vm/reportserver/ReportService2 ...

  2. Meter and pixel units in a box2d game - LibGDX

    http://pimentoso.blogspot.com/2013/01/meter-and-pixel-units-in-box2d-game.html 需FQ ————————————————— ...

  3. PAT003 List Leaves

    题目: Given a tree, you are supposed to list all the leaves in the order of top down, and left to righ ...

  4. 图像处理之拼接---图像拼接opencv

    基于SURF特征的图像与视频拼接技术的研究和实现(一)      一直有计划研究实时图像拼接,但是直到最近拜读西电2013年张亚娟的<基于SURF特征的图像与视频拼接技术的研究和实现>,条 ...

  5. Accept-Encoding 使用

    [总结] 想要获得正确网页内容,而非乱码的话,就有两种方式了: 1.不要设置Accept-Encoding的Header //req.Headers.Add("Accept-Encoding ...

  6. JavaScript修改IE注册表

    http://www.cnblogs.com/zmc/p/3373812.html <script type="text/javascript"> var obj = ...

  7. python入门(一):基础语法

    1.修改字符编码# -*- coding: cp-1252 -*-2.标识符以字母或下划线开头,大小写敏感3.以缩进表示代码块,同一个代码块缩进必须一致4.多行代码用反斜杠表示,() [] {}则不需 ...

  8. 使用Beautifulsoup去除特定标签

    使用Beautifulsoup去除特定标签 试用了Beautifulsoup,的确是个神器. 在抓取到网页时,会出现很多不想要的内容,例如<script>标签,利用beautifulsou ...

  9. django用户认证系统——修改密码6

    再此之前我们已经完成了用户登录.注册.注销等功能,接下来让我们继续为用户提供修改密码的功能.该功能 Django 的 auth 应用也已经为我们提供,过程几乎和之前的登录功能完全一样. 编写修改密码模 ...

  10. Android 调用堆栈跟踪

    Android开发中,我们也会经常遇到段错误,也就是SIGSEGV(11),这个时候libc的backtrace会打印出对应的堆栈信 息,而你看到的仅仅是一对数字,好像无从查起. 如下面这一从串断错误 ...