2013-07-01 36 views
5

Tôi có tập lệnh sau để nhập '33' vào Máy tính, trong Android, sử dụng UiAutomator. Tuy nhiên, chỉ chấp nhận '3' đầu tiên, báo chí thứ hai hoàn toàn bị bỏ qua.Làm thế nào để nhấn một nút hai lần bằng cách sử dụng Google UiAutomator?

import com.android.uiautomator.core.*; 
import com.android.uiautomator.testrunner.UiAutomatorTestCase; 

public class MyFirstUiAutomatorTest extends UiAutomatorTestCase { 
    UiObject getByDescription(String description) { 
     return new UiObject(new UiSelector().description(description)); 
    } 

    UiObject getByText(String description) { 
     return new UiObject(new UiSelector().text(description)); 
    } 

    UiObject scrollableGetByText(String text) throws UiObjectNotFoundException { 
      UiScrollable uiScrollable = new UiScrollable(new UiSelector().scrollable(true)); 
      uiScrollable.setAsHorizontalList(); 
      return uiScrollable.getChildByText(new UiSelector().className(
        android.widget.TextView.class.getName()), 
        text);  
    } 

    public void testStuff() throws UiObjectNotFoundException { 
     getUiDevice().pressHome(); 
     getByDescription("Apps").clickAndWaitForNewWindow(); 
     getByText("Apps").click(); 
     scrollableGetByText("Calculator").clickAndWaitForNewWindow(); 

     // pressing '+' and '=' effectively clears the previous input 
     getByText("+").click(); 
     getByText("=").click(); 
     getByText("3").click(); 
     // this second '3' is ignored 
     getByText("3").click(); 
    } 
} 

Tôi đã thử thêm một giấc ngủ trong 2 giây sau khi nhấp chuột đầu tiên, bằng cách thực hiện:

 try { 
      Thread.sleep(2000); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 

... nhưng điều đó không thay đổi bất cứ điều gì.

Tôi cũng cố gắng nhấp chuột vào một nút khác nhau, ở giữa 2 '3 của, ví dụ:

 new UiObject(new UiSelector().text("3")).click(); 
     new UiObject(new UiSelector().className("android.widget.EditText")).click(); 
     new UiObject(new UiSelector().text("3")).click(); 

... nhưng điều đó không làm việc, hoặc.

Ý tưởng?

(Lưu ý: sử dụng Android 4.1.2, trong một AVD; chạy trên Ubuntu Linux 12.04)

Edit, sau quan sát Rami, tôi thử như sau, để tái sử dụng các đối tượng UiObject cùng cho một yêu cầu thứ hai cho cùng mô tả:

HashMap<String,UiObject> objectByText = new HashMap<String,UiObject>(); 
UiObject getByText(String description) { 
    if(objectByText.containsKey(description)) { 
     System.out.println("" + objectByText.get(description)); 
     return objectByText.get(description); 
    } 
    System.out.println("Created new object for [" + description + "]"); 
    UiObject object = new UiObject(new UiSelector().text(description)); 
    objectByText.put(description, object); 
    System.out.println("" + object); 
    return object; 
} 

... nhưng nó đã không làm việc, mặc dù nó được tái sử dụng rõ ràng cùng UiObject mỗi lần, vì nó chỉ nói 'tạo đối tượng mới cho [3]' một lần.

Sau đó, tôi đã cố gắng UiDevice.click() 'lừa', bằng cách tạo ra một chức năng nghe tiếng 'click' như sau, một lần nữa, sau những quan sát Rami của:

void click(UiObject target) throws UiObjectNotFoundException { 
    Rect rect = target.getBounds(); 
    System.out.println("rect: " + rect); 
    getUiDevice().click(rect.centerX(), rect.centerY()); 
} 

Tuy nhiên, điều này không làm việc cho tôi, hoặc : chỉ lần đầu tiên '3' xuất hiện và thứ hai bị bỏ qua, mặc dù cả hai lần nhấp đều rõ ràng ở cùng một vị trí, bởi vì các vị trí đầu ra rect: giống hệt nhau. Nếu tôi nhấp vào '3' hai lần theo cách thủ công, sử dụng chuột trên máy tính để bàn của riêng tôi, thì cả 3 đều xuất hiện ok.

Tôi cũng đã thử thêm hai giây Thread.sleep() giữa các lần nhấp và vẫn chỉ xuất hiện một '3' duy nhất cho tôi.

Trả lời

1

Tôi gặp vấn đề tương tự, có vẻ như nó đang tìm kiếm một phần tử giao diện người dùng khác có cùng nội dung. Tôi đang cố gắng để tự động hóa việc tạo ra một báo động nhưng khi thời gian là ở ví dụ 4:45 pm. Uiautomator sẽ nhấp vào nút bên phải.

clickByText("4"); 
clickByText("4"); 
clickByText("5"); 
clickByText("PM"); 
clickByText("OK"); 

private void clickByText(String text) throws UiObjectNotFoundException { 
      UiObject obj = new UiObject(new UiSelector().text(text)); 
      obj.click(); 
    } 

Đây là Log cho là người đầu tiên "4" click:

07-04 16: 54: 05,259: I/QueryController (25.605): chọn đối sánh: UiSelector [ TEXT = 4] < < == >> [[email protected]; boundsInParent: Rect (0, 0 - 202, 129); boundsInScreen: Rect (56, 508 - 258, 637); packageName: com.android.deskclock; className: android.widget.Nút; văn bản: 4; contentDescription: null; có thể kiểm tra: sai; checked: false; focusable: true; tập trung: sai; được chọn: sai; có thể nhấp: true; longClickable: false; enabled: true; mật khẩu: sai; có thể cuộn: sai; [ACTION_FOCUS, ACTION_SELECT, ACTION_CLEAR_SELECTION, ACTION_CLICK, ACTION_ACCESSIBILITY_FOCUS, ACTION_NEXT_AT_MOVEMENT_GRANULARITY, ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY]]

Đây là Log cho phần thứ hai "4" click:

07-04 16: 54: 07.798: I/QueryController (25605): Bộ chọn được đối sánh: UiSelector [TEXT = 4] < < == >> [android.view.accessibility.Access ibilityNodeInfo @ 5bffd; boundsInParent: Rect (0, 0 - 66, 90); boundsInScreen: Rect (191, 264 - 257, 354); packageName: com.android.deskclock; className: android.widget.TextView; văn bản: 4; contentDescription: null; có thể kiểm tra: sai; checked: false; focusable: false; tập trung: sai; được chọn: sai; có thể nhấp: sai; longClickable: false; được bật: đúng; mật khẩu: sai; có thể cuộn: sai; [ACTION_SELECT, ACTION_CLEAR_SELECTION, ACTION_ACCESSIBILITY_FOCUS, ACTION_NEXT_AT_MOVEMENT_GRANULARITY, ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY]]

Chúng ta có thể thấy rằng một là nhấn vào android.widget.Button đúng và lần thứ hai vào tìm kiếm của mình cho android.widget.TextView.

2

Tôi đã tìm thấy một hack nhỏ để giải quyết vấn đề này ngay bây giờ. có được ranh giới mọi lúc bạn chạy thử nghiệm để thiết bị của nó không tập trung và sẽ thích ứng khi đang bay.

UiObject obj1 = new UiObject(new UiSelector().text("4")); 

    Rect four = obj1.getBounds(); 

    getUiDevice().click(four.centerX(), four.centerY()); 
+0

này nghe có vẻ giống như một cách giải quyết tuyệt vời, nhưng tôi đã thử nó ngay bây giờ, và nó không làm việc cho tôi. Nếu tôi nhấp vào nút '3' theo cách thủ công hai lần, thì tôi thấy '33', nhưng nếu tôi sử dụng UiAutomator để sử dụng 'getUiDevice(). Click()' để nhấp hai lần vào cùng một vị trí, thì tôi vẫn chỉ thấy một ' 3 '. Điều này, ngay cả khi tôi thêm 'Thread.sleep (2000)' vào giữa hai lần nhấp chuột. –

+0

Tôi đã tạo một phương thức gọi là 'setUpDigit()' trong đó tôi thiết lập UIobject 'UiObject zero = new UiObject (new UiSelector(). Văn bản (" 0 "));' và tôi có một giá trị toàn cục Rzero được thiết lập trong cùng phương thức setUpDigit() 'Rzero = zero.getBounds();' Sau đó, tôi có một công tắc sẽ sử dụng giá trị toàn cục Rzero và nhấn vào nút bên phải 'getUiDevice(). click (Rzero.centerX(), Rzero.centerY()); 'Phần khó khăn là khi gọi setUpDigit(). Nó cần phải được gọi khi bạn có máy tính hoặc cho tôi tạo ra báo động trên màn hình. –

4

Thay vì chỉ tìm kiếm bằng văn bản, hãy thử tìm kiếm theo văn bản và lớp học. Đây là một phương pháp mẫu để làm như vậy.

Uiobject getByTextAndClass(String text, String className) { 
    return new UiObject(new UiSelector().text(text).className(className)); 
} 

Và sau đó nếu bạn đang cố gắng gọi phương pháp này cho nút Calculator với số 3 trên nó:

getByTextAndClass("3", android.widget.Button.class.getName()).click(); 

Bạn có thể sử dụng công cụ UiAutomatorViewer: {android-sdk}/tools/uiautomator .bat để kiểm tra tên lớp và các thuộc tính khác của các UiObject khác nhau.

Tính năng này hoạt động trên thiết bị 4.2.2 của tôi, nhưng tôi đang tải xuống 4.1.2 để thử nghiệm trên đó.

Tôi đã thử nó trên 4.1.2 AVD và nó hoạt động trên máy tính Windows của tôi.

2

Sự cố này dường như được xây dựng theo cách UiObject được thiết lập. Theo như tôi có thể nói, một thể hiện của UiObject dường như không đề cập đến một đối tượng cụ thể trên màn hình. Nó giống như một thể hiện của những gì được chỉ ra bởi UiSelector khi UiObject được định nghĩa. Chìa khóa ở đây là mỗi khi đối tượng được gọi, nó tìm kiếm một mục mới phù hợp với yêu cầu UiSelector.

Bằng chứng:

UiObject ok = new UiObject(new UiSelector().text("OK")); 
ok.click(); 
// clicks a button with the text ok on the page 
// Navigate to some different page with a button with the text ok 
ok.click(); 
// this ok button on a completely different page is still clicked 

Vì vậy, tôi nghĩ rằng workaround Rami của có thể thực sự bởi cách chính xác để làm điều đó (lưu trữ vị trí của đối tượng thông qua tọa độ của nó và click vào trung tâm của vị trí đó). Điều quan trọng cần lưu ý về cách giải quyết của Rami, lưu tọa độ/hình chữ nhật một lần và sau đó tái sử dụng tọa độ/hình chữ nhật bất cứ khi nào bạn muốn tham chiếu đến đối tượng. Sử dụng obj.getBounds() nhiều lần trên cùng một đối tượng dường như không hoạt động.

Ngoài ra, các bản ghi của các mục đã được chuyển qua trong quá trình diễn giải UiObject dường như được lưu trữ trong ứng dụng. Chạy kiểm tra hai lần tìm thấy UiObject (ví dụ: nút 4 trong trang báo thức đã đặt) và nhấp chuột không thành công giống như kiểm tra tìm UiObject và nhấp vào hai lần. Điều này có nghĩa là dữ liệu của các truy vấn đối tượng phải được lưu trữ trên thiết bị vì việc đặt lại UIautomator không tạo ra sự khác biệt nào.

0

Tạo một UiObject cho 3 nút bấm và twice.below là đoạn

UiObject three = new UiObject(new UiSelector().text("3")); 
three.click(); 
three.click(); 
Các vấn đề liên quan