一、元素定位
使用 SDK自带的APP元素查看工具uiautomatorviewer来获取元素,方法如下:
1、将测试机连接到电脑上,打开测试机上的待测app;
2、打开ANDROID SDK文件夹,在\sdk\tools下找到批处理文件uiautomatorviewer.bat,运行这个文件;
3、点击Devices Screenshot,获取元素如下
二、获取&操作元素
1、直接文本定位,通常用于操作文案不变的按钮;
/*直接文本定位*/
//登录框切换注册、登录
WebElement LogItemBtn =driver.findElementByAndroidUIAutomator("new UiSelector().text(\"Log In\")");
LogItemBtn.click();
Thread.sleep(3000);
WebElement RegisterItemBtn =driver.findElementByAndroidUIAutomator("new UiSelector().text(\"Register\")");
RegisterItemBtn.click();
Thread.sleep(3000);
2、通过id定位元素,较为常用的编写脚本的方式,有通用的缺点是开发增删控件需要重新维护脚本;
/*通过id定位元素*/
//点击按钮-登录框点击back
WebElement backItemBtn = driver.findElement(By.id("com.jollycorp.jollychic:id/tvBack"));
backItemBtn.click();
Thread.sleep(5000);
//首次打开关闭freegift弹框
WebElement freeItemBtn1 = driver.findElement(By.id("com.jollycorp.jollychic:id/iv_free_gift_close"));
freeItemBtn1.click();
Thread.sleep(5000);
WebElement searchBtn = driver.findElement(By.id("com.jollycorp.jollychic:id/tv_home_search_text"));
searchBtn.click();
Thread.sleep(5000);
//输入框输入内容
WebElement editText = driver.findElement(By.id("com.jollycorp.jollychic:id/etSearch"));
String itemText="dress";
editText.sendKeys(itemText);
Thread.sleep(3000);
3、通过className定位元素,适用于class里只有一个控件,通常与List遍历结合使用;
/*通过className定位*/
//点击按钮-登录框点击back
WebElement backItemBtn = driver.findElement(By.id("com.jollycorp.jollychic:id/tvBack"));
backItemBtn.click();
Thread.sleep(5000);
//首次打开关闭freegift弹框-两种写法
//WebElement freeItemBtn = driver.findElementByClassName("android.widget.ImageView");
WebElement freeItemBtn = driver.findElement(By.className("android.widget.ImageView"));
freeItemBtn.click();
Thread.sleep(5000);
4、通过List遍历class定位元素,有通用的缺点是开发修改class控件需要重新维护脚本;
/*通过className定位*/
//点击按钮-登录框点击skip
WebElement skipItemBtn = driver.findElement(By.id("com.jollycorp.jollychic:id/tvBack"));
skipItemBtn.click();
Thread.sleep(5000);
//首次打开关闭freegift弹框
List<WebElement> textFieldsList = driver.findElementsByClassName("android.widget.ImageView");
System.out.println(textFieldsList.size());
textFieldsList.get(0).click();
Thread.sleep(5000);
WebElement backItemBtn = driver.findElement(By.id("com.jollycorp.jollychic:id/tvTitleLeft"));
backItemBtn.click();
Thread.sleep(2000);
//循环打印class控件数
List<WebElement> wishItemBtnList = driver.findElementsByClassName("android.widget.TextView");
for(intk=0;k<wishItemBtnList.size();k++){
logger.info(wishItemBtnList.get(k).getText());
}
5、调用系统按键事件,通常用于快速调试脚本或者替代不好实现的控件操作;
/*调用系统按键事件*/
//点击按钮-登录框点击back
WebElement backItemBtn = driver.findElement(By.id("com.jollycorp.jollychic:id/tvBack"));
backItemBtn.click();
Thread.sleep(5000);
//首次打开关闭freegift弹框
WebElement freeItemBtn1 = driver.findElement(By.id("com.jollycorp.jollychic:id/iv_free_gift_close"));
freeItemBtn1.click();
Thread.sleep(3000);
WebElement searchBtn = driver.findElement(By.id("com.jollycorp.jollychic:id/tv_home_search_text"));
searchBtn.click();
Thread.sleep(3000);
//输入框输入内容
WebElement editText = driver.findElement(By.id("com.jollycorp.jollychic:id/etSearch"));
String itemText="dress";
editText.sendKeys(itemText);
Thread.sleep(5000);
//调用系统enter键开始搜索
driver.pressKeyCode(66);
Thread.sleep(3000);
//文本抓取ok点掉新手提示
driver.findElementByAndroidUIAutomator("new UiSelector().text(\"OK\")").click();
常用事件及参考附录如下,详细参考 http://www.jianshu.com/p/bfc978d52e76
KEYCODE_DPAD_UP导航键向上19
KEYCODE_DPAD_DOWN导航键向下20
KEYCODE_DPAD_LEFT导航键向左21
KEYCODE_DPAD_RIGHT导航键向右22
KEYCODE_PAGE_UP向上翻页键92
KEYCODE_PAGE_DOWN向下翻页键93
KEYCODE_BACK返回键4
KEYCODE_ENTER回车键66
6、通过xpath定位,优点是可以模糊匹配,有通用的缺点是开发修改class控件需要重新维护脚本;
//点击按钮-登录框点击skip
WebElement skipItemBtn = driver.findElement(By.id("com.jollycorp.jollychic:id/tvBack"));
skipItemBtn.click();
Thread.sleep(5000);
driver.findElementByXPath("//android.widget.TextView[contains(@text,'Cancel')]").click();
//driver.findElementByXPath("//android.widget.TextView[contains(@text,'Can')]").click();
还可用于判定控件是否存在,详细可参考http://www.cnblogs.com/paulwinflo/p/4738904.html;
List appiumItems = driver.findElementsByXPath("//android.widget.RelativeLayout[@text='Cancel']");
if(appiumItems.isEmpty()) {
System.out.println("is null");
}else{
System.out.println("is exist");
}
// Check if item is added
//List appiumItems =driver.findElementsByXPath("//android.widget.RelativeLayout[@text='Cancel']");
//Assert.assertEquals("is nul 'Cancel'", false,appiumItems.isEmpty());
7、通过获取控件value,来判定当前控件是否为选中状态
/**获取底下导航标签列表**/
List<String> elemnts =findElements(By.id("com.jollycorp.jollychic:id/fixed_bottom_navigation_icon"));
/**如果当前选中的不是Home标签则点击Home **/
if(!Boolean.TRUE.toString().equals(getValueInJsonObject(getAttribute(elemnts.get(i),Attribute.SELECTED.getName()),"value"))) {
click(elemnts.get(i));
}
8、findElemnt(By.id())方法
findElemnt(By.id("com.jollycorp.jollychic:id/tv_my_account_help_center"))
获取到结果:
{"status":0,"value":{"ELEMENT":"bf599629-49fa-43c6-be84-8043bdf63f15"}}
获取不到结果:
{"status":7,"value":"An element could not be located on the page using the given search parameters."}
例用方法:
if(!isElementPresent(findElemnt(By.id("com.jollycorp.jollychic:id/tv_my_account_help_center")))) {
slideScreen(1,Direction.UP.getName());
}
public static booleanisElementPresent(String elementResponse)throwsJSONException {
int status =newJSONObject(elementResponse).getInt("status");
return status ==0;
}
9、uiautomator2.0直接调用系统方法发post请求
public static voidpressBack() {
JSONObject jsonObject =newJSONObject();
jsonObject.put("command","input keyevent BACK");
post(UI2_SERVER_ADDR+"/exec",jsonObject.toString());
}
public static finalStringUI2_SERVER_ADDR="http://127.0.0.1:"+port+UI2_SERVER_PREFIX;
10、使用content找元素
click(findElemnt(By.xpath("//*[@content-desc='Cooperation']")));
11、xpath的一种用法
List list =findElements(By.id("sss"));
String text =getText(list.get(0));
findElemnt(By.xpath("//*[@text='"+text+"']"));