@@ -61,7 +61,8 @@ class EmbeddedDataTest : ComposeTest(PegaVersion.v24_2_2) {
6161 waitForNode(" brand: Cannot be blank" , substring = true )
6262
6363 // enter data in row 1 and verify
64- onAllNodes(hasAnyAncestor(hasTestTag(" field_group_template_[Cars repeating view editable]" ))).let {
64+ val carsEditableFieldGroup = " field_group_template_[Cars repeating view editable]"
65+ allDescendantsOf(carsEditableFieldGroup).let {
6566 it.findFirstWithText(" brand" ).performTextInput(" Audi" )
6667 it.findFirstWithText(" model" ).performTextInput(" A5" )
6768 it.findFirstWithText(" Price" ).performTextInput(" 123000" )
@@ -85,48 +86,46 @@ class EmbeddedDataTest : ComposeTest(PegaVersion.v24_2_2) {
8586 onNodeWithText(" Cars repeating view readonly" ).performScrollTo().performClick()
8687
8788 // verify editable data
88- verifyEmbeddedDataRecord (
89+ verifyFieldGroupItem (
8990 nodes = it,
9091 expectedDate = LocalDateTime .now().toString().substring(0 , 10 ),
9192 isEditable = true
9293 )
9394 }
9495 // verify if row 1 data propagated to readonly duplicated view
95- onAllNodes(hasAnyAncestor(hasTestTag(" field_group_template_[Cars repeating view readonly]" ))).let {
96- verifyEmbeddedDataRecord(
97- nodes = it,
98- expectedDate = LocalDateTime .now().toString().substring(0 , 10 ),
99- isEditable = false
100- )
101- }
96+ val carsReadonlyFieldGroup = " field_group_template_[Cars repeating view readonly]"
97+ verifyFieldGroupItem(
98+ nodes = allDescendantsOf(carsReadonlyFieldGroup),
99+ expectedDate = LocalDateTime .now().toString().substring(0 , 10 ),
100+ isEditable = false
101+ )
102102
103103 // adding row 2
104104 onNodeWithText(" Add" , substring = true ).performScrollTo().performClick()
105-
106105 // enter data in row 2
107106 waitForNodes(" cars 2" , count = 2 )
108- onAllNodes(hasAnyAncestor(hasTestTag( " field_group_template_[Cars repeating view editable] " )) ).let { nodes ->
109- nodes.filter(hasAnyAncestor(hasTestTag( " field_group_item_2" )) ).let {
107+ allDescendantsOf(carsEditableFieldGroup ).let { nodes ->
108+ nodes.filterDescendantsOf( " field_group_item_2" ).let {
110109 it.findFirstWithText(" brand" ).performTextInput(" Ford" )
111110 nodes.findFirstWithText(" cars 2" ).performClick() // remove focus to propagate data
112111 it.findFirstWithText(" Ford" ).assertExists()
113112 }
114113 }
115114 // verify data in row 2 propagated to duplicated
116- onAllNodes(hasAnyAncestor(hasTestTag(" field_group_template_[Cars repeating view readonly]" ))).let { nodes ->
117- nodes.filter(hasAnyAncestor(hasTestTag(" field_group_item_2" ))).let {
118- waitUntilAtLeastOneExists(it, hasText(" Ford" ), timeoutMillis = 5000L )
119- }
115+ allDescendantsOf(carsReadonlyFieldGroup).filterDescendantsOf(" field_group_item_2" ).let {
116+ waitUntilAtLeastOneExists(it, hasText(" Ford" ), timeoutMillis = 5000L )
120117 }
121118
122119 // 2nd step
123120 onNodeWithText(" Next" ).performClick()
124121 waitForNode(" ED repeating view readonly" , substring = true )
125122
126123 // verify row 1 on second step
127- onAllNodes(hasAnyAncestor(hasTestTag(" field_group_template_[Cars repeating view readonly]" ))).let {
128- verifyEmbeddedDataRecord(it, expectedDate = " 2025-12-16" , isEditable = false )
129- }
124+ verifyFieldGroupItem(
125+ allDescendantsOf(carsReadonlyFieldGroup),
126+ expectedDate = " 2025-12-16" ,
127+ isEditable = false
128+ )
130129 }
131130
132131 @Test
@@ -146,6 +145,7 @@ class EmbeddedDataTest : ComposeTest(PegaVersion.v24_2_2) {
146145 " Notes" to " This is a note"
147146 )
148147 val edContext = " caseInfo.content.EmbeddedDataListOfRecords"
148+
149149 // create case
150150 onNodeWithText(" New Service" ).performClick()
151151
@@ -155,7 +155,10 @@ class EmbeddedDataTest : ComposeTest(PegaVersion.v24_2_2) {
155155 // verify table title
156156 waitForNode(" Cars editable table" )
157157 // verify columns
158- columnValues.keys.forEach { waitForNodes(it.uppercase(), count = 2 ) } // despite there is only one table with column names, test sees two of them
158+ columnValues.keys.forEach {
159+ waitForNodes(it.uppercase(), count = 2 )
160+ } // despite there is only one table with column names, test sees two of them
161+
159162 // verify add and delete records
160163 onNodeWithText(" + Add cars" ).performClick()
161164 waitUntilAtLeastOneExists(hasContentDescription(" Delete item 1" ))
@@ -194,16 +197,14 @@ class EmbeddedDataTest : ComposeTest(PegaVersion.v24_2_2) {
194197 // verify columns
195198 columnValues.keys.forEach { waitForNodes(it.uppercase(), count = 2 ) } // despite there is only one table with column names, test sees two of them
196199 // verify table data
197- columnValues.values.forEach {
198- waitForNodes(it, count = 2 )
199- }
200+ columnValues.values.forEach { waitForNodes(it, count = 2 ) }
200201 // verify reorder icon exists
201202 waitUntilAtLeastOneExists(hasContentDescription(" Reorder item 1" ))
202203 // verify edit record popup
203204 onAllNodes(hasContentDescription(" Edit item 1" )).onFirst().performScrollTo().performClick()
204205 waitForNode(" Edit Record" )
205206
206- onAllNodes(hasAnyAncestor(hasTestTag( " ModalViewContainer" )) ).let { nodes ->
207+ allDescendantsOf( " ModalViewContainer" ).let { nodes ->
207208 columnValues.forEach {
208209 nodes.findFirstWithText(it.key).assertExists()
209210 if (it.key != " IsFirstOwner" ) { // not able to check checkbox state
@@ -220,9 +221,10 @@ class EmbeddedDataTest : ComposeTest(PegaVersion.v24_2_2) {
220221 // adding new record via popup
221222 onNodeWithText(" + Add cars" ).performScrollTo().performClick()
222223 waitForNode(" Add Record" )
223- onAllNodes(hasAnyAncestor(hasTestTag( " ModalViewContainer" )) ).let { nodes ->
224+ allDescendantsOf( " ModalViewContainer" ).let { nodes ->
224225 nodes.findFirstWithText(" Submit" ).performScrollTo().performClick()
225- waitUntilAtLeastOneExists(nodes, hasText(" brand: Cannot be blank" ), timeoutMillis = 5000L )
226+ waitUntilAtLeastOneExists(nodes, hasText(" brand: Cannot be blank" ))
227+
226228 nodes.findFirstWithText(" brand" ).performTextReplacement(" Opel" )
227229 nodes.findFirstWithText(" model" ).performTextReplacement(" Astra" )
228230 nodes.findFirstWithText(" Submit" ).performScrollTo().performClick()
@@ -298,21 +300,7 @@ class EmbeddedDataTest : ComposeTest(PegaVersion.v24_2_2) {
298300 waitUntilDoesNotExist(hasContentDescription(" Reorder item 1" ))
299301 }
300302
301- private fun ComposeUiTest.performTextInput (testTag : String , inputText : String ) {
302- waitUntilAtLeastOneExists(hasTestTag(testTag))
303- onAllNodes(hasAnyAncestor(hasTestTag(testTag)))
304- .filter(hasSetTextAction())
305- .onFirst().performTextInput(inputText)
306- }
307-
308- private fun ComposeUiTest.performClick (testTag : String ) {
309- waitUntilAtLeastOneExists(hasTestTag(testTag))
310- onAllNodes(hasAnyAncestor(hasTestTag(testTag)))
311- .filter(hasClickAction())
312- .onFirst().performScrollTo().performClick()
313- }
314-
315- private fun ComposeUiTest.verifyEmbeddedDataRecord (
303+ private fun ComposeUiTest.verifyFieldGroupItem (
316304 nodes : SemanticsNodeInteractionCollection ,
317305 expectedDate : String ,
318306 isEditable : Boolean
@@ -334,19 +322,6 @@ class EmbeddedDataTest : ComposeTest(PegaVersion.v24_2_2) {
334322 }
335323 }
336324
337- private fun SemanticsNodeInteractionCollection.findFirstWithText (text : String ) =
338- this .filter(hasText(text)).onFirst()
339-
340- private fun ComposeUiTest.waitUntilAtLeastOneExists (
341- nodes : SemanticsNodeInteractionCollection ,
342- matcher : SemanticsMatcher ,
343- timeoutMillis : Long = 5000L
344- ) {
345- waitUntil(" exactly 1 nodes match (${matcher.description} )" , timeoutMillis) {
346- nodes.filter(matcher).fetchSemanticsNodes().size == 1
347- }
348- }
349-
350325 private fun ComposeUiTest.verifyReadonlyTable (columnValues : MutableMap <String , String >) {
351326 // verify columns
352327 columnValues.keys.forEach { waitForNodes(it.uppercase(), count = 2 ) }
@@ -363,4 +338,37 @@ class EmbeddedDataTest : ComposeTest(PegaVersion.v24_2_2) {
363338 waitUntilDoesNotExist(hasContentDescription(" Delete item 1" ))
364339 waitUntilDoesNotExist(hasContentDescription(" Reorder item 1" ))
365340 }
341+
342+ private fun ComposeUiTest.performTextInput (testTag : String , inputText : String ) {
343+ waitUntilAtLeastOneExists(hasTestTag(testTag))
344+ onAllNodes(hasAnyAncestor(hasTestTag(testTag)))
345+ .filter(hasSetTextAction())
346+ .onFirst().performTextInput(inputText)
347+ }
348+
349+ private fun ComposeUiTest.performClick (testTag : String ) {
350+ waitUntilAtLeastOneExists(hasTestTag(testTag))
351+ onAllNodes(hasAnyAncestor(hasTestTag(testTag)))
352+ .filter(hasClickAction())
353+ .onFirst().performScrollTo().performClick()
354+ }
355+
356+ private fun SemanticsNodeInteractionCollection.findFirstWithText (text : String ) =
357+ this .filter(hasText(text)).onFirst()
358+
359+ private fun ComposeUiTest.waitUntilAtLeastOneExists (
360+ nodes : SemanticsNodeInteractionCollection ,
361+ matcher : SemanticsMatcher ,
362+ timeoutMillis : Long = 5000L
363+ ) {
364+ waitUntil(" exactly 1 nodes match (${matcher.description} )" , timeoutMillis) {
365+ nodes.filter(matcher).fetchSemanticsNodes().size == 1
366+ }
367+ }
368+
369+ private fun ComposeUiTest.allDescendantsOf (testTag : String ) =
370+ onAllNodes(hasAnyAncestor(hasTestTag(testTag)))
371+
372+ private fun SemanticsNodeInteractionCollection.filterDescendantsOf (testTag : String ) =
373+ filter(hasAnyAncestor(hasTestTag(testTag)))
366374}
0 commit comments