1. 程式人生 > >appium定位元素java篇

appium定位元素java篇

1、關於沒有name,沒有ID的元素的定位---通用篇
解題思路:
因為沒有name,id;其實剩下的選擇已不多,要麼xpath,要麼className。xpath木有好印象(穩定性不高,加之1.0x後需要寫全路徑,相當崩潰),我決定十分個人色彩的建議使用className。
具體方法:
用className獲取所有該型別的元素;
根據元素的位置確定元素的index;
獲取目標元素。
示例:
List<WebElement> lis = driver.findElementsByClassName("android.widget.ImageView");//獲取ImageView的所有元素
WebEelement targetEle = lis.get(0);//獲取列表中第一個元素

進階:
你可以自己定義一個className的常量,然後封裝個方法,提供大家使用:
public List<WebElement> getAllImges(){
List<WebElement> lis = driver.findElementsByClassName(AndroidClassName.IMAGEVIEW);
return lis;
}
使用的時候,就只需要呼叫此方法就可以了

此方法的好處:通吃的方法,基本可解決定位的問題;能解決多語言(自然語言)的困擾;
缺點:因為系統需要去獲取List,就目前來看,執行效率不是很高,那直接是可以用肉眼看的到的速度在跑。。。

2、關於沒有name,沒有ID的元素的定位---特用篇
因為是特用,所以需要對頁面元素做進一步的分析,找出其中的特性。這些特性主要為className,index,以及clickable等屬性。
場景1:同一個頁面有10個ImageView物件,而我們的目標元素的index為4,而同為ImageView且index為4的頁面只有2個。那我們就可以根據這2個條件來組合查詢條件,提高效率。
示例:
List<WebElement> lis = driver.findElementsByAndroidUIAutomator("new UiSelector().className("+"android.widget.ImageView"+").index(4)");
基於這個場景可以封裝一個方法:
public List<WebElement> getElementsByClassAndIndex(String classname,int index){
List<WebElement> lis =null;
lis = driver.findElementsByAndroidUIAutomator("new UiSelector().className("+classname+").index("+index+")");
return lis;
}

場景2:同一個頁面有10個ImageView物件,而其中index為4的有5個,而這時我們發現我們的目標元素的是clickable的。然後review頁面發現,同時滿足上述條件的只有2個。那麼。。。
示例:
List<WebElement> lis = driver.findElementsByAndroidUIAutomator("new UiSelector().className("+"android.widget.ImageView"+").index(4).clickable(true)");
同樣可以封裝一個方法:
public List<WebElement> getElementsByClassAndIndexAndClickable(String classname,int index){
List<WebElement> lis =null;
lis = driver.findElementsByAndroidUIAutomator("new UiSelector().className("+classname+").index("+index+").clickable(true)");
return lis;
}

場景3:在分析頁面元素的時候發現,頁面相對比較簡單,而且其中只有目標元素的index為4.
示例:
driver.findElementByAndroidUIAutomator("new UiSelector().index("+index+")");
同樣得到一個方法
public WebElement getElementByIndex(int index){
return driver.findElementByAndroidUIAutomator("new UiSelector().index("+index+")");
}

3、關於輸入框有預設text,且當你選中時,不會清空的清空的處理。
類似的情況,用element.clear()是沒有效果的。那怎麼辦呢? 不急,appium提供了很多的操作,直擊不行,我們就上組合拳。
示例:
public void clear(WebElement el){
el.click(); //選中輸入框
driver.sendKeyEvent(123);//將游標移到最後
String txt = el.getText(); //獲取字串長度
for(int i=0;i<txt.length();i++){
driver.sendKeyEvent(67);//一個個的刪除。。。。。
}
}

4、關於UiAutomator無法識別的元素
整體思路:不要忘了咱的手機是可以點選的。
獲取相對座標,點選,就這麼簡單。(不用絕對座標是保證程式能在不同的解析度下執行)
下面一起討論下相對座標的獲取:找一個頁面,這個頁面上有相關的元素的位置與目標位置類似,或者根據這些元素能獲取到目標的大致位置。
上段程式碼,幫助理解:
public List<Point> getFileMngPoint(){
List<Point> list = new ArrayList<Point>();
WebElement scrol = driver.findElementByClassName(AndroidClassName.HORIZONTALSCROLL);
List<WebElement> imgs = scrol.findElements(By.className(AndroidClassName.IMAGEVIEW));
//以上僅獲取類似位置的元素
Point e0 = getCenterPoint(imgs.get(0));
Point e1 = getCenterPoint(imgs.get(1), imgs.get(2));
Point e2 = getCenterPoint(imgs.get(3));
Point e4 = getCenterPoint(imgs.get(2),imgs.get(3));
Point e5 = getCenterPoint(getElementsByClassAndIndexAndClickable(AndroidClassName.IMAGEVIEW, 0).get(4));
//以上獲取元素的中心座標,相關方法是自己寫的
list.add(e0);
list.add(e1);
list.add(e2);
list.add(e4);
list.add(e5);

return list;
}

轉自 :http://blog.csdn.net/today520/article/details/37815087