Selector expression

Shirates Selector expression is expression to filter screen elements.

select function accepts selector expressions, parses them, retrieves and filters elements, and returns result element.

Selector expression consists of one or more filter expressions.

it.select("#id1")    // id filter

it.select("@accessibility1") // accessibility filter

it.select(".android.widget.ImageButton")    // class filter

it.select("text1")  // text filter

it.select("xpath=//*[@resource-id='android:id/icon']")  // xpath filter

it.select("Hello&&.android.widget.TextView")    // text filter and class filter combined with "&&"(and) operator

it.select("About phone||About emulated device") // text filters combined with "||"(or) operator

Filter expression

Shirates Filter expression is expression describing conditions to filter screen elements.

filter formal abbreviation Android attribute iOS attribute remarks
text text=text1 text1 text label
textStartsWith textStartsWith=text1 text1* text label
textContains textContains=text1 *text1* text label
textEndsWith textEndsWith=text1 *text1 text label
textMatches textMatches=^text$ n/a text label
literal literal=literal1 ‘literal1’ text label
id id=id1 #id1 resource-id name
idStartsWith idStartsWith=id1 #id1* resource-id name
idContains idContains=id1 #*id1* resource-id name
idEndsWith idEndsWith=id1 #*id1 resource-id name
idMatches idMatches=^id1$ n/a resource-id name
access access=access1 @access1 content-desc name
accessStartsWith accessStartsWith=access1 @access1* content-desc name
accessContains accessContains=access1 @*access1* content-desc name
accessEndsWith accessEndsWith=access1 @*access1 content-desc name
accessMatches accessMatches=^access1$ n/a content-desc name
value value=value1 n/a text value
valueStartsWith valueStartsWith=value1 n/a text value
valueContains valueContains=value1 n/a text value
valueEndsWith valueEndsWith=value1 n/a text value
valueMatches valueMatches=^value1$ n/a text value
class class=class1 .class1 class type
focusable focusable=true n/a focusable n/a
scrollable scrollable=true n/a scrollable n/a
selected selected=true n/a selected n/a
visible visible=true n/a n/a visible deprecated
xpath xpath=//*[@text=‘text1’] n/a (arbitrary) (arbitrary)
pos pos=2 [2] n/a n/a
ignoreTypes ignoreTypes=Class1,Class2 n/a class type
image image=image1.png image1.png n/a n/a
capturable capturable=?? ?? n/a n/a

Note: The visibility attribute in iOS is deprecated because it cannot be used to determine whether an element is visible on the screen.

Multiple values in filter

Filter accepts multiple values using parentheses and “|”(or) operator.

it.select("text=(text1|text2)") // formal

it.select("(text1|text2)")  // abbreviation

The below selector expression is simple and equivalent to above.

it.select("text1||text2")   // equivalent selector expression

In this case, the result is the same whether the or expression by filter or by selector is used.

In more complex situation, “|” may be needed.

it.select("(text1|text2)&&.class1||(@access1|@access2)&&.class2)")

Rules of selector expression

A filter expression can be used alone as a selector expression.

text1

Filter expression can be combined with “&&”(AND) operator.

text1&&.class1&&visible=true

Filter expressions can be combined with “||”(OR) operator.

text1||text2||@access1

“&&” is prior to “||”

text1&&.class1||@access1

The above means (text=text1 and class=class1) or access=access1, but do not specify parenthesis like below (not supported).

Bad example

(text1&&.class1)||@access1

Fully qualified id

In android resource-id has prefix that corresponds to the app package name. For example, “com.android.settings” is package name of Settings app.

fully qualified abbreviated
com.android.settings:id/search_bar search_bar

In Shirates, abbreviated id is recommended to use because it is converted to fully qualified id automatically, and it is easy to read. In case of failing, try fully qualified id explicitly.

Platform annotation for selector expression

You can use platform annotation(@a, @i) to write selector expression for Android and for iOS in one line.

@a<.android.widget.ImageButton>,@i<.XCUIElementTypeButton>
it.select("@a<.android.widget.ImageButton>,@i<.XCUIElementTypeButton>")

With this annotation, a nickname can be defined for Android and iOS.

"[Button1]": "@a<.android.widget.ImageButton>,@i<.XCUIElementTypeButton>"

Negative filter

In some complex situation you can use negative filter.

text=text1      // positive
text!=text1     // negative

text1       // positive
!text1      // negative

accessContains=text1    // positive
accessContains!=text1   // negative

@*text1*    // positive
!@*text1*   // negative

Image filter

You can use image file for image matching(template matching). See Image assertion

image=image1.png    // formal
image1.png          // abbreviation
image1.png?scale=0.5&threshold=20   // with option(formal)
image1.png?s=0.5&t=20   // with option(abbreviation)

Capturable filter (Meta Filter)

Depending on the implementation of the app, it may not be possible to retrieve the corresponding element even though it is displayed on the screen. For example, an element corresponding to an image displayed on the screen can be captured on Android, but not on iOS. In this case, a capturable filter can be used to explicitly state that the element cannot be captured on iOS.

it.existImage("@a<.android.widget.ImageButton>,@i<??>")

In this example, on Android, the element is searched with .android.widget.ImageButton and matched with an image template, On iOS, element search and image matching are not performed, and the result of verification is COND_AUTO, which indicates that manual testing is required.

Link