Giới thiệu một số cú pháp truy vấn của calabash

1. Tổng quan

Các API Calabash Android và API Calabash iOS cả hai đều có một phương thức truy vấn chọn một hoặc nhiều đối tượng có thể nhìn thấy trong màn hình hiện tại của ứng dụng. Các phương thức truy vấn có một đối số các chuỗi mô tả những đối tượng được "truy vấn".

Với iOS cú pháp cho các truy vấn dựa trên UIScript, nhưng nó là một thực hiện mới với các tính năng được bổ sung thêm vào (và một số đã được loại bỏ).

Truy vấn và UIScript cung cấp một bộ "CSS selector" để tìm các đối tượng trong màn hình ứng dụng.

  • **Ví dụ truy vấn trên android **

      krukow:~/tmp/android$ calabash-android console login.apk
      irb(main):001:0> start_test_server_in_background
      => nil
    
    irb(main):001:0> query("button")
    [{"id"=>"login_button",
      "enabled"=>true,
      "contentDescription"=>nil,
      "text"=>"Login",
      "qualified_class"=>"android.widget.Button",
      "frame"=>{"y"=>322, "height"=>73, "width"=>84, "x"=>135},
      "description"=>"[email protected]",
      "class"=>"Button"},

     {"id"=>"login_button_slow",
      "enabled"=>true,
      "contentDescription"=>nil,
      "text"=>"Login (slow)",
      "qualified_class"=>"android.widget.Button",
      "frame"=>{"y"=>322, "height"=>73, "width"=>143, "x"=>234},
      "description"=>"[email protected]",
      "class"=>"Button"}]

Bạn có thể thấy , truy vấn trả về một mảng các kết quả. Mỗi kết quả là một Hash đại diện cho một đối tượng.

- **Ví dụ truy vấn trên IOS**

        krukow:~/github/calabash-ios-example$ calabash-ios console
        irb(main):001:0> query("tabBarButton").count
        => 4

```XQuery

    irb(main):002:0> query("tabBarButton")[0]
    => {"class"=>"UITabBarButton",
        "frame"=>{"y"=>1, "width"=>76, "x"=>2, "height"=>48},
        "UIType"=>"UIControl",
        "description"=>"<UITabBarButton: 0x856a820; frame = (2 1; 76 48); opaque = NO; layer = <CALayer: 0x856d210>>"
        }

Một lần nữa,có thể thấy, truy vấn trả về một mảng các kết quả. Mỗi kết quả là một Hash đại diện cho một đối tượng.

Tuy nhiên, thông thường chúng ta quan tâm đến labels/ids của các đối tượng. Lệnh truy vấn thực sự có thể cần hai hoặc nhiều đối số: một query và selectors.

    irb(main):003:0> query "tabBarButton", :accessibilityLabel
    => ["First", "Second", "Third", "Fourth"]

2. Một số các cú pháp truy vấn

2.1 : ClassName - Tên lớp

Class Name tồn tại trên cả iOS và Android, nhưng nó có cách viết khác nhau trên mỗi nền tảng.

  • Android

Chọn đối tượng có một lớp riêng(hoặc là một sub-class của lớp đó). Để xác định một biểu thức Class Name,chỉ cần viết tên lớp đầy đủ của lớp đó.

    android.widget.Button

Cú pháp trên sẽ chọn ra tất cả những lớp android.widget.Button hoặc kế thừa từ android.widget.Button.

Có một hình thức đơn giản để xác định lớp. Ví dụ, nếu chỉ cần viết nút này phù hợp với tất cả các quan điểm trong đó có một lớp với tên đơn giản "button" (hoặc "Button"). Các tên đơn giản của một lớp là đoạn cuối cùng của tên lớp đầy đủ, ví dụ, cho android.widget.Button nó là Button.

  • IOS

Chọn đối tượng có một lớp riêng (hoặc là một sub-class của lớp đó). Để xác định một biểu thức Class Name, bạn viết

    view:'MyClass'

Cú pháp trên sẽ chọn ra tất cả những lớp MyClass hoặc kế thừa từ MyClass.

2.2: Direction - Phương hướng

  • Android Có bốn direction là con cháu(descendant), con(child), anh chị em(sibling), và cha mẹ(parent) .

Thông thường, các biểu thức truy vấn là một chuỗi các biểu thức ClassName. Ví dụ: "linearLayout editText"

Cú pháp có nghĩa là "đầu tiên tìm tất cả các linearLayouts, sau đó tìm tất cả các view có chứa EditText". Chìa khóa ở đây là từ bên trong. Điều này được xác định bởi hướng truy vấn. Mặc định direction là con cháu(descendant).

  • IOS

Có bốn direction là con cháu(descendant), con(child), anh chị em(sibling), và cha mẹ(parent) .

Thông thường, các biểu thức truy vấn là một chuỗi các biểu thức ClassName. Ví dụ:

    "tableViewCell label"

Cú pháp có nghĩa là "đầu tiên tìm thấy tất cả các UITableViewCell, sau đó tìm tất cả các view UILabel". Chìa khóa ở đây là từ bên trong. Điều này được xác định bởi hướng truy vấn.

Mặc định direction là con cháu(descendant) Nhưng có thể thay đổi direction. Dưới đây là một ví dụ :

    label marked:'Tears in Heaven' parent tableViewCell descendant tableViewCellReorderControl

Truy vấn này tìm thấy một label là "Tears in Heaven ', và sau đó tiến hành để tìm ra tableViewCell có chứa label này (tức là, tìm theo hướng cha mẹ sau đó tìm theo hướng con cháu ). Từ TableViewCell di chuyển xuống và tìm thấy tableViewCellReorderControl.

Hướng(Direction) hợp lệ là con cháu, cha mẹ, con và anh chị em. Cả con cháu và con sẽ tìm trong subviews của một view. Sự khác biệt là con cháu tiếp tục tìm kiếm xuống sub-view của các subviews, trong khi con chỉ tìm xuống level một. Các direction anh chị em tìm kiếm các view "cùng cấp".

2.3: Bộ lọc - Filtering

  • Android Chọn một bộ cài đặt nhỏ các view có thuộc tính nhất định (ví dụ, text hoặc id). Dạng tổng quát của một bộ lọc là:

      prop:val
    

prop là tên của một "thuộc tính" để được lọc, và val là một giá trị kiểu chuỗi, số nguyên hay boolean. Chuỗi được giới hạn bởi dấu ngoặc kép, ví dụ: 'Cell 2' là chuỗi "Cell 2". Bạn cũng có thể lọc bởi boolean bằng cách sử dụng đúng và sai.

Thông thường prop : val sẽ cố gắng gọi:

  • prop()
  • getProp()
  • isProp()

Nếu không có phương thức được tìm thấy, các đối tượng view là không có. Nếu một trong những phương thức được tìm thấy, nó được gọi và kết quả được so sánh với val. Nếu chúng là những giá trị giống nhau, view được tìm thấy

Một số tên có ý nghĩa đặc biệt.Như là marked, index và id được mô tả dưới đây.

marked

Bộ lọc đơn giản nhất và phổ biến nhất là marked.

    "button marked:'Login'"

Bộ lọc này lọc bằng id, nội dung mô tả ( contentDescription) hoặc text.

Ví dụ, đầu tiên tất cả các nút được tìm thấy. Sau đó, chỉ những nút có id, nội dung mô tả hoặc text bằng 'Login' được lựa chọn.

index

Bộ lọc bởi index

    "button index:0"

Trả về nút đầu tiên được tìm thấy. Chỉ nên sử dụng chỉ số trong một số trường hợp vì khi sử dụng nếu thay đổi giao diện thì kiểm thử thường hay bị sai.

id

Một cấu trúc đặc biệt hỗ trợ view bằng chuỗi id.

    "button id:'login_button'"

Có thể lọc bằng bất kỳ phương thức mà trả về một kết quả đơn giản như một số nguyên, chuỗi hoặc boolean.

    "button isEnabled:true"
  • IOS

Chọn một bộ cài đặt nhỏ các view có thuộc tính nhất định (ví dụ, text hoặc label). Dạng tổng quát của một bộ lọc là:

    prop:val

prop là tên của một bộ chọn Objective-C, và val là một giá trị kiểu chuỗi hay số nguyên. Chuỗi được giới hạn bởi dấu ngoặc kép. Cũng có thể lọc bởi booleans bằng cách sử dụng 1 cho đúng / YES và 0 cho false / NO.

Một số tên có ý nghĩa đặc biệt. Như là marked, index và indexPath chúng được giải thích dưới đây :

marked

Bộ lọc đơn giản nhất và phổ biến nhất là marked.

    "label marked:'Cell 8'"

Lọc bởi label hoặc id. Trong ví dụ, đầu tiên tất cả các view có UILabel được tìm thấy. Sau đó, chỉ những view có Label hoặc Id bằng 'Cell 8' được lựa chọn.

index

Lọc bằng index

    "label index:0"

Trả về UILabel đầu tiên được tìm thấy. Chỉ nên sử dụng chỉ số trong một số trường hợp vì khi sử dụng nếu thay đổi giao diện thì kiểm thử thường hay bị sai.

indexPath

Một cấu trúc đặc biệt có hỗ trợ việc lựa chọn các ô trong UITableViews bởi indexPath. Hình thức tổng quát là:

    "tableViewCell indexPath:row,sec"

row là một số mô tả hàng của cell, và sec là một số mô tả một phần của cell.

2.4: Predicate

iOS và Android

Calabash hỗ trợ một số bộ lọc mà không xuất hiện trong UIScript. Đặc biệt hỗ trợ lọc bởi Predicate. Ví dụ tìm kiếm một chuỗi tiền tố:

    "label {text BEGINSWITH 'Cell 1'}"

Trả lại các label với text Cell 1 và Cell 10.

Sử dụng một Predicate bằng cách viết một bộ lọc: {selector OP val}, trong đó selector là tên của một bộ chọn Objective-C để thực hiện trên đối tượng, OP là hoạt động, và val là một chuỗi hoặc giá trị nguyên.

Các hoạt động phổ biến

  • BEGINSWITH - tiền tố, ví dụ: "label {text BEGINSWITH 'Cell 1'}"
  • ENDSWITH - hậu tố, ví dụ: "label {text ENDSWITH '10'}"
  • LIKE - Tìm kiếm ký tự đại diện, ví dụ : "label {text LIKE 'C*ll'}"
  • CONTAINS - chuỗi, ví dụ : "label {text CONTAINS 'ell'}"
  • So sánh < , > , ...

2.5 : Hỗ trợ DOM/WebView

  • iOS và Android

Calabash Android hỗ trợ truy vấn và hành động theo nội dung webview.

Để nhìn vào một webview chỉ cần sử dụng các chức năng truy vấn và cú pháp.

Dưới đây là một số ví dụ:

  1. Truy vấn cho một phần tử với id, class hoặc tagname

        query("webView css:'#header'")
        query("webView css:'.js-current-repository'")
        query("webView css:'a'")

Các chuỗi sau css: có thể là bất kỳ css selector nào. 2. Lấy tất cả các HTML liên quan đến webview:

    query("webView css:'*'")

Lưu ý: truy vấn sẽ chỉ trả lại các nút DOM có thể nhìn thấy trên màn hình

2.6 : Touching - Chạm vào

  • iOS và Android

Bất cứ thứ gì bạn có thể truy vấn, bạn có thể chạm (nhưng phần tử phải được nhìn thấy trên màn hình ứng dụng).

    touch("webView css:'a'")

2.7 : Entering text - Nhập văn bản

  • Android Có ba phương thức có thể được sử dụng để nhập văn bản vào một UITextField hoặc một TextField / TextArea:

      enter_text "webView css:input.login", "ruk"
    

keyboard_enter_text - phương thức này sẽ nhập văn bản vào view đã được focus.

    keyboard_enter_text "ruk"

keyboard_enter_char - phương thức này sẽ nhập một ký tự đơn giản vào view đã được focus.

  • IOS

Đối với iOS, Nên chạm vào một input field để hiển thị bàn phím, và sử dụng keyboard_enter_char và keyboard_enter_text.

2.8 : Evaluating JavaScript - Đánh giá Javascript

  • iOS và Android

Có thể đánh giá JavaScript trong một web view:

js = 'document.body.innerHTML'
query("webView", :stringByEvaluatingJavaScriptFromString => js)

###2.9: Visibility - Mức độ hiển thị

  • iOS và Android

Theo mặc định Calabash sẽ chỉ truy vấn các phần tử nhìn thấy được. Nếu muốn thay đổi hành vi để truy vấn tất cả các phần tử bạn chỉ cần thêm vào từ all.

    query("all button")
    query("all view marked:'something'")

Trên đây là một số cú pháp được dùng khi truy vấn để thực hiện việc viết kiêm thử tự động bằng calabash trên Android và IOS . Bạn có thể tham khảo thêm một số hàm truy vấn ở đây http://calabashapi.xamarin.com/ios/Calabash/Cucumber.html