From 779763f17ecf04632c099ef55e1e7efcfe5fec92 Mon Sep 17 00:00:00 2001 From: Nikita Date: Mon, 24 Feb 2025 18:20:33 -0500 Subject: [PATCH] ISSUE-602: Update Kakao lib version to 0.4.5 - with a tests that wouldn't work previously. --- gradle/libs.versions.toml | 8 +-- .../sample/screen/ComposeLazyListScreen.kt | 51 ++++++++++++++ .../sample/screen/ComposeMainScreen.kt | 4 ++ .../sample/test/ComposeLazyListTest.kt | 63 +++++++++++++++++ .../composesupport/sample/MainActivity.kt | 7 +- .../features/lazylist/LazyListScreen.kt | 69 +++++++++++++++++++ .../sample/features/main/MainScreen.kt | 16 ++++- .../composesupport/sample/resources/C.kt | 19 +++++ .../src/main/res/values/strings.xml | 1 + 9 files changed, 231 insertions(+), 7 deletions(-) create mode 100644 samples/kaspresso-compose-support-sample/src/androidTest/kotlin/com/kaspersky/kaspresso/composesupport/sample/screen/ComposeLazyListScreen.kt create mode 100644 samples/kaspresso-compose-support-sample/src/androidTest/kotlin/com/kaspersky/kaspresso/composesupport/sample/test/ComposeLazyListTest.kt create mode 100644 samples/kaspresso-compose-support-sample/src/main/kotlin/com/kaspersky/kaspresso/composesupport/sample/features/lazylist/LazyListScreen.kt diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index ddf54d989..7acca84b0 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,13 +1,13 @@ [versions] -kotlin = "1.8.22" +kotlin = "1.9.25" detekt = "1.21.0" espresso = "3.6.1" kakao = "3.6.2" -kakaoCompose = "0.2.3" +kakaoCompose = "0.4.5" kakaoExtClicks = "1.0.0" allure = "2.4.0" -compose = "1.5.4" -composeCompiler = "1.4.8" +compose = "1.7.8" +composeCompiler = "1.5.15" activityCompose = "1.4.0" androidXTest = "1.6.1" testOrchestrator = "1.4.2" diff --git a/samples/kaspresso-compose-support-sample/src/androidTest/kotlin/com/kaspersky/kaspresso/composesupport/sample/screen/ComposeLazyListScreen.kt b/samples/kaspresso-compose-support-sample/src/androidTest/kotlin/com/kaspersky/kaspresso/composesupport/sample/screen/ComposeLazyListScreen.kt new file mode 100644 index 000000000..7752517ed --- /dev/null +++ b/samples/kaspresso-compose-support-sample/src/androidTest/kotlin/com/kaspersky/kaspresso/composesupport/sample/screen/ComposeLazyListScreen.kt @@ -0,0 +1,51 @@ +package com.kaspersky.kaspresso.composesupport.sample.screen + +import androidx.compose.ui.semantics.SemanticsNode +import androidx.compose.ui.test.SemanticsMatcher +import androidx.compose.ui.test.SemanticsNodeInteractionsProvider +import com.kaspersky.kaspresso.composesupport.sample.features.lazylist.ListItemPositionSemantics +import com.kaspersky.kaspresso.composesupport.sample.features.lazylist.ListLengthSemantics +import com.kaspersky.kaspresso.composesupport.sample.resources.C +import io.github.kakaocup.compose.node.element.ComposeScreen +import io.github.kakaocup.compose.node.element.KNode +import io.github.kakaocup.compose.node.element.lazylist.KLazyListItemNode +import io.github.kakaocup.compose.node.element.lazylist.KLazyListNode + +class ComposeLazyListScreen(semanticsProvider: SemanticsNodeInteractionsProvider) : +ComposeScreen( +semanticsProvider = semanticsProvider, +) { + val list: KLazyListNode = + KLazyListNode( + semanticsProvider = semanticsProvider, + viewBuilderAction = { hasTestTag(C.Tag.scroll_screen_multi_text_list) }, + itemTypeBuilder = { + itemType(::LazyListScreenItemNode) + }, + positionMatcher = { position -> SemanticsMatcher.expectValue(ListItemPositionSemantics, position) }, + lengthSemanticsPropertyKey = ListLengthSemantics + ) +} +class LazyListScreenItemNode( + semanticsNode: SemanticsNode, + semanticsProvider: SemanticsNodeInteractionsProvider +) : KLazyListItemNode( + semanticsNode, + semanticsProvider +) { + val text1: KNode = + child { + useUnmergedTree = true + hasTestTag(C.Tag.multi_text_text1) + } + val text2: KNode = + child { + useUnmergedTree = true + hasTestTag(C.Tag.multi_text_text2) + } + val text3: KNode = + child { + useUnmergedTree = true + hasTestTag(C.Tag.multi_text_text3) + } +} diff --git a/samples/kaspresso-compose-support-sample/src/androidTest/kotlin/com/kaspersky/kaspresso/composesupport/sample/screen/ComposeMainScreen.kt b/samples/kaspresso-compose-support-sample/src/androidTest/kotlin/com/kaspersky/kaspresso/composesupport/sample/screen/ComposeMainScreen.kt index b2f9252d1..d38799d0c 100644 --- a/samples/kaspresso-compose-support-sample/src/androidTest/kotlin/com/kaspersky/kaspresso/composesupport/sample/screen/ComposeMainScreen.kt +++ b/samples/kaspresso-compose-support-sample/src/androidTest/kotlin/com/kaspersky/kaspresso/composesupport/sample/screen/ComposeMainScreen.kt @@ -22,4 +22,8 @@ class ComposeMainScreen(semanticsProvider: SemanticsNodeInteractionsProvider) : val scrollButton: KNode = child { hasTestTag(C.Tag.main_screen_scroll_button) } + + val lazyListButton: KNode = child { + hasTestTag(C.Tag.main_screen_lazy_list_button) + } } diff --git a/samples/kaspresso-compose-support-sample/src/androidTest/kotlin/com/kaspersky/kaspresso/composesupport/sample/test/ComposeLazyListTest.kt b/samples/kaspresso-compose-support-sample/src/androidTest/kotlin/com/kaspersky/kaspresso/composesupport/sample/test/ComposeLazyListTest.kt new file mode 100644 index 000000000..27fa2b7a0 --- /dev/null +++ b/samples/kaspresso-compose-support-sample/src/androidTest/kotlin/com/kaspersky/kaspresso/composesupport/sample/test/ComposeLazyListTest.kt @@ -0,0 +1,63 @@ +package com.kaspersky.kaspresso.composesupport.sample.test + +import androidx.compose.ui.test.ExperimentalTestApi +import androidx.compose.ui.test.junit4.createAndroidComposeRule +import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.kaspersky.components.composesupport.config.withComposeSupport +import com.kaspersky.kaspresso.composesupport.sample.MainActivity +import com.kaspersky.kaspresso.composesupport.sample.resources.C +import com.kaspersky.kaspresso.composesupport.sample.screen.ComposeLazyListScreen +import com.kaspersky.kaspresso.composesupport.sample.screen.ComposeMainScreen +import com.kaspersky.kaspresso.composesupport.sample.screen.LazyListScreenItemNode +import com.kaspersky.kaspresso.kaspresso.Kaspresso +import com.kaspersky.kaspresso.testcases.api.testcase.TestCase +import io.github.kakaocup.compose.node.element.ComposeScreen.Companion.onComposeScreen +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith + +@RunWith(AndroidJUnit4::class) +class ComposeLazyListTest : TestCase( + kaspressoBuilder = Kaspresso.Builder.withComposeSupport() +) { + + @get:Rule + val composeTestRule = createAndroidComposeRule() + + @OptIn(ExperimentalTestApi::class) + @Test + fun test() = run { + step("Open LazyList screen") { + onComposeScreen(composeTestRule) { + lazyListButton { + performClick() + } + } + } + step("Verify Lazy List") { + onComposeScreen(composeTestRule) { + list { + assertIsDisplayed() + assertLengthEquals(C.Tag.scroll_screen_multi_text_items.size) + + repeat(C.Tag.scroll_screen_multi_text_items.size) { i -> + childAt(i) { + text1 { + assertIsDisplayed() + assertTextContains("text1_$i") + } + text2 { + assertIsDisplayed() + assertTextContains("text2_$i") + } + text3 { + assertIsDisplayed() + assertTextContains("text3_$i") + } + } + } + } + } + } + } +} diff --git a/samples/kaspresso-compose-support-sample/src/main/kotlin/com/kaspersky/kaspresso/composesupport/sample/MainActivity.kt b/samples/kaspresso-compose-support-sample/src/main/kotlin/com/kaspersky/kaspresso/composesupport/sample/MainActivity.kt index e7315e32f..8abadce6d 100644 --- a/samples/kaspresso-compose-support-sample/src/main/kotlin/com/kaspersky/kaspresso/composesupport/sample/MainActivity.kt +++ b/samples/kaspresso-compose-support-sample/src/main/kotlin/com/kaspersky/kaspresso/composesupport/sample/MainActivity.kt @@ -10,6 +10,7 @@ import androidx.navigation.compose.composable import androidx.navigation.compose.rememberNavController import com.kaspersky.kaspresso.composesupport.sample.features.flaky.SimpleFlakyScreen import com.kaspersky.kaspresso.composesupport.sample.features.flaky.SimpleFlakyViewModel +import com.kaspersky.kaspresso.composesupport.sample.features.lazylist.LazyListScreen import com.kaspersky.kaspresso.composesupport.sample.features.main.MainScreen import com.kaspersky.kaspresso.composesupport.sample.features.sanityflaky.SanityFlakyScreen import com.kaspersky.kaspresso.composesupport.sample.features.sanityflaky.SanityFlakyViewModel @@ -36,7 +37,8 @@ class MainActivity : AppCompatActivity() { MainScreen( simpleFlakyClick = { navController.navigate(C.Screen.simple_flaky_screen) }, sanityFlakyClick = { navController.navigate(C.Screen.sanity_flaky_screen) }, - scrollClick = { navController.navigate(C.Screen.scroll_screen) } + scrollClick = { navController.navigate(C.Screen.scroll_screen) }, + lazyListClick = { navController.navigate(C.Screen.lazy_list) } ) } @@ -57,6 +59,9 @@ class MainActivity : AppCompatActivity() { SanityFlakyScreen(sanityFlakyStateLiveData = sanityFlakyViewModel.sanityFlakyStateLiveData, firstButtonClick = { sanityFlakyViewModel.firstButtonClick() }) } + composable(C.Screen.lazy_list) { + LazyListScreen() + } } } } diff --git a/samples/kaspresso-compose-support-sample/src/main/kotlin/com/kaspersky/kaspresso/composesupport/sample/features/lazylist/LazyListScreen.kt b/samples/kaspresso-compose-support-sample/src/main/kotlin/com/kaspersky/kaspresso/composesupport/sample/features/lazylist/LazyListScreen.kt new file mode 100644 index 000000000..2e2025897 --- /dev/null +++ b/samples/kaspresso-compose-support-sample/src/main/kotlin/com/kaspersky/kaspresso/composesupport/sample/features/lazylist/LazyListScreen.kt @@ -0,0 +1,69 @@ +package com.kaspersky.kaspresso.composesupport.sample.features.lazylist + +import androidx.compose.foundation.BorderStroke +import androidx.compose.foundation.border +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.wrapContentSize +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.itemsIndexed +import androidx.compose.material.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.platform.testTag +import androidx.compose.ui.semantics.SemanticsPropertyKey +import androidx.compose.ui.semantics.SemanticsPropertyReceiver +import androidx.compose.ui.semantics.semantics +import androidx.compose.ui.semantics.testTag +import androidx.compose.ui.unit.dp +import com.kaspersky.kaspresso.composesupport.sample.resources.C + +@Composable +fun LazyListScreen() { + LazyColumn( + modifier = Modifier + .fillMaxSize() + .padding(8.dp) + .testTag(C.Tag.scroll_screen_multi_text_list) + .lazyListLength(C.Tag.scroll_screen_multi_text_items.size) + .semantics { testTag = C.Tag.scroll_screen_multi_text } + + ) { + itemsIndexed( + C.Tag.scroll_screen_multi_text_items + ) { index, item -> + Row(modifier = Modifier.lazyListItemPosition(index).padding(8.dp).border(BorderStroke(1.dp, Color.Green))) { + Column( + modifier = Modifier.fillMaxWidth().wrapContentSize().padding(8.dp) + ) { + Text( + text = item.text1, + modifier = Modifier.testTag(C.Tag.multi_text_text1) + ) + Text( + text = item.text2, + modifier = Modifier.testTag(C.Tag.multi_text_text2) + ) + Text( + text = item.text3, + modifier = Modifier.testTag(C.Tag.multi_text_text3) + ) + } + } + } + } +} + +val ListItemPositionSemantics: SemanticsPropertyKey = SemanticsPropertyKey("ListItemPosition") +var SemanticsPropertyReceiver.lazyListItemPosition: Int by ListItemPositionSemantics + +fun Modifier.lazyListItemPosition(position: Int): Modifier = semantics { lazyListItemPosition = position } + +val ListLengthSemantics: SemanticsPropertyKey = SemanticsPropertyKey("ListLength") +var SemanticsPropertyReceiver.lazyListLength: Int by ListLengthSemantics + +fun Modifier.lazyListLength(length: Int): Modifier = semantics { lazyListLength = length } diff --git a/samples/kaspresso-compose-support-sample/src/main/kotlin/com/kaspersky/kaspresso/composesupport/sample/features/main/MainScreen.kt b/samples/kaspresso-compose-support-sample/src/main/kotlin/com/kaspersky/kaspresso/composesupport/sample/features/main/MainScreen.kt index 6c283761b..e59544cc5 100644 --- a/samples/kaspresso-compose-support-sample/src/main/kotlin/com/kaspersky/kaspresso/composesupport/sample/features/main/MainScreen.kt +++ b/samples/kaspresso-compose-support-sample/src/main/kotlin/com/kaspersky/kaspresso/composesupport/sample/features/main/MainScreen.kt @@ -23,7 +23,8 @@ import com.kaspersky.kaspresso.composesupport.sample.resources.C fun MainScreen( simpleFlakyClick: () -> Unit, sanityFlakyClick: () -> Unit, - scrollClick: () -> Unit + scrollClick: () -> Unit, + lazyListClick: () -> Unit ) { Column( modifier = Modifier @@ -62,6 +63,16 @@ fun MainScreen( }, onClick = scrollClick, ) + + Button( + modifier = Modifier + .fillMaxWidth() + .semantics { testTag = C.Tag.main_screen_lazy_list_button }, + content = { + Text(text = stringResource(id = R.string.main_screen_lazy_list_button)) + }, + onClick = lazyListClick, + ) } } @@ -72,7 +83,8 @@ private fun MainScreenPreview() { MainScreen( simpleFlakyClick = { }, sanityFlakyClick = { }, - scrollClick = { } + scrollClick = { }, + lazyListClick = { } ) } } diff --git a/samples/kaspresso-compose-support-sample/src/main/kotlin/com/kaspersky/kaspresso/composesupport/sample/resources/C.kt b/samples/kaspresso-compose-support-sample/src/main/kotlin/com/kaspersky/kaspresso/composesupport/sample/resources/C.kt index 97fe70727..04987050a 100644 --- a/samples/kaspresso-compose-support-sample/src/main/kotlin/com/kaspersky/kaspresso/composesupport/sample/resources/C.kt +++ b/samples/kaspresso-compose-support-sample/src/main/kotlin/com/kaspersky/kaspresso/composesupport/sample/resources/C.kt @@ -7,6 +7,7 @@ object C { const val main_screen_simple_flaky_button = "main_screen_simple_flaky_button" const val main_screen_scroll_button = "main_screen_scroll_button" const val main_screen_sanity_flaky_button = "main_screen_sanity_flaky_button" + const val main_screen_lazy_list_button = "main_screen_lazy_list_button" const val simple_flaky_screen_container = "simple_flaky_screen_container" const val simple_flaky_screen_simple_first_button = "simple_flaky_screen_simple_first_button" @@ -18,15 +19,33 @@ object C { const val sanity_flaky_screen_simple_second_button = "sanity_flaky_screen_simple_second_button" const val scroll_screen_container = "scroll_screen_container" + const val scroll_screen_multi_text = "scroll_screen_multi_text" + const val scroll_screen_multi_text_list = "scroll_screen_multi_text_list" + + const val multi_text_text1 = "multi_text_text1" + const val multi_text_text2 = "multi_text_text2" + const val multi_text_text3 = "multi_text_text3" + val scroll_screen_buttons = MutableList(30) { "button_${it}" } + + val scroll_screen_multi_text_items = MutableList(30) { + MultiTextTestData( "text1_${it}", "text2_${it}", "text3_${it}") + } } + data class MultiTextTestData( + val text1: String, + val text2: String, + val text3: String + ) + object Screen { const val main_screen = "main_screen" const val simple_flaky_screen = "simple_flaky_screen" const val sanity_flaky_screen = "sanity_flaky_screen" const val scroll_screen = "scroll_screen" + const val lazy_list = "lazy_list" } } diff --git a/samples/kaspresso-compose-support-sample/src/main/res/values/strings.xml b/samples/kaspresso-compose-support-sample/src/main/res/values/strings.xml index 93f4424c1..c6d91c8d0 100644 --- a/samples/kaspresso-compose-support-sample/src/main/res/values/strings.xml +++ b/samples/kaspresso-compose-support-sample/src/main/res/values/strings.xml @@ -4,6 +4,7 @@ Simple flaky sample Sanity flaky sample Scroll button + LazyList button First button Second button