Scanning Individual Compose Elements using Test Tags

Link to Scanning Individual Compose Elements using Test Tags copied to clipboard

Test Tags are provided by Jetpack Compose to attach a unique identifier to a composable. The testTag string can be passed to the axe-devtools-android library to scan that specific compose element. This example highlights the use of the setTestTag(params) API available in axe DevTools Mobile with Compose. When utilizing the AxeDevToolsCompose object in UITests with the setTestTag API, the compose element with the marked test tag string can be tested. The setTestTag API can also be used when the No View initialized, did you call AxeDevToolsCompose.setComposeTestRule()? error is encountered while scanning.

Quick links:

Below is an example of the AxeDevToolsCompose object in an Espresso test when utilizing the setTestTag API.

Complete Example

Set the test tag of the composable to be tested.

@Composable
fun AlertBox() {
   val openDialog = remember { mutableStateOf(true)  }
   AlertDialog(
       modifier = Modifier.semantics { testTag = "customDialog" },
       onDismissRequest = {
           openDialog.value = false
       },
       title = {
           Text(text = "Dialog Title Will Show Here")
       },
       text = {
           Text("Here is a description text of the dialog")
       }, ...
   )
}

Use the same test tag string to scan the compose element.

@RunWith(AndroidJUnit4::class)
class EmptyComposeRuleAPITest {
    @get:Rule
    val composeEmptyTestRule = createEmptyComposeRule()

    private lateinit var activity: ComponentActivity

    lateinit var scenario: ActivityScenario<ComponentActivity>

    companion object {
        val axe = AxeDevToolsCompose()

        init {
            axe.loginWithApiKey(
                "YOUR_API_KEY_HERE"
            )
        }
    }

    @Before
    fun setup() {
        scenario = ActivityScenario.launch(ComponentActivity::class.java)
        scenario.onActivity { activity ->
            this.activity = activity
            activity.setContent {
                AlertBox()
            }   
        }
        composeEmptyTestRule.mainClock.autoAdvance = false
        composeEmptyTestRule.waitForIdle()
    }

    @Test
    fun doGenericScan() {
        axe.setEmptyComposeTestRule(composeEmptyTestRule, activity)
        axe.setTestTag("customDialog")

        axe.scan()?.uploadToDashboard()
    }

}