원클릭으로
android-instrumented-ui-test
Rules and guidelines for writing Android instrumented UI tests for the android-cmp-app sample
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Rules and guidelines for writing Android instrumented UI tests for the android-cmp-app sample
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
Rules and workflow for integrating Constellation Mobile SDK into a Compose Multiplatform application
Rules and guidelines for overriding UI field components in the Compose Multiplatform SDK
Rules and workflow for migrating Angular TypeScript components to plain ES module JavaScript for the scripts/ bridge layer
Rules and guidelines for creating components in the core Kotlin module
Rules and guidelines for writing unit tests for JavaScript components in the scripts/ bridge layer
Rules and guidelines for creating Compose Multiplatform UI components in the ui-components-cmp module
| name | android-instrumented-ui-test |
| description | Rules and guidelines for writing Android instrumented UI tests for the android-cmp-app sample |
Android instrumented UI tests live in:
samples/android-cmp-app/src/androidInstrumentedTest/kotlin/com/pega/constellation/sdk/kmp/samples/androidcmpapp/test/
Tests are run with Compose UI Test against a mock HTTP server backed by fixture JSON files.
DxAssignmentsHandler
assignmentId from response and create handle function for each test. Inside handle function handle exact request using actionIdDxAssignmentsHandler) related jsons (POST in name, files in test/src/commonMain/composeResources/files/responses/dx/cases/) -> DxCasesHandlerDxDataViewsHandlerHandlers inside folder: test/src/commonMain/kotlin/com/pega/constellation/sdk/kmp/test/mock/handlers/
Location: samples/android-cmp-app/src/androidInstrumentedTest/kotlin/com/pega/constellation/sdk/kmp/samples/androidcmpapp/test/cases/
Name: Test.kt
<FeatureName>TestComposeTest and pass the appropriate PegaVersion - please ask user for it if not provided.@OptIn(ExperimentalTestApi::class)kotlin.test.Test as testing librarytest_ prefix + snake_case (test_<feature_name>)runComposeUiTest { ... }setupApp(caseClassName = "...") as the first statement inside runComposeUiTestAlways begin by triggering case creation from the app's home screen:
onNodeWithText("New Service").performClick()
Then wait for the form title to confirm the view loaded before asserting anything else:
waitForNode("Expected title", substring = true)
ComposeTestUtils.kt)Import from com.pega.constellation.sdk.kmp.samples.androidcmpapp.test:
| Function | Purpose |
|---|---|
waitForNode(text, substring) | Wait up to 5 s for exactly one node with given text; fails with a clear message |
waitForNodes(text, count, substring) | Wait up to 5 s for exactly count nodes with given text |
onAllDescendantsOf(testTag) | Returns all nodes that are descendants of a node with the given test tag |
find(text) | Extension on SemanticsNodeInteractionCollection — filters by text and returns the first match |
printAllFormNodes() | Debug helper — prints the full node tree to logcat |
onAllDescendantsOf + find patternUse this pattern to scope assertions to a specific section of the UI identified by a test tag:
import com.pega.constellation.sdk.kmp.samples.androidcmpapp.test.find
import com.pega.constellation.sdk.kmp.samples.androidcmpapp.test.onAllDescendantsOf
onAllDescendantsOf("some_test_tag").let { nodes ->
nodes.find("label text").assertExists()
nodes.find("value text").assertExists()
}
Both find and onAllDescendantsOf must be explicitly imported — they are top-level extension functions, not methods on the test class.
When the same set of texts must be verified in multiple places (e.g. in two different sections of the same screen), extract them into a class-level property and iterate:
private val expectedFields = mapOf(
"label 1" to "value 1",
"label 2" to "value 2",
)
private fun ComposeUiTest.verifyExpectedFields(testTag: String) {
onAllDescendantsOf(testTag).let { nodes ->
expectedFields.forEach { (label, value) ->
nodes.find(label).assertExists()
nodes.find(value).assertExists()
}
}
}
Call the shared function with different test tags:
verifyExpectedFields("section_one_tag")
verifyExpectedFields("section_two_tag")
Extract repeated assertion sequences into private fun ComposeUiTest.<name>() methods to keep the main test body readable:
private fun ComposeUiTest.verifyDetailsShown() {
waitForNode("Details")
waitForNode("Label")
waitForNode("Some value")
}
// Text input
onNodeWithText("field label").performTextInput("value")
// Click
onNodeWithText("Button label").performClick()
// Checkbox via test tag
onNodeWithTag("checkbox_[Label]").performClick()
// Scroll then interact
it.find("field label").performScrollTo().performClick()
// Wait for node to disappear
waitUntilDoesNotExist(hasText("text"))
// Assert node count
waitForNodes("text", count = 2)
Please ask user for PegaVersion if he didin't specify it. Available values are defined in PegaVersion (e.g. PegaVersion.v24_1_0, PegaVersion.v24_2_2, PegaVersion.v25_1).