How to use selector expression in Shirates
Tags: appium, android, ios, testautomation
Published: 2022-10-15 20:16:35

This article is an introduction of how to use [Shirates](https://dev.to/wave1008/introducing-shirates-a-mobile-testing-automation-tool-3nmc), a mobile testing automation tool.

# 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**.


![Example](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cglnw8i7lgmvnbs7iv9o.png)



## Filter expression

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

| filter           | formal                    | abbreviation | Android attribute | iOS attribute |
|:-----------------|:--------------------------|:-------------|:------------------|:--------------|
| 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          |
| 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           |
| visible          | visible=true              | n/a          | n/a               | visible       |
| 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           |


## For more information
See [Selector expression](https://github.com/ldi-github/shirates-core/blob/main/doc/markdown/basic/selector_and_nickname/selector_expression.md)

## Material
You can get complete sample project from [https://github.com/wave1008/shirates-samples-selectors].

### SelectTest2
```kotlin
import org.junit.jupiter.api.Order
import org.junit.jupiter.api.Test
import shirates.core.driver.branchextension.emulator
import shirates.core.driver.branchextension.realDevice
import shirates.core.driver.commandextension.*
import shirates.core.testcode.UITest

class SelectTest2 : UITest() {

    @Test
    @Order(10)
    fun selectByText() {

        scenario {
            case(1) {
                condition {
                    it.restartApp()
                }.action {
                    it.select("Network & internet")
                }.expectation {
                    it.textIs("Network & internet")
                }
            }
            case(2) {
                action {
                    it.select("Network &*")
                }.expectation {
                    it.textIs("Network & internet")
                }
            }
            case(3) {
                action {
                    it.select("*internet")
                }.expectation {
                    it.textIs("Network & internet")
                }
            }
            case(4) {
                action {
                    it.select("textMatches=^Network & internet$")
                }.expectation {
                    it.textIs("Network & internet")
                }
            }
            case(5) {
                action {
                    it.selectWithScrollDown("About phone||About emulated device")
                }.expectation {
                    realDevice {
                        it.textIs("About phone")
                    }.emulator {
                        it.textIs("About emulated device")
                    }
                }
            }
        }
    }

    @Test
    @Order(20)
    fun selectById() {

        scenario {
            case(1) {
                condition {
                    it.restartApp()
                }.action {
                    it.select("#search_action_bar_title")
                }.expectation {
                    it.textIs("Search settings")
                }
            }
        }
    }

    @Test
    @Order(30)
    fun selectByAccessibility() {

        scenario {
            case(1) {
                condition {
                    it.restartApp()
                        .tap("Network & internet")
                }.action {
                    it.select("@Network & internet")
                }.expectation {
                    it.idIs("collapsing_toolbar")
                }
            }
        }
    }

    @Test
    @Order(40)
    fun selectByClass() {

        scenario {
            case(1) {
                condition {
                    it.restartApp()
                }.action {
                    it.select(".android.widget.ImageButton")
                }.expectation {
                    it.classIs("android.widget.ImageButton")
                }
            }
        }
    }

    @Test
    @Order(50)
    fun selectByXpath() {

        scenario {
            case(1) {
                condition {
                    it.restartApp()
                }.action {
                    it.select("xpath=//*[@text='Search settings']")
                }.expectation {
                    it.textIs("Search settings")
                }
            }
        }
    }

    @Test
    @Order(60)
    fun selectByPos() {

        scenario {
            case(1) {
                condition {
                    it.restartApp()
                        .tap("Battery")
                }.action {
                    it.select("*Battery*&&[1]")
                }.expectation {
                    it.textIs("Battery Usage")
                }
            }
            case(2) {
                action {
                    it.select("*Battery*&&[2]")
                }.expectation {
                    it.textIs("Battery Saver")
                }
            }
            case(3) {
                action {
                    it.select("*Battery*&&[3]")
                }.expectation {
                    it.textIs("Battery percentage")
                }
            }
        }
    }

}
```

### Test Result


![Result1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hukrvkmdrkt9qee314rq.png)

![Result2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rl8qco60mgx9xsdvf61j.png)

---

## Conclusion
Shirates **Selector expression** is simple yet powerful expression for retrieving an element on the screen, as flexible as XPath, but much easier than XPath.