ワンクリックで
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).