# AndroidComposeTestRule

Artifact: [androidx.compose.ui:ui-test-junit4](https://developer.android.com/jetpack/androidx/releases/compose-ui) [View Source](https://cs.android.com/search?q=file:androidx/compose/ui/test/junit4/AndroidComposeTestRule.android.kt+class:androidx.compose.ui.test.junit4.AndroidComposeTestRule) Added in [1.0.0](https://developer.android.com/jetpack/androidx/releases/compose-ui#1.0.0) Android/JVM
- android

  ```
  class AndroidComposeTestRule<R : TestRule, A : ComponentActivity> : ComposeContentTestRule
  ```

*** ** * ** ***

## Summary

| ### Nested types |
|---|
| `inner class https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/AndroidComposeTestRule.AndroidComposeStatement : https://junit.org/junit4/javadoc/latest/org/junit/runners/model/Statement.html` **This class is deprecated.** Do not instantiate this Statement, use AndroidComposeTestRule instead |

| ### Public constructors |
|---|---|
| `<R : https://junit.org/junit4/javadoc/latest/org/junit/rules/TestRule.html, A : https://developer.android.com/reference/kotlin/androidx/activity/ComponentActivity> [AndroidComposeTestRule](https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/AndroidComposeTestRule#AndroidComposeTestRule(org.junit.rules.TestRule,kotlin.Function1))( activityRule: R, activityProvider: (R) -> A )` **This function is deprecated.** Use \`androidx.compose.ui.test.junit4.v2.AndroidComposeTestRule\` instead. | android |
| `<R : https://junit.org/junit4/javadoc/latest/org/junit/rules/TestRule.html, A : https://developer.android.com/reference/kotlin/androidx/activity/ComponentActivity> [AndroidComposeTestRule](https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/AndroidComposeTestRule#AndroidComposeTestRule(org.junit.rules.TestRule,kotlin.coroutines.CoroutineContext,kotlin.Function1))( activityRule: R, effectContext: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.coroutines/-coroutine-context/index.html, activityProvider: (R) -> A )` **This function is deprecated.** Use \`androidx.compose.ui.test.junit4.v2.AndroidComposeTestRule\` instead. | android |

| ### Public functions |
|---|---|---|
| `open https://junit.org/junit4/javadoc/latest/org/junit/runners/model/Statement.html` | `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/AndroidComposeTestRule#apply(org.junit.runners.model.Statement,org.junit.runner.Description)(base: https://junit.org/junit4/javadoc/latest/org/junit/runners/model/Statement.html, description: https://junit.org/junit4/javadoc/latest/org/junit/runner/Description.html)` | android |
| `open suspend https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/AndroidComposeTestRule#awaitIdle()()` Suspends until the UI is idle. | android |
| `https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/AndroidComposeTestRule#cancelAndRecreateRecomposer()()` Cancels AndroidComposeUiTestEnvironment's current Recomposer and creates a new one. | android |
| `open https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-boolean/index.html` | `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/AndroidComposeTestRule#hasPendingWork()()` Returns whether the Compose UI has any pending work. | android |
| `open https://developer.android.com/reference/kotlin/androidx/compose/ui/test/SemanticsNodeInteractionCollection` | `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/AndroidComposeTestRule#onAllNodes(androidx.compose.ui.test.SemanticsMatcher,kotlin.Boolean)(matcher: https://developer.android.com/reference/kotlin/androidx/compose/ui/test/SemanticsMatcher, useUnmergedTree: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-boolean/index.html)` Finds all semantics nodes that match the given condition. | android |
| `open https://developer.android.com/reference/kotlin/androidx/compose/ui/test/SemanticsNodeInteraction` | `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/AndroidComposeTestRule#onNode(androidx.compose.ui.test.SemanticsMatcher,kotlin.Boolean)(matcher: https://developer.android.com/reference/kotlin/androidx/compose/ui/test/SemanticsMatcher, useUnmergedTree: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-boolean/index.html)` Finds a semantics node that matches the given condition. | android |
| `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/SemanticsNodeInteractionsProvider` | `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/AndroidComposeTestRule#onRootWithViewInteraction(androidx.test.espresso.ViewInteraction)(interaction: https://developer.android.com/reference/kotlin/androidx/test/espresso/ViewInteraction)` Scopes the Compose interaction to the View hierarchy matched by the provided Espresso `https://developer.android.com/reference/kotlin/androidx/test/espresso/ViewInteraction`. | android |
| `open https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/AndroidComposeTestRule#registerIdlingResource(androidx.compose.ui.test.IdlingResource)(idlingResource: https://developer.android.com/reference/kotlin/androidx/compose/ui/test/IdlingResource)` Registers an `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/IdlingResource` in this test. | android |
| `open T` | `<T : https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-any/index.html?> https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/AndroidComposeTestRule#runOnIdle(kotlin.Function0)(action: () -> T)` Executes the given `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/ComposeTestRule#runOnIdle(kotlin.Function0)` in the same way as `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/ComposeTestRule#runOnUiThread(kotlin.Function0)` but `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/ComposeTestRule#waitForIdle()` until the app is idle before executing the action. | android |
| `open T` | `<T : https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-any/index.html?> https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/AndroidComposeTestRule#runOnUiThread(kotlin.Function0)(action: () -> T)` Runs the given `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/ComposeTestRule#runOnUiThread(kotlin.Function0)` on the UI thread. | android |
| `open T` | `<T : https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-any/index.html?> https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/AndroidComposeTestRule#runWithoutImplicitWait(kotlin.Function0)(block: () -> T)` Executes the given `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/ComposeTestRule#runWithoutImplicitWait(kotlin.Function0)` with implicit synchronization suppressed. | android |
| `open https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/AndroidComposeTestRule#setContent(kotlin.Function0)(composable: @https://developer.android.com/reference/kotlin/androidx/compose/runtime/Composable () -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html)` Sets the given composable as a content of the current screen. | android |
| `open https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/AndroidComposeTestRule#unregisterIdlingResource(androidx.compose.ui.test.IdlingResource)(idlingResource: https://developer.android.com/reference/kotlin/androidx/compose/ui/test/IdlingResource)` Unregisters an `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/IdlingResource` from this test. | android |
| `open https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/AndroidComposeTestRule#waitForIdle()()` Waits for the UI to become idle. | android |
| `open https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/AndroidComposeTestRule#waitUntil(kotlin.Long,kotlin.Function0)(timeoutMillis: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-long/index.html, condition: () -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-boolean/index.html)` Blocks until the given `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/ComposeTestRule#waitUntil(kotlin.Long,kotlin.Function0)` is satisfied. | android |
| `open https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/AndroidComposeTestRule#waitUntil(kotlin.String,kotlin.Long,kotlin.Function0)( conditionDescription: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-string/index.html, timeoutMillis: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-long/index.html, condition: () -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-boolean/index.html )` Blocks until the given `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/ComposeTestRule#waitUntil(kotlin.String,kotlin.Long,kotlin.Function0)` is satisfied. | android |
| `open https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/AndroidComposeTestRule#waitUntilAtLeastOneExists(androidx.compose.ui.test.SemanticsMatcher,kotlin.Long,kotlin.Boolean)( matcher: https://developer.android.com/reference/kotlin/androidx/compose/ui/test/SemanticsMatcher, timeoutMillis: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-long/index.html, useUnmergedTree: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-boolean/index.html )` Blocks until at least one node matches the given `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/ComposeTestRule#waitUntilAtLeastOneExists(androidx.compose.ui.test.SemanticsMatcher,kotlin.Long,kotlin.Boolean)`. | android |
| `open https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/AndroidComposeTestRule#waitUntilDoesNotExist(androidx.compose.ui.test.SemanticsMatcher,kotlin.Long,kotlin.Boolean)( matcher: https://developer.android.com/reference/kotlin/androidx/compose/ui/test/SemanticsMatcher, timeoutMillis: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-long/index.html, useUnmergedTree: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-boolean/index.html )` Blocks until no nodes match the given `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/ComposeTestRule#waitUntilDoesNotExist(androidx.compose.ui.test.SemanticsMatcher,kotlin.Long,kotlin.Boolean)`. | android |
| `open https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/AndroidComposeTestRule#waitUntilExactlyOneExists(androidx.compose.ui.test.SemanticsMatcher,kotlin.Long,kotlin.Boolean)( matcher: https://developer.android.com/reference/kotlin/androidx/compose/ui/test/SemanticsMatcher, timeoutMillis: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-long/index.html, useUnmergedTree: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-boolean/index.html )` Blocks until exactly one node matches the given `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/ComposeTestRule#waitUntilExactlyOneExists(androidx.compose.ui.test.SemanticsMatcher,kotlin.Long,kotlin.Boolean)`. | android |
| `open https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/AndroidComposeTestRule#waitUntilNodeCount(androidx.compose.ui.test.SemanticsMatcher,kotlin.Int,kotlin.Long,kotlin.Boolean)( matcher: https://developer.android.com/reference/kotlin/androidx/compose/ui/test/SemanticsMatcher, count: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html, timeoutMillis: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-long/index.html, useUnmergedTree: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-boolean/index.html )` Blocks until the number of nodes matching the given `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/ComposeTestRule#waitUntilNodeCount(androidx.compose.ui.test.SemanticsMatcher,kotlin.Int,kotlin.Long,kotlin.Boolean)` is equal to the given `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/ComposeTestRule#waitUntilNodeCount(androidx.compose.ui.test.SemanticsMatcher,kotlin.Int,kotlin.Long,kotlin.Boolean)`. | android |

| ### Public properties |
|---|---|---|
| `A` | `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/AndroidComposeTestRule#activity()` Provides the current activity. | android |
| `R` | `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/AndroidComposeTestRule#activityRule()` | android |
| `open https://developer.android.com/reference/kotlin/androidx/compose/ui/unit/Density` | `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/AndroidComposeTestRule#density()` Current device screen's density. | android |
| `open https://developer.android.com/reference/kotlin/androidx/compose/ui/test/MainTestClock` | `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/AndroidComposeTestRule#mainClock()` Clock that drives frames and recompositions in compose tests. | android |

| ### Extension functions |
|---|---|---|
| `https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | `@https://developer.android.com/reference/kotlin/androidx/annotation/RequiresApi(value = 34) <R : https://junit.org/junit4/javadoc/latest/org/junit/rules/TestRule.html, A : https://developer.android.com/reference/kotlin/androidx/activity/ComponentActivity> https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/AndroidComposeTestRule<R, A>.https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/AndroidComposeTestRule#(androidx.compose.ui.test.junit4.AndroidComposeTestRule).disableAccessibilityChecks()( )` Disables accessibility checks. | android |
| `https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | `@https://developer.android.com/reference/kotlin/androidx/annotation/RequiresApi(value = 34) <R : https://junit.org/junit4/javadoc/latest/org/junit/rules/TestRule.html, A : https://developer.android.com/reference/kotlin/androidx/activity/ComponentActivity> https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/AndroidComposeTestRule<R, A>.https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/AndroidComposeTestRule#(androidx.compose.ui.test.junit4.AndroidComposeTestRule).enableAccessibilityChecks(com.google.android.apps.common.testing.accessibility.framework.integrations.espresso.AccessibilityValidator)( accessibilityValidator: com.google.android.apps.common.testing.accessibility.framework.integrations.espresso.AccessibilityValidator )` Enables accessibility checks using an `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/accessibility/package-summary#(androidx.compose.ui.test.junit4.AndroidComposeTestRule).enableAccessibilityChecks(com.google.android.apps.common.testing.accessibility.framework.integrations.espresso.AccessibilityValidator)` that will be run before every action that is expected to change the UI. | android |
| `https://developer.android.com/reference/kotlin/androidx/xr/compose/testing/SubspaceSemanticsNodeInteractionCollection` | `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/AndroidComposeTestRule<*, *>.https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/AndroidComposeTestRule#(androidx.compose.ui.test.junit4.AndroidComposeTestRule).onAllSubspaceNodes(androidx.xr.compose.testing.SubspaceSemanticsMatcher)( matcher: https://developer.android.com/reference/kotlin/androidx/xr/compose/testing/SubspaceSemanticsMatcher )` Finds all semantics nodes in the Subspace hierarchy that match the given condition. | android |
| `https://developer.android.com/reference/kotlin/androidx/xr/compose/testing/SubspaceSemanticsNodeInteractionCollection` | `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/AndroidComposeTestRule<*, *>.https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/AndroidComposeTestRule#(androidx.compose.ui.test.junit4.AndroidComposeTestRule).onAllSubspaceNodesWithTag(kotlin.String)( testTag: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-string/index.html )` Finds all semantics nodes in the Subspace hierarchy identified by the provided test tag. | android |
| `https://developer.android.com/reference/kotlin/androidx/xr/compose/testing/SubspaceSemanticsNodeInteraction` | `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/AndroidComposeTestRule<*, *>.https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/AndroidComposeTestRule#(androidx.compose.ui.test.junit4.AndroidComposeTestRule).onSubspaceNode(androidx.xr.compose.testing.SubspaceSemanticsMatcher)( matcher: https://developer.android.com/reference/kotlin/androidx/xr/compose/testing/SubspaceSemanticsMatcher )` Finds a semantics node in the Subspace hierarchy that matches the given condition. | android |
| `https://developer.android.com/reference/kotlin/androidx/xr/compose/testing/SubspaceSemanticsNodeInteraction` | `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/AndroidComposeTestRule<*, *>.https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/AndroidComposeTestRule#(androidx.compose.ui.test.junit4.AndroidComposeTestRule).onSubspaceNodeWithTag(kotlin.String)(testTag: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-string/index.html)` Finds a semantics node in the Subspace hierarchy identified by the provided test tag. | android |

## Public constructors

### AndroidComposeTestRule

android

```
<R : TestRule, A : ComponentActivity> [AndroidComposeTestRule](https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/AndroidComposeTestRule#AndroidComposeTestRule(org.junit.rules.TestRule,kotlin.Function1))(
    activityRule: R,
    activityProvider: (R) -> A
)
```

> [!CAUTION]
> **This function is deprecated.**   
> Use \`androidx.compose.ui.test.junit4.v2.AndroidComposeTestRule\` instead. The v2 APIs use StandardTestDispatcher instead of UnconfinedTestDispatcher, which aligns with standard coroutine behavior by queuing tasks rather than executing them immediately. Tests relying on immediate execution may require explicit synchronization. Please refer to the migration guide for more details.

Android specific implementation of `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/ComposeContentTestRule`, where compose content is hosted by an Activity.

The Activity is normally launched by the given `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/AndroidComposeTestRule#(org.junit.rules.TestRule,kotlin.Function1)` before the test starts, but it is possible to pass a test rule that chooses to launch an Activity on a later time. The Activity is retrieved from the `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/AndroidComposeTestRule#(org.junit.rules.TestRule,kotlin.Function1)` by means of the `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/AndroidComposeTestRule#(org.junit.rules.TestRule,kotlin.Function1)`, which can be thought of as a getter for the Activity on the `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/AndroidComposeTestRule#(org.junit.rules.TestRule,kotlin.Function1)`. If you use an `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/AndroidComposeTestRule#(org.junit.rules.TestRule,kotlin.Function1)` that launches an Activity on a later time, you should make sure that the Activity is launched by the time or while the `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/AndroidComposeTestRule#(org.junit.rules.TestRule,kotlin.Function1)` is called.

The `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/AndroidComposeTestRule` wraps around the given `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/AndroidComposeTestRule#(org.junit.rules.TestRule,kotlin.Function1)` to make sure the Activity is launched *after* the `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/AndroidComposeTestRule` has completed all necessary steps to control and monitor the compose content.

| Parameters |
|---|---|
| `activityRule: R` | Test rule to use to launch the Activity. |
| `activityProvider: (R) -> A` | Function to retrieve the Activity from the given `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/AndroidComposeTestRule#(org.junit.rules.TestRule,kotlin.Function1)`. |

### AndroidComposeTestRule

android

```
<R : TestRule, A : ComponentActivity> [AndroidComposeTestRule](https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/AndroidComposeTestRule#AndroidComposeTestRule(org.junit.rules.TestRule,kotlin.coroutines.CoroutineContext,kotlin.Function1))(
    activityRule: R,
    effectContext: CoroutineContext = EmptyCoroutineContext,
    activityProvider: (R) -> A
)
```

> [!CAUTION]
> **This function is deprecated.**   
> Use \`androidx.compose.ui.test.junit4.v2.AndroidComposeTestRule\` instead. The v2 APIs use StandardTestDispatcher instead of UnconfinedTestDispatcher, which aligns with standard coroutine behavior by queuing tasks rather than executing them immediately. Tests relying on immediate execution may require explicit synchronization. Please refer to the migration guide for more details.

Android specific implementation of `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/ComposeContentTestRule`, where compose content is hosted by an Activity.

The Activity is normally launched by the given `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/AndroidComposeTestRule#(org.junit.rules.TestRule,kotlin.coroutines.CoroutineContext,kotlin.Function1)` before the test starts, but it is possible to pass a test rule that chooses to launch an Activity on a later time. The Activity is retrieved from the `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/AndroidComposeTestRule#(org.junit.rules.TestRule,kotlin.coroutines.CoroutineContext,kotlin.Function1)` by means of the `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/AndroidComposeTestRule#(org.junit.rules.TestRule,kotlin.coroutines.CoroutineContext,kotlin.Function1)`, which can be thought of as a getter for the Activity on the `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/AndroidComposeTestRule#(org.junit.rules.TestRule,kotlin.coroutines.CoroutineContext,kotlin.Function1)`. If you use an `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/AndroidComposeTestRule#(org.junit.rules.TestRule,kotlin.coroutines.CoroutineContext,kotlin.Function1)` that launches an Activity on a later time, you should make sure that the Activity is launched by the time or while the `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/AndroidComposeTestRule#(org.junit.rules.TestRule,kotlin.coroutines.CoroutineContext,kotlin.Function1)` is called.

The `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/AndroidComposeTestRule` wraps around the given `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/AndroidComposeTestRule#(org.junit.rules.TestRule,kotlin.coroutines.CoroutineContext,kotlin.Function1)` to make sure the Activity is launched *after* the `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/AndroidComposeTestRule` has completed all necessary steps to control and monitor the compose content.

| Parameters |
|---|---|
| `activityRule: R` | Test rule to use to launch the Activity. |
| `effectContext: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.coroutines/-coroutine-context/index.html = EmptyCoroutineContext` | The `https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.coroutines/-coroutine-context/index.html` used to run the composition. The context for `LaunchedEffect`s and `rememberCoroutineScope` will be derived from this context. If this context contains a `https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-test/kotlinx.coroutines.test/-test-dispatcher/index.html` or `https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-test/kotlinx.coroutines.test/-test-coroutine-scheduler/index.html` (in that order), it will be used for composition and the `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/MainTestClock`. |
| `activityProvider: (R) -> A` | Function to retrieve the Activity from the given `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/AndroidComposeTestRule#(org.junit.rules.TestRule,kotlin.coroutines.CoroutineContext,kotlin.Function1)`. |

## Public functions

### apply

android Added in [1.0.0](https://developer.android.com/jetpack/androidx/releases/compose-ui#1.0.0)

```
open fun apply(base: Statement, description: Description): Statement
```

### awaitIdle

android

```
open suspend fun awaitIdle(): Unit
```

Suspends until the UI is idle. Quiescence is reached when there are no more pending changes (e.g. pending recompositions or a pending draw call) and all `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/IdlingResource`s are idle.

If `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/MainTestClock#autoAdvance()` is enabled on the `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/ComposeTestRule#mainClock()`, this method will advance the clock to process any pending composition, invalidation and animation. If auto advancement is not enabled, the clock will not be advanced which means that the Compose UI appears to be frozen. This is ideal for testing animations in a deterministic way. This method will always wait for all `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/IdlingResource`s to become idle.

Note that some processes are driven by the host operating system and will therefore still execute when auto advancement is disabled. For example, Android's measure, layout and draw passes can still happen if required by the View system.

### cancelAndRecreateRecomposer

android Added in [1.7.0](https://developer.android.com/jetpack/androidx/releases/compose-ui#1.7.0)

```
fun cancelAndRecreateRecomposer(): Unit
```

Cancels AndroidComposeUiTestEnvironment's current Recomposer and creates a new one.

Recreates the CoroutineContext associated with Compose being cancelled. This happens when an app moves from a regular ("Full screen") view of the app to a "Pop up" view AND certain properties in the manifest's android:configChanges are set to prevent a full tear down of the app. This is a somewhat rare case (see `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/AndroidComposeUiTestEnvironment` for more details).

### hasPendingWork

android

```
open fun hasPendingWork(): Boolean
```

Returns whether the Compose UI has any pending work.

This performs a passive check of the `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/ComposeTestRule#mainClock()`, snapshot state, and recomposer to determine if there is any pending work. Unlike `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/ComposeTestRule#waitForIdle()`, calling this method does not advance the clock or drain the main message queue.

This is particularly useful when `autoAdvance` is disabled, allowing you to inspect the state of the UI while an animation or other work is still active. If `autoAdvance` is `true`, the testing framework continuously processes pending work. In that scenario, calling this method acts as a momentary snapshot and will generally return `false`. It may briefly return `true` if work is queued but the framework hasn't auto-advanced yet, making the result fleeting and unreliable for driving test logic.

```kotlin
import androidx.compose.ui.test.onNodeWithTag
import androidx.compose.ui.test.performClick

composeTestRule.mainClock.autoAdvance = false

// Trigger the animation
composeTestRule.onNodeWithTag("ExpandButton").performClick()

while (composeTestRule.hasPendingWork()) {
    // Advance the clock by exactly one frame
    composeTestRule.mainClock.advanceTimeByFrame()
    composeTestRule.waitForIdle()
    composeTestRule.runOnUiThread {
        composeTestRule.runWithoutImplicitWait {
            // Make intermediate assertions (e.g., check bounds or visibility)
            composeTestRule.onNodeWithTag("CardContent").assertExists()
        }
    }
}
```

### onAllNodes

android Added in [1.0.0](https://developer.android.com/jetpack/androidx/releases/compose-ui#1.0.0)

```
open fun onAllNodes(matcher: SemanticsMatcher, useUnmergedTree: Boolean = false): SemanticsNodeInteractionCollection
```

Finds all semantics nodes that match the given condition.

If you are working with elements that are not supposed to occur multiple times use `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/SemanticsNodeInteractionsProvider#onNode(androidx.compose.ui.test.SemanticsMatcher,kotlin.Boolean)` instead.

For usage patterns and semantics concepts see `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/SemanticsNodeInteraction`

| Parameters |
|---|---|
| `matcher: https://developer.android.com/reference/kotlin/androidx/compose/ui/test/SemanticsMatcher` | Matcher used for filtering. |
| `useUnmergedTree: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-boolean/index.html = false` | If `true`, searches the unmerged semantics tree instead of the merged semantics tree. This allows you to search for individual nodes that would otherwise be part of a larger semantic unit, for example a text and an image forming a Button together. |

| See also |
|---|---|
| `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/SemanticsNodeInteractionsProvider#onNode(androidx.compose.ui.test.SemanticsMatcher,kotlin.Boolean)` |   |

### onNode

android Added in [1.0.0](https://developer.android.com/jetpack/androidx/releases/compose-ui#1.0.0)

```
open fun onNode(matcher: SemanticsMatcher, useUnmergedTree: Boolean = false): SemanticsNodeInteraction
```

Finds a semantics node that matches the given condition.

Any subsequent operation on its result will expect exactly one element found (unless `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/SemanticsNodeInteraction#assertDoesNotExist()` is used) and will throw an `https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-assertion-error/index.html` if none or more than one element is found.

For usage patterns and semantics concepts see `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/SemanticsNodeInteraction`

| Parameters |
|---|---|
| `matcher: https://developer.android.com/reference/kotlin/androidx/compose/ui/test/SemanticsMatcher` | Matcher used for filtering |
| `useUnmergedTree: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-boolean/index.html = false` | If `true`, searches the unmerged semantics tree instead of the merged semantics tree. This allows you to search for individual nodes that would otherwise be part of a larger semantic unit, for example a text and an image forming a Button together. |

| See also |
|---|---|
| `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/SemanticsNodeInteractionsProvider#onAllNodes(androidx.compose.ui.test.SemanticsMatcher,kotlin.Boolean)` | to work with multiple elements |

### onRootWithViewInteraction

android Added in [1.12.0](https://developer.android.com/jetpack/androidx/releases/compose-ui#1.12.0)

```
fun onRootWithViewInteraction(interaction: ViewInteraction): SemanticsNodeInteractionsProvider
```

Scopes the Compose interaction to the View hierarchy matched by the provided Espresso `https://developer.android.com/reference/kotlin/androidx/test/espresso/ViewInteraction`.

It resolves the View from the Espresso `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/AndroidComposeTestRule#onRootWithViewInteraction(androidx.test.espresso.ViewInteraction)`, locates all Compose roots within that view hierarchy, and creates a new, scoped SemanticsNodeInteractionsProvider.

### registerIdlingResource

android

```
open fun registerIdlingResource(idlingResource: IdlingResource): Unit
```

Registers an `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/IdlingResource` in this test.

### runOnIdle

android

```
open fun <T : Any?> runOnIdle(action: () -> T): T
```

Executes the given `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/ComposeTestRule#runOnIdle(kotlin.Function0)` in the same way as `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/ComposeTestRule#runOnUiThread(kotlin.Function0)` but `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/ComposeTestRule#waitForIdle()` until the app is idle before executing the action. This is the recommended way of doing your assertions on shared variables.

This method blocks until the action is complete.

### runOnUiThread

android

```
open fun <T : Any?> runOnUiThread(action: () -> T): T
```

Runs the given `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/ComposeTestRule#runOnUiThread(kotlin.Function0)` on the UI thread.

This method is blocking until the action is complete.

### runWithoutImplicitWait

android

```
open fun <T : Any?> runWithoutImplicitWait(block: () -> T): T
```

Executes the given `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/ComposeTestRule#runWithoutImplicitWait(kotlin.Function0)` with implicit synchronization suppressed. `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/ComposeTestRule#runWithoutImplicitWait(kotlin.Function0)` should contain read-only assertions, and any actions that mutate state should be performed outside of this block.

To ensure stability of the UI tree while running assertions in this block, make sure to call this on the UI thread, such as with `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/ComposeTestRule#runOnUiThread(kotlin.Function0)`. If you run this block off the UI thread, state might change in the background and be reflected in the UI while the block is executing. This exposes your test to race conditions, flakiness, and may cause you to read stale or inconsistent state.

Standard node queries (like `onNodeWithTag` or `fetchSemanticsNode`) normally trigger a `waitForIdle()` under the hood. In animation tests that manually step through frames in a loop, these implicit waits impose a severe performance penalty.

This API acts as a performance optimization for motion tests that assert UI state across multiple frames. It is primarily designed for use when mainClock.autoAdvance is set to false and the UI is known to be in a stable state at the specific frame being tested (for example, by calling waitForIdle() before this block).

```kotlin
import androidx.compose.ui.test.onNodeWithTag
import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.performClick

composeTestRule.mainClock.autoAdvance = false

// Trigger an animation
composeTestRule.onNodeWithText("Start Animation").performClick()

// Step through the animation frame-by-frame
while (composeTestRule.hasPendingWork()) {
    composeTestRule.mainClock.advanceTimeByFrame()
    composeTestRule.waitForIdle()
    composeTestRule.runOnUiThread {
        // Suppress implicit synchronization inside this block to avoid redundant
        // waits on each node query, making the frame assertions execute much faster.
        composeTestRule.runWithoutImplicitWait {
            val box1 = composeTestRule.onNodeWithTag("Box1").fetchSemanticsNode()
            val box2 = composeTestRule.onNodeWithTag("Box2").fetchSemanticsNode()

            assert(box1.boundsInRoot.right <= box2.boundsInRoot.left)
        }
    }
}
```

| See also |
|---|---|
| `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/ComposeTestRule#runOnUiThread(kotlin.Function0)` |   |
| `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/ComposeTestRule#hasPendingWork()` |   |

### setContent

android

```
open fun setContent(composable: @Composable () -> Unit): Unit
```

Sets the given composable as a content of the current screen.

Use this in your tests to setup the UI content to be tested. This should be called exactly once per test.

| Throws |
|---|---|
| `https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-illegal-state-exception/index.html` | if called more than once per test. |

### unregisterIdlingResource

android

```
open fun unregisterIdlingResource(idlingResource: IdlingResource): Unit
```

Unregisters an `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/IdlingResource` from this test.

### waitForIdle

android

```
open fun waitForIdle(): Unit
```

Waits for the UI to become idle. Quiescence is reached when there are no more pending changes (e.g. pending recompositions or a pending draw call) and all `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/IdlingResource`s are idle.

If `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/MainTestClock#autoAdvance()` is enabled on the `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/ComposeTestRule#mainClock()`, this method will advance the clock to process any pending composition, invalidation and animation. If auto advancement is not enabled, the clock will not be advanced which means that the Compose UI appears to be frozen. This is ideal for testing animations in a deterministic way. This method will always wait for all `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/IdlingResource`s to become idle.

Note that some processes are driven by the host operating system and will therefore still execute when auto advancement is disabled. For example, Android's measure, layout and draw passes can still happen if required by the View system.

### waitUntil

android

```
open fun waitUntil(timeoutMillis: Long, condition: () -> Boolean): Unit
```

Blocks until the given `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/ComposeTestRule#waitUntil(kotlin.Long,kotlin.Function0)` is satisfied.

If `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/MainTestClock#autoAdvance()` is enabled on the `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/ComposeTestRule#mainClock()`, this method will actively advance the clock to process any pending composition, invalidation and animation. If auto advancement is not enabled, the clock will not be advanced actively which means that the Compose UI appears to be frozen. It is still valid to use this method in this way, if the condition will be satisfied by something not driven by our clock.

Compared to `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/MainTestClock#advanceTimeUntil(kotlin.Long,kotlin.Function0)`, `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/ComposeTestRule#waitUntil(kotlin.Long,kotlin.Function0)` sleeps after every iteration to yield to other processes. This gives `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/ComposeTestRule#waitUntil(kotlin.Long,kotlin.Function0)` a better integration with the host, but it is less preferred from a performance viewpoint. Therefore, we recommend that you try using `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/MainTestClock#advanceTimeUntil(kotlin.Long,kotlin.Function0)` before resorting to `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/ComposeTestRule#waitUntil(kotlin.Long,kotlin.Function0)`.

| Parameters |
|---|---|
| `timeoutMillis: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-long/index.html` | The time after which this method throws an exception if the given condition is not satisfied. This observes wall clock time, not `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/ComposeTestRule#mainClock()`. |
| `condition: () -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-boolean/index.html` | Condition that must be satisfied in order for this method to successfully finish. |

| Throws |
|---|---|
| `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/ComposeTimeoutException` | If the condition is not satisfied after `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/ComposeTestRule#waitUntil(kotlin.Long,kotlin.Function0)` (in wall clock time). |

### waitUntil

android

```
open fun waitUntil(
    conditionDescription: String,
    timeoutMillis: Long,
    condition: () -> Boolean
): Unit
```

Blocks until the given `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/ComposeTestRule#waitUntil(kotlin.String,kotlin.Long,kotlin.Function0)` is satisfied.

If `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/MainTestClock#autoAdvance()` is enabled on the `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/ComposeTestRule#mainClock()`, this method will actively advance the clock to process any pending composition, invalidation and animation. If auto advancement is not enabled, the clock will not be advanced actively which means that the Compose UI appears to be frozen. It is still valid to use this method in this way, if the condition will be satisfied by something not driven by our clock.

Compared to `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/MainTestClock#advanceTimeUntil(kotlin.Long,kotlin.Function0)`, `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/ComposeTestRule#waitUntil(kotlin.String,kotlin.Long,kotlin.Function0)` sleeps after every iteration to yield to other processes. This gives `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/ComposeTestRule#waitUntil(kotlin.String,kotlin.Long,kotlin.Function0)` a better integration with the host, but it is less preferred from a performance viewpoint. Therefore, we recommend that you try using `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/MainTestClock#advanceTimeUntil(kotlin.Long,kotlin.Function0)` before resorting to `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/ComposeTestRule#waitUntil(kotlin.String,kotlin.Long,kotlin.Function0)`.

| Parameters |
|---|---|
| `conditionDescription: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-string/index.html` | An optional human-readable description of `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/ComposeTestRule#waitUntil(kotlin.String,kotlin.Long,kotlin.Function0)` that will be included in the timeout exception if thrown. |
| `timeoutMillis: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-long/index.html` | The time after which this method throws an exception if the given condition is not satisfied. This observes wall clock time, not `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/ComposeTestRule#mainClock()`. |
| `condition: () -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-boolean/index.html` | Condition that must be satisfied in order for this method to successfully finish. |

| Throws |
|---|---|
| `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/ComposeTimeoutException` | If the condition is not satisfied after `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/ComposeTestRule#waitUntil(kotlin.String,kotlin.Long,kotlin.Function0)` (in wall clock time). |

### waitUntilAtLeastOneExists

android

```
open fun waitUntilAtLeastOneExists(
    matcher: SemanticsMatcher,
    timeoutMillis: Long,
    useUnmergedTree: Boolean = false
): Unit
```

Blocks until at least one node matches the given `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/ComposeTestRule#waitUntilAtLeastOneExists(androidx.compose.ui.test.SemanticsMatcher,kotlin.Long,kotlin.Boolean)`.

| Parameters |
|---|---|
| `matcher: https://developer.android.com/reference/kotlin/androidx/compose/ui/test/SemanticsMatcher` | The matcher that will be used to filter nodes. |
| `timeoutMillis: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-long/index.html` | The time after which this method throws an exception if no nodes match the given `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/ComposeTestRule#waitUntilAtLeastOneExists(androidx.compose.ui.test.SemanticsMatcher,kotlin.Long,kotlin.Boolean)`. This observes wall clock time, not frame time. |
| `useUnmergedTree: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-boolean/index.html = false` | If true, searches the unmerged semantics tree instead of the merged semantics tree. |

| Throws |
|---|---|
| `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/ComposeTimeoutException` | If no nodes match the given `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/ComposeTestRule#waitUntilAtLeastOneExists(androidx.compose.ui.test.SemanticsMatcher,kotlin.Long,kotlin.Boolean)` after `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/ComposeTestRule#waitUntilAtLeastOneExists(androidx.compose.ui.test.SemanticsMatcher,kotlin.Long,kotlin.Boolean)` (in wall clock time). |

| See also |
|---|---|
| `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/ComposeTestRule#waitUntil(kotlin.Long,kotlin.Function0)` |   |

### waitUntilDoesNotExist

android

```
open fun waitUntilDoesNotExist(
    matcher: SemanticsMatcher,
    timeoutMillis: Long,
    useUnmergedTree: Boolean = false
): Unit
```

Blocks until no nodes match the given `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/ComposeTestRule#waitUntilDoesNotExist(androidx.compose.ui.test.SemanticsMatcher,kotlin.Long,kotlin.Boolean)`.

| Parameters |
|---|---|
| `matcher: https://developer.android.com/reference/kotlin/androidx/compose/ui/test/SemanticsMatcher` | The matcher that will be used to filter nodes. |
| `timeoutMillis: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-long/index.html` | The time after which this method throws an exception if any nodes match the given `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/ComposeTestRule#waitUntilDoesNotExist(androidx.compose.ui.test.SemanticsMatcher,kotlin.Long,kotlin.Boolean)`. This observes wall clock time, not frame time. |
| `useUnmergedTree: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-boolean/index.html = false` | If true, searches the unmerged semantics tree instead of the merged semantics tree. |

| Throws |
|---|---|
| `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/ComposeTimeoutException` | If any nodes match the given `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/ComposeTestRule#waitUntilDoesNotExist(androidx.compose.ui.test.SemanticsMatcher,kotlin.Long,kotlin.Boolean)` after `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/ComposeTestRule#waitUntilDoesNotExist(androidx.compose.ui.test.SemanticsMatcher,kotlin.Long,kotlin.Boolean)` (in wall clock time). |

| See also |
|---|---|
| `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/ComposeTestRule#waitUntil(kotlin.Long,kotlin.Function0)` |   |

### waitUntilExactlyOneExists

android

```
open fun waitUntilExactlyOneExists(
    matcher: SemanticsMatcher,
    timeoutMillis: Long,
    useUnmergedTree: Boolean = false
): Unit
```

Blocks until exactly one node matches the given `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/ComposeTestRule#waitUntilExactlyOneExists(androidx.compose.ui.test.SemanticsMatcher,kotlin.Long,kotlin.Boolean)`.

| Parameters |
|---|---|
| `matcher: https://developer.android.com/reference/kotlin/androidx/compose/ui/test/SemanticsMatcher` | The matcher that will be used to filter nodes. |
| `timeoutMillis: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-long/index.html` | The time after which this method throws an exception if exactly one node does not match the given `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/ComposeTestRule#waitUntilExactlyOneExists(androidx.compose.ui.test.SemanticsMatcher,kotlin.Long,kotlin.Boolean)`. This observes wall clock time, not frame time. |
| `useUnmergedTree: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-boolean/index.html = false` | If true, searches the unmerged semantics tree instead of the merged semantics tree. |

| Throws |
|---|---|
| `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/ComposeTimeoutException` | If exactly one node does not match the given `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/ComposeTestRule#waitUntilExactlyOneExists(androidx.compose.ui.test.SemanticsMatcher,kotlin.Long,kotlin.Boolean)` after `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/ComposeTestRule#waitUntilExactlyOneExists(androidx.compose.ui.test.SemanticsMatcher,kotlin.Long,kotlin.Boolean)` (in wall clock time). |

| See also |
|---|---|
| `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/ComposeTestRule#waitUntil(kotlin.Long,kotlin.Function0)` |   |

### waitUntilNodeCount

android

```
open fun waitUntilNodeCount(
    matcher: SemanticsMatcher,
    count: Int,
    timeoutMillis: Long,
    useUnmergedTree: Boolean = false
): Unit
```

Blocks until the number of nodes matching the given `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/ComposeTestRule#waitUntilNodeCount(androidx.compose.ui.test.SemanticsMatcher,kotlin.Int,kotlin.Long,kotlin.Boolean)` is equal to the given `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/ComposeTestRule#waitUntilNodeCount(androidx.compose.ui.test.SemanticsMatcher,kotlin.Int,kotlin.Long,kotlin.Boolean)`.

| Parameters |
|---|---|
| `matcher: https://developer.android.com/reference/kotlin/androidx/compose/ui/test/SemanticsMatcher` | The matcher that will be used to filter nodes. |
| `count: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html` | The number of nodes that are expected to be matched. |
| `timeoutMillis: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-long/index.html` | The time after which this method throws an exception if the number of nodes that match the `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/ComposeTestRule#waitUntilNodeCount(androidx.compose.ui.test.SemanticsMatcher,kotlin.Int,kotlin.Long,kotlin.Boolean)` is not `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/ComposeTestRule#waitUntilNodeCount(androidx.compose.ui.test.SemanticsMatcher,kotlin.Int,kotlin.Long,kotlin.Boolean)`. This observes wall clock time, not frame time. |
| `useUnmergedTree: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-boolean/index.html = false` | If true, searches the unmerged semantics tree instead of the merged semantics tree. |

| Throws |
|---|---|
| `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/ComposeTimeoutException` | If the number of nodes that match the `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/ComposeTestRule#waitUntilNodeCount(androidx.compose.ui.test.SemanticsMatcher,kotlin.Int,kotlin.Long,kotlin.Boolean)` is not `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/ComposeTestRule#waitUntilNodeCount(androidx.compose.ui.test.SemanticsMatcher,kotlin.Int,kotlin.Long,kotlin.Boolean)` after `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/ComposeTestRule#waitUntilNodeCount(androidx.compose.ui.test.SemanticsMatcher,kotlin.Int,kotlin.Long,kotlin.Boolean)` (in wall clock time). |

| See also |
|---|---|
| `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/ComposeTestRule#waitUntil(kotlin.Long,kotlin.Function0)` |   |

## Public properties

### activity

android Added in [1.0.0](https://developer.android.com/jetpack/androidx/releases/compose-ui#1.0.0)

```
val activity: A
```

Provides the current activity.

Avoid calling often as it can involve synchronization and can be slow.

### activityRule

android Added in [1.0.0](https://developer.android.com/jetpack/androidx/releases/compose-ui#1.0.0)

```
val activityRule: R
```

### density

android

```
open val density: Density
```

Current device screen's density. Note that it is technically possible for a Compose hierarchy to define a different density for a certain subtree.

### mainClock

android

```
open val mainClock: MainTestClock
```

Clock that drives frames and recompositions in compose tests.

## Extension functions

### AndroidComposeTestRule.disableAccessibilityChecks

android Artifact: [androidx.compose.ui:ui-test-junit4-accessibility](https://developer.android.com/jetpack/androidx/releases/compose-ui) [View Source](https://cs.android.com/search?q=file:androidx/compose/ui/test/junit4/accessibility/AndroidComposeTestRuleExt.android.kt+function:disableAccessibilityChecks)

```
@RequiresApi(value = 34)
fun <R : TestRule, A : ComponentActivity> AndroidComposeTestRule<R, A>.disableAccessibilityChecks(

): Unit
```

Disables accessibility checks.

| See also |
|---|---|
| `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/accessibility/package-summary#(androidx.compose.ui.test.junit4.AndroidComposeTestRule).enableAccessibilityChecks(com.google.android.apps.common.testing.accessibility.framework.integrations.espresso.AccessibilityValidator)` |   |

### AndroidComposeTestRule.enableAccessibilityChecks

android Artifact: [androidx.compose.ui:ui-test-junit4-accessibility](https://developer.android.com/jetpack/androidx/releases/compose-ui) [View Source](https://cs.android.com/search?q=file:androidx/compose/ui/test/junit4/accessibility/AndroidComposeTestRuleExt.android.kt+function:enableAccessibilityChecks)

```
@RequiresApi(value = 34)
fun <R : TestRule, A : ComponentActivity> AndroidComposeTestRule<R, A>.enableAccessibilityChecks(
    accessibilityValidator: com.google.android.apps.common.testing.accessibility.framework.integrations.espresso.AccessibilityValidator = AccessibilityValidator().setRunChecksFromRootView(true)
): Unit
```

Enables accessibility checks using an `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/accessibility/package-summary#(androidx.compose.ui.test.junit4.AndroidComposeTestRule).enableAccessibilityChecks(com.google.android.apps.common.testing.accessibility.framework.integrations.espresso.AccessibilityValidator)` that will be run before every action that is expected to change the UI.

This requires API 34+ (Android U), and currently does not work on Robolectric.

```kotlin
import androidx.compose.ui.test.junit4.accessibility.enableAccessibilityChecks
import androidx.test.espresso.accessibility.AccessibilityChecks

// Configure your own AccessibilityValidator
val accessibilityValidator =
    AccessibilityValidator().also {
        it.setThrowExceptionFor(AccessibilityCheckResultType.ERROR)
    }

// Enable accessibility checks with your own AccessibilityValidator:
androidComposeTestRule.enableAccessibilityChecks(accessibilityValidator)
```

If you have a hybrid application with both Compose and Views, and you use both Compose Test and Espresso, then you should set up accessibility checks in both frameworks and share the configuration in the following way:

```kotlin
import androidx.compose.ui.test.junit4.accessibility.enableAccessibilityChecks
import androidx.test.espresso.accessibility.AccessibilityChecks

// Enable accessibility checks in both Espresso and Compose, and share the configuration
val accessibilityValidator = AccessibilityChecks.enable()
androidComposeTestRule.enableAccessibilityChecks(accessibilityValidator)
```

| See also |
|---|---|
| `https://developer.android.com/reference/kotlin/androidx/compose/ui/test/junit4/accessibility/package-summary#(androidx.compose.ui.test.junit4.AndroidComposeTestRule).disableAccessibilityChecks()` |   |

### AndroidComposeTestRule.onAllSubspaceNodes

android Artifact: [androidx.xr.compose:compose-testing](https://developer.android.com/jetpack/androidx/releases/xr-compose) [View Source](https://cs.android.com/search?q=file:androidx/xr/compose/testing/AndroidComposeTestRuleExt.kt+function:onAllSubspaceNodes)

```
fun AndroidComposeTestRule<*, *>.onAllSubspaceNodes(
    matcher: SubspaceSemanticsMatcher
): SubspaceSemanticsNodeInteractionCollection
```

Finds all semantics nodes in the Subspace hierarchy that match the given condition.

This function only locates nodes within the Subspace hierarchy and does not include nodes from standard 2D compose contexts. For locating 2D nodes, use `AndroidComposeTestRule.onAllNodes`. If you are dealing with elements guaranteed to occur exactly once, prefer using `onSubspaceNode` to enforce uniqueness constraints and improve clarity.

```kotlin
import androidx.compose.material3.Button
import androidx.compose.material3.Text
import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.performClick
import androidx.compose.ui.unit.dp
import androidx.xr.compose.spatial.Subspace
import androidx.xr.compose.subspace.SpatialPanel
import androidx.xr.compose.subspace.layout.SubspaceModifier
import androidx.xr.compose.subspace.semantics.testTag
import androidx.xr.compose.testing.assertPositionInRootIsEqualTo
import androidx.xr.compose.testing.onSubspaceNode
import androidx.xr.compose.testing.onSubspaceNodeWithTag

var count = 0

composeTestRule.setContent {
    Subspace {
        SpatialPanel(SubspaceModifier.testTag("spatialPanel")) {
            Button(onClick = { count++ }) { Text("Increment") }
        }
    }
}

// Assert subspace node existence, position, and dimensions in the Spatial hierarchy
composeTestRule
    .onSubspaceNodeWithTag("spatialPanel")
    .assertExists()
    .assertPositionInRootIsEqualTo(0.dp, 0.dp, 0.dp)

// Interact with the 2D Compose node nested within the Spatial container
composeTestRule.onNodeWithText("Increment").performClick()

composeTestRule.waitForIdle()

// Verify outcomes
assert(count == 1)
```

```kotlin
import androidx.compose.ui.unit.dp
import androidx.xr.compose.spatial.Subspace
import androidx.xr.compose.subspace.SpatialPanel
import androidx.xr.compose.subspace.layout.SubspaceModifier
import androidx.xr.compose.subspace.layout.height
import androidx.xr.compose.subspace.layout.width
import androidx.xr.compose.subspace.semantics.testTag
import androidx.xr.compose.testing.assertHeightIsEqualTo
import androidx.xr.compose.testing.assertPositionInRootIsEqualTo
import androidx.xr.compose.testing.assertWidthIsEqualTo
import androidx.xr.compose.testing.onSubspaceNode
import androidx.xr.compose.testing.onSubspaceNodeWithTag

composeTestRule.setContent {
    Subspace {
        SpatialPanel(SubspaceModifier.width(100.dp).height(100.dp).testTag("myPanel")) {}
    }
}

// Check existence and exact spatial dimensions in DP using semantic matchers
composeTestRule
    .onSubspaceNodeWithTag("myPanel")
    .assertExists()
    .assertPositionInRootIsEqualTo(0.dp, 0.dp, 0.dp)
    .assertWidthIsEqualTo(100.dp)
    .assertHeightIsEqualTo(100.dp)
```

| Parameters |
|---|---|
| `matcher: https://developer.android.com/reference/kotlin/androidx/xr/compose/testing/SubspaceSemanticsMatcher` | the `SubspaceSemanticsMatcher` used to filter the semantics nodes. |

| Returns |
|---|---|
| `https://developer.android.com/reference/kotlin/androidx/xr/compose/testing/SubspaceSemanticsNodeInteractionCollection` | the `SubspaceSemanticsNodeInteractionCollection` containing all matching nodes. |

| See also |
|---|---|
| `https://developer.android.com/reference/kotlin/androidx/xr/compose/testing/package-summary#(androidx.compose.ui.test.junit4.AndroidComposeTestRule).onSubspaceNode(androidx.xr.compose.testing.SubspaceSemanticsMatcher)` |   |

### AndroidComposeTestRule.onAllSubspaceNodesWithTag

android Artifact: [androidx.xr.compose:compose-testing](https://developer.android.com/jetpack/androidx/releases/xr-compose) [View Source](https://cs.android.com/search?q=file:androidx/xr/compose/testing/AndroidComposeTestRuleExt.kt+function:onAllSubspaceNodesWithTag)

```
fun AndroidComposeTestRule<*, *>.onAllSubspaceNodesWithTag(
    testTag: String
): SubspaceSemanticsNodeInteractionCollection
```

Finds all semantics nodes in the Subspace hierarchy identified by the provided test tag.

This convenience function specifically searches for nodes within the Subspace hierarchy and does not locate standard 2D compose elements. The search evaluates for an exact string match on the test tag.

```kotlin
import androidx.compose.material3.Button
import androidx.compose.material3.Text
import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.performClick
import androidx.compose.ui.unit.dp
import androidx.xr.compose.spatial.Subspace
import androidx.xr.compose.subspace.SpatialPanel
import androidx.xr.compose.subspace.layout.SubspaceModifier
import androidx.xr.compose.subspace.semantics.testTag
import androidx.xr.compose.testing.assertPositionInRootIsEqualTo
import androidx.xr.compose.testing.onSubspaceNode
import androidx.xr.compose.testing.onSubspaceNodeWithTag

var count = 0

composeTestRule.setContent {
    Subspace {
        SpatialPanel(SubspaceModifier.testTag("spatialPanel")) {
            Button(onClick = { count++ }) { Text("Increment") }
        }
    }
}

// Assert subspace node existence, position, and dimensions in the Spatial hierarchy
composeTestRule
    .onSubspaceNodeWithTag("spatialPanel")
    .assertExists()
    .assertPositionInRootIsEqualTo(0.dp, 0.dp, 0.dp)

// Interact with the 2D Compose node nested within the Spatial container
composeTestRule.onNodeWithText("Increment").performClick()

composeTestRule.waitForIdle()

// Verify outcomes
assert(count == 1)
```

```kotlin
import androidx.compose.ui.unit.dp
import androidx.xr.compose.spatial.Subspace
import androidx.xr.compose.subspace.SpatialPanel
import androidx.xr.compose.subspace.layout.SubspaceModifier
import androidx.xr.compose.subspace.layout.height
import androidx.xr.compose.subspace.layout.width
import androidx.xr.compose.subspace.semantics.testTag
import androidx.xr.compose.testing.assertHeightIsEqualTo
import androidx.xr.compose.testing.assertPositionInRootIsEqualTo
import androidx.xr.compose.testing.assertWidthIsEqualTo
import androidx.xr.compose.testing.onSubspaceNode
import androidx.xr.compose.testing.onSubspaceNodeWithTag

composeTestRule.setContent {
    Subspace {
        SpatialPanel(SubspaceModifier.width(100.dp).height(100.dp).testTag("myPanel")) {}
    }
}

// Check existence and exact spatial dimensions in DP using semantic matchers
composeTestRule
    .onSubspaceNodeWithTag("myPanel")
    .assertExists()
    .assertPositionInRootIsEqualTo(0.dp, 0.dp, 0.dp)
    .assertWidthIsEqualTo(100.dp)
    .assertHeightIsEqualTo(100.dp)
```

| Parameters |
|---|---|
| `testTag: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-string/index.html` | the specific tag string to search for within the hierarchy. |

| Returns |
|---|---|
| `https://developer.android.com/reference/kotlin/androidx/xr/compose/testing/SubspaceSemanticsNodeInteractionCollection` | the `SubspaceSemanticsNodeInteractionCollection` containing all matching nodes. |

| See also |
|---|---|
| `https://developer.android.com/reference/kotlin/androidx/xr/compose/testing/package-summary#(androidx.compose.ui.test.junit4.AndroidComposeTestRule).onAllSubspaceNodes(androidx.xr.compose.testing.SubspaceSemanticsMatcher)` |   |

### AndroidComposeTestRule.onSubspaceNode

android Artifact: [androidx.xr.compose:compose-testing](https://developer.android.com/jetpack/androidx/releases/xr-compose) [View Source](https://cs.android.com/search?q=file:androidx/xr/compose/testing/AndroidComposeTestRuleExt.kt+function:onSubspaceNode)

```
fun AndroidComposeTestRule<*, *>.onSubspaceNode(
    matcher: SubspaceSemanticsMatcher
): SubspaceSemanticsNodeInteraction
```

Finds a semantics node in the Subspace hierarchy that matches the given condition.

This function only locates nodes within the Subspace hierarchy and does not include nodes from standard 2D compose contexts. For example, it targets `SpatialPanel`, `SpatialRow`, or `SpatialColumn` nodes but not standard `Row`, `Column`, or `Text` nodes. For locating 2D nodes, use `AndroidComposeTestRule.onNode`.

Any subsequent operation on the returned interaction expects exactly one element to be found (unless `SubspaceSemanticsNodeInteraction.assertDoesNotExist` is used) and throws an `AssertionError` if zero or multiple elements are found.

```kotlin
import androidx.compose.material3.Button
import androidx.compose.material3.Text
import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.performClick
import androidx.compose.ui.unit.dp
import androidx.xr.compose.spatial.Subspace
import androidx.xr.compose.subspace.SpatialPanel
import androidx.xr.compose.subspace.layout.SubspaceModifier
import androidx.xr.compose.subspace.semantics.testTag
import androidx.xr.compose.testing.assertPositionInRootIsEqualTo
import androidx.xr.compose.testing.onSubspaceNode
import androidx.xr.compose.testing.onSubspaceNodeWithTag

var count = 0

composeTestRule.setContent {
    Subspace {
        SpatialPanel(SubspaceModifier.testTag("spatialPanel")) {
            Button(onClick = { count++ }) { Text("Increment") }
        }
    }
}

// Assert subspace node existence, position, and dimensions in the Spatial hierarchy
composeTestRule
    .onSubspaceNodeWithTag("spatialPanel")
    .assertExists()
    .assertPositionInRootIsEqualTo(0.dp, 0.dp, 0.dp)

// Interact with the 2D Compose node nested within the Spatial container
composeTestRule.onNodeWithText("Increment").performClick()

composeTestRule.waitForIdle()

// Verify outcomes
assert(count == 1)
```

```kotlin
import androidx.compose.ui.unit.dp
import androidx.xr.compose.spatial.Subspace
import androidx.xr.compose.subspace.SpatialPanel
import androidx.xr.compose.subspace.layout.SubspaceModifier
import androidx.xr.compose.subspace.layout.height
import androidx.xr.compose.subspace.layout.width
import androidx.xr.compose.subspace.semantics.testTag
import androidx.xr.compose.testing.assertHeightIsEqualTo
import androidx.xr.compose.testing.assertPositionInRootIsEqualTo
import androidx.xr.compose.testing.assertWidthIsEqualTo
import androidx.xr.compose.testing.onSubspaceNode
import androidx.xr.compose.testing.onSubspaceNodeWithTag

composeTestRule.setContent {
    Subspace {
        SpatialPanel(SubspaceModifier.width(100.dp).height(100.dp).testTag("myPanel")) {}
    }
}

// Check existence and exact spatial dimensions in DP using semantic matchers
composeTestRule
    .onSubspaceNodeWithTag("myPanel")
    .assertExists()
    .assertPositionInRootIsEqualTo(0.dp, 0.dp, 0.dp)
    .assertWidthIsEqualTo(100.dp)
    .assertHeightIsEqualTo(100.dp)
```

| Parameters |
|---|---|
| `matcher: https://developer.android.com/reference/kotlin/androidx/xr/compose/testing/SubspaceSemanticsMatcher` | the `SubspaceSemanticsMatcher` used to identify the matching semantics node. |

| Returns |
|---|---|
| `https://developer.android.com/reference/kotlin/androidx/xr/compose/testing/SubspaceSemanticsNodeInteraction` | the `SubspaceSemanticsNodeInteraction` for the matched node. |

| See also |
|---|---|
| `https://developer.android.com/reference/kotlin/androidx/xr/compose/testing/package-summary#(androidx.compose.ui.test.junit4.AndroidComposeTestRule).onAllSubspaceNodes(androidx.xr.compose.testing.SubspaceSemanticsMatcher)` |   |

### AndroidComposeTestRule.onSubspaceNodeWithTag

android Artifact: [androidx.xr.compose:compose-testing](https://developer.android.com/jetpack/androidx/releases/xr-compose) [View Source](https://cs.android.com/search?q=file:androidx/xr/compose/testing/AndroidComposeTestRuleExt.kt+function:onSubspaceNodeWithTag)

```
fun AndroidComposeTestRule<*, *>.onSubspaceNodeWithTag(testTag: String): SubspaceSemanticsNodeInteraction
```

Finds a semantics node in the Subspace hierarchy identified by the provided test tag.

This convenience function specifically searches for nodes within the Subspace hierarchy and does not locate standard 2D compose elements. The search evaluates for an exact string match on the test tag.

```kotlin
import androidx.compose.material3.Button
import androidx.compose.material3.Text
import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.performClick
import androidx.compose.ui.unit.dp
import androidx.xr.compose.spatial.Subspace
import androidx.xr.compose.subspace.SpatialPanel
import androidx.xr.compose.subspace.layout.SubspaceModifier
import androidx.xr.compose.subspace.semantics.testTag
import androidx.xr.compose.testing.assertPositionInRootIsEqualTo
import androidx.xr.compose.testing.onSubspaceNode
import androidx.xr.compose.testing.onSubspaceNodeWithTag

var count = 0

composeTestRule.setContent {
    Subspace {
        SpatialPanel(SubspaceModifier.testTag("spatialPanel")) {
            Button(onClick = { count++ }) { Text("Increment") }
        }
    }
}

// Assert subspace node existence, position, and dimensions in the Spatial hierarchy
composeTestRule
    .onSubspaceNodeWithTag("spatialPanel")
    .assertExists()
    .assertPositionInRootIsEqualTo(0.dp, 0.dp, 0.dp)

// Interact with the 2D Compose node nested within the Spatial container
composeTestRule.onNodeWithText("Increment").performClick()

composeTestRule.waitForIdle()

// Verify outcomes
assert(count == 1)
```

```kotlin
import androidx.compose.ui.unit.dp
import androidx.xr.compose.spatial.Subspace
import androidx.xr.compose.subspace.SpatialPanel
import androidx.xr.compose.subspace.layout.SubspaceModifier
import androidx.xr.compose.subspace.layout.height
import androidx.xr.compose.subspace.layout.width
import androidx.xr.compose.subspace.semantics.testTag
import androidx.xr.compose.testing.assertHeightIsEqualTo
import androidx.xr.compose.testing.assertPositionInRootIsEqualTo
import androidx.xr.compose.testing.assertWidthIsEqualTo
import androidx.xr.compose.testing.onSubspaceNode
import androidx.xr.compose.testing.onSubspaceNodeWithTag

composeTestRule.setContent {
    Subspace {
        SpatialPanel(SubspaceModifier.width(100.dp).height(100.dp).testTag("myPanel")) {}
    }
}

// Check existence and exact spatial dimensions in DP using semantic matchers
composeTestRule
    .onSubspaceNodeWithTag("myPanel")
    .assertExists()
    .assertPositionInRootIsEqualTo(0.dp, 0.dp, 0.dp)
    .assertWidthIsEqualTo(100.dp)
    .assertHeightIsEqualTo(100.dp)
```

| Parameters |
|---|---|
| `testTag: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-string/index.html` | the specific tag string to search for within the hierarchy. |

| Returns |
|---|---|
| `https://developer.android.com/reference/kotlin/androidx/xr/compose/testing/SubspaceSemanticsNodeInteraction` | the `SubspaceSemanticsNodeInteraction` for the matched node. |

| See also |
|---|---|
| `https://developer.android.com/reference/kotlin/androidx/xr/compose/testing/package-summary#(androidx.compose.ui.test.junit4.AndroidComposeTestRule).onSubspaceNode(androidx.xr.compose.testing.SubspaceSemanticsMatcher)` |   |