欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

AS+Appium+Java+Win自动化测试之Appium的Java测试脚本封装(Android测试)

程序员文章站 2022-05-03 13:41:09
一、为什么需要封装? 封装的本意就是为了方便、简洁。 二、android的显式等待封装 1. androiddriverwait.java package com.example.base;...

一、为什么需要封装?

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

二、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 {
 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 extends function {}

3. 使用

 /**
  * 显示等待,等待id对应的控件出现time秒,一出现马上返回,time秒不出现也返回
  */
 public androidelement waitauto(by by, int time) {
  try {
return new androiddriverwait(driver, time)
  .until(new expectedcondition() {
@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 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 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 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("https://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 byby
  * @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  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() {
@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 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);
}


 }

}