Browse Source

Add common test samples to widgets-gallery (#4202)

pull/4382/head
Alexander Maryanovsky 5 months ago committed by GitHub
parent
commit
69d3a24295
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 3
      examples/widgets-gallery/gradle.properties
  2. 49
      examples/widgets-gallery/shared/build.gradle.kts
  3. 0
      examples/widgets-gallery/shared/src/commonMain/composeResources/drawable/ic_instagram.xml
  4. 0
      examples/widgets-gallery/shared/src/commonMain/composeResources/drawable/ic_send.xml
  5. 0
      examples/widgets-gallery/shared/src/commonMain/composeResources/drawable/ic_twitter.xml
  6. 0
      examples/widgets-gallery/shared/src/commonMain/composeResources/drawable/p1.jpeg
  7. 0
      examples/widgets-gallery/shared/src/commonMain/composeResources/drawable/p2.jpeg
  8. 0
      examples/widgets-gallery/shared/src/commonMain/composeResources/drawable/p3.jpeg
  9. 0
      examples/widgets-gallery/shared/src/commonMain/composeResources/drawable/p6.jpeg
  10. 0
      examples/widgets-gallery/shared/src/commonMain/composeResources/values/strings.xml
  11. 9
      examples/widgets-gallery/shared/src/commonMain/kotlin/org/jetbrains/compose/demo/widgets/platform/Res.kt
  12. 6
      examples/widgets-gallery/shared/src/commonMain/kotlin/org/jetbrains/compose/demo/widgets/ui/MainView.kt
  13. 3
      examples/widgets-gallery/shared/src/commonMain/kotlin/org/jetbrains/compose/demo/widgets/ui/WidgetView.kt
  14. 5
      examples/widgets-gallery/shared/src/commonMain/kotlin/org/jetbrains/compose/demo/widgets/ui/WidgetsType.kt
  15. 37
      examples/widgets-gallery/shared/src/commonMain/kotlin/org/jetbrains/compose/demo/widgets/ui/screens/AppBars.kt
  16. 4
      examples/widgets-gallery/shared/src/commonMain/kotlin/org/jetbrains/compose/demo/widgets/ui/screens/Buttons.kt
  17. 78
      examples/widgets-gallery/shared/src/commonMain/kotlin/org/jetbrains/compose/demo/widgets/ui/screens/Chips.kt
  18. 33
      examples/widgets-gallery/shared/src/commonMain/kotlin/org/jetbrains/compose/demo/widgets/ui/screens/Loaders.kt
  19. 48
      examples/widgets-gallery/shared/src/commonMain/kotlin/org/jetbrains/compose/demo/widgets/ui/screens/SnackBars.kt
  20. 123
      examples/widgets-gallery/shared/src/commonMain/kotlin/org/jetbrains/compose/demo/widgets/ui/screens/TextInputs.kt
  21. 5
      examples/widgets-gallery/shared/src/commonMain/kotlin/org/jetbrains/compose/demo/widgets/ui/screens/Texts.kt
  22. 4
      examples/widgets-gallery/shared/src/commonMain/kotlin/org/jetbrains/compose/demo/widgets/ui/screens/Toggles.kt
  23. 167
      examples/widgets-gallery/shared/src/commonMain/kotlin/org/jetbrains/compose/demo/widgets/ui/screens/UICards.kt
  24. 9
      examples/widgets-gallery/shared/src/commonMain/kotlin/org/jetbrains/compose/demo/widgets/ui/utils/ResizablePanel.kt
  25. 34
      examples/widgets-gallery/shared/src/commonTest/kotlin/ExampleTest.kt
  26. 28
      examples/widgets-gallery/shared/src/commonTest/kotlin/WidgetsPanelTest.kt

3
examples/widgets-gallery/gradle.properties

@ -10,4 +10,5 @@ kotlin.mpp.androidSourceSetLayoutVersion=2
kotlin.native.binary.memoryModel=experimental kotlin.native.binary.memoryModel=experimental
kotlin.version=1.9.21 kotlin.version=1.9.21
agp.version=8.0.2 agp.version=8.0.2
compose.version=1.5.11 # Replace this with release version when it comes out
compose.version=1.6.0-dev1397

49
examples/widgets-gallery/shared/build.gradle.kts

@ -1,4 +1,5 @@
@file:Suppress("OPT_IN_IS_NOT_ENABLED") import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSetTree
plugins { plugins {
kotlin("multiplatform") kotlin("multiplatform")
@ -9,7 +10,19 @@ plugins {
version = "1.0-SNAPSHOT" version = "1.0-SNAPSHOT"
kotlin { kotlin {
androidTarget() androidTarget {
@OptIn(ExperimentalKotlinGradlePluginApi::class)
instrumentedTestVariant {
sourceSetTree.set(KotlinSourceSetTree.test)
dependencies {
// Remove the dependency on ui-test-junit4-android when 1.7.0 is released,
// as the needed classes in will have moved to ui-test
implementation("androidx.compose.ui:ui-test-junit4-android:1.6.0")
debugImplementation("androidx.compose.ui:ui-test-manifest")
}
}
}
jvm("desktop") jvm("desktop")
@ -32,33 +45,34 @@ kotlin {
implementation(compose.material) implementation(compose.material)
implementation(compose.materialIconsExtended) implementation(compose.materialIconsExtended)
@OptIn(org.jetbrains.compose.ExperimentalComposeLibrary::class) @OptIn(org.jetbrains.compose.ExperimentalComposeLibrary::class)
implementation("org.jetbrains.compose.components:components-resources:1.6.0-dev1306") implementation("org.jetbrains.compose.components:components-resources:${project.property("compose.version")}")
} }
} }
val androidMain by getting { val androidMain by getting {
dependencies { dependencies {
api("androidx.activity:activity-compose:1.7.2") api("androidx.activity:activity-compose:1.8.2")
api("androidx.appcompat:appcompat:1.6.1") api("androidx.appcompat:appcompat:1.6.1")
api("androidx.core:core-ktx:1.10.1") api("androidx.core:core-ktx:1.12.0")
} }
} }
val iosMain by creating {
dependsOn(commonMain)
}
val iosX64Main by getting {
dependsOn(iosMain)
}
val iosArm64Main by getting {
dependsOn(iosMain)
}
val iosSimulatorArm64Main by getting {
dependsOn(iosMain)
}
val desktopMain by getting { val desktopMain by getting {
dependencies { dependencies {
implementation(compose.desktop.common) implementation(compose.desktop.common)
} }
} }
val desktopTest by getting {
dependencies {
implementation(compose.desktop.currentOs)
}
}
val commonTest by getting {
dependencies {
implementation(kotlin("test"))
@OptIn(org.jetbrains.compose.ExperimentalComposeLibrary::class)
implementation(compose.uiTest)
}
}
} }
} }
@ -71,6 +85,7 @@ android {
defaultConfig { defaultConfig {
minSdk = 26 minSdk = 26
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
} }
compileOptions { compileOptions {
sourceCompatibility = JavaVersion.VERSION_17 sourceCompatibility = JavaVersion.VERSION_17

0
examples/widgets-gallery/shared/src/commonMain/resources/composeRes/images/ic_instagram.xml → examples/widgets-gallery/shared/src/commonMain/composeResources/drawable/ic_instagram.xml

0
examples/widgets-gallery/shared/src/commonMain/resources/composeRes/images/ic_send.xml → examples/widgets-gallery/shared/src/commonMain/composeResources/drawable/ic_send.xml

0
examples/widgets-gallery/shared/src/commonMain/resources/composeRes/images/ic_twitter.xml → examples/widgets-gallery/shared/src/commonMain/composeResources/drawable/ic_twitter.xml

0
examples/widgets-gallery/shared/src/commonMain/resources/composeRes/images/p1.jpeg → examples/widgets-gallery/shared/src/commonMain/composeResources/drawable/p1.jpeg

Before

Width:  |  Height:  |  Size: 7.0 KiB

After

Width:  |  Height:  |  Size: 7.0 KiB

0
examples/widgets-gallery/shared/src/commonMain/resources/composeRes/images/p2.jpeg → examples/widgets-gallery/shared/src/commonMain/composeResources/drawable/p2.jpeg

Before

Width:  |  Height:  |  Size: 4.9 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

0
examples/widgets-gallery/shared/src/commonMain/resources/composeRes/images/p3.jpeg → examples/widgets-gallery/shared/src/commonMain/composeResources/drawable/p3.jpeg

Before

Width:  |  Height:  |  Size: 5.6 KiB

After

Width:  |  Height:  |  Size: 5.6 KiB

0
examples/widgets-gallery/shared/src/commonMain/resources/composeRes/images/p6.jpeg → examples/widgets-gallery/shared/src/commonMain/composeResources/drawable/p6.jpeg

Before

Width:  |  Height:  |  Size: 5.7 KiB

After

Width:  |  Height:  |  Size: 5.7 KiB

0
examples/widgets-gallery/shared/src/commonMain/resources/composeRes/values/strings.xml → examples/widgets-gallery/shared/src/commonMain/composeResources/values/strings.xml

9
examples/widgets-gallery/shared/src/commonMain/kotlin/org/jetbrains/compose/demo/widgets/platform/Res.kt

@ -1,9 +0,0 @@
package org.jetbrains.compose.demo.widgets.platform
object Res {
object strings {
val spotify_nav_home = "Home"
val spotify_nav_search = "Search"
val spotify_nav_library = "Your Library"
}
}

6
examples/widgets-gallery/shared/src/commonMain/kotlin/org/jetbrains/compose/demo/widgets/ui/MainView.kt

@ -20,6 +20,7 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clipToBounds import androidx.compose.ui.draw.clipToBounds
import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.semantics.Role import androidx.compose.ui.semantics.Role
import androidx.compose.ui.semantics.SemanticsProperties import androidx.compose.ui.semantics.SemanticsProperties
import androidx.compose.ui.semantics.semantics import androidx.compose.ui.semantics.semantics
@ -115,6 +116,10 @@ private fun WidgetsListView(widgetsTypeState: MutableState<WidgetsType>) {
} }
val WidgetsType.listItemTestTag: String
get() = "${testTag}_list_item"
@Composable @Composable
private fun WidgetsListItemViewImpl( private fun WidgetsListItemViewImpl(
widgetsType: WidgetsType, widgetsType: WidgetsType,
@ -133,6 +138,7 @@ private fun WidgetsListItemViewImpl(
} }
.height(height) .height(height)
.padding(start = 16.dp) .padding(start = 16.dp)
.testTag(widgetsType.listItemTestTag)
) { ) {
val inFocusInteractionSource = remember { MutableInteractionSource() } val inFocusInteractionSource = remember { MutableInteractionSource() }
val inFocus by inFocusInteractionSource.collectIsHoveredAsState() val inFocus by inFocusInteractionSource.collectIsHoveredAsState()

3
examples/widgets-gallery/shared/src/commonMain/kotlin/org/jetbrains/compose/demo/widgets/ui/WidgetView.kt

@ -2,7 +2,6 @@ package org.jetbrains.compose.demo.widgets.ui
import androidx.compose.foundation.gestures.detectTapGestures import androidx.compose.foundation.gestures.detectTapGestures
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll import androidx.compose.foundation.verticalScroll
@ -19,7 +18,7 @@ fun WidgetsView(
modifier: Modifier modifier: Modifier
) { ) {
ClearFocusBox { ClearFocusBox {
Column(modifier = modifier.verticalScroll(state = rememberScrollState())) { Box(modifier = modifier.verticalScroll(state = rememberScrollState())) {
@Suppress("UNUSED_VARIABLE") @Suppress("UNUSED_VARIABLE")
val exhaustive = when (widgetsTypeState.value) { val exhaustive = when (widgetsTypeState.value) {
WidgetsType.APP_BARS -> AppBars() WidgetsType.APP_BARS -> AppBars()

5
examples/widgets-gallery/shared/src/commonMain/kotlin/org/jetbrains/compose/demo/widgets/ui/WidgetsType.kt

@ -24,9 +24,12 @@ enum class WidgetsType(private val customTitle: String? = null) {
val title: String val title: String
get() = customTitle ?: readableName get() = customTitle ?: readableName
val testTag: String
get() = name.lowercase()
companion object { companion object {
val sortedValues: List<WidgetsType> by lazy { val sortedValues: List<WidgetsType> by lazy {
values().sortedBy { it.name } entries.sortedBy { it.name }
} }
} }
} }

37
examples/widgets-gallery/shared/src/commonMain/kotlin/org/jetbrains/compose/demo/widgets/ui/screens/AppBars.kt

@ -5,7 +5,8 @@ import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.* import androidx.compose.material.*
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowBack import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material.icons.automirrored.outlined.ReadMore
import androidx.compose.material.icons.filled.MoreHoriz import androidx.compose.material.icons.filled.MoreHoriz
import androidx.compose.material.icons.filled.StarBorder import androidx.compose.material.icons.filled.StarBorder
import androidx.compose.material.icons.outlined.* import androidx.compose.material.icons.outlined.*
@ -14,20 +15,24 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.clip
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import org.jetbrains.compose.demo.widgets.platform.Res
import org.jetbrains.compose.resources.painterResource import org.jetbrains.compose.resources.painterResource
import org.jetbrains.compose.demo.widgets.theme.twitterColor import org.jetbrains.compose.demo.widgets.theme.twitterColor
import org.jetbrains.compose.demo.widgets.ui.WidgetsType
import org.jetbrains.compose.demo.widgets.ui.utils.SubtitleText import org.jetbrains.compose.demo.widgets.ui.utils.SubtitleText
import org.jetbrains.compose.demo.widgets.ui.utils.TitleText import org.jetbrains.compose.demo.widgets.ui.utils.TitleText
import org.jetbrains.compose.resources.ExperimentalResourceApi import org.jetbrains.compose.resources.ExperimentalResourceApi
import org.jetbrains.compose.resources.ImageResource import org.jetbrains.compose.resources.stringResource
import widgets_gallery.shared.generated.resources.Res
@Composable @Composable
fun AppBars() { fun AppBars() {
TopAppBarsDemo() Column(Modifier.testTag(WidgetsType.APP_BARS.testTag)) {
BottomAppBarDemo() TopAppBarsDemo()
NavigationBarDemo() BottomAppBarDemo()
NavigationBarDemo()
}
} }
@OptIn(ExperimentalResourceApi::class) @OptIn(ExperimentalResourceApi::class)
@ -40,7 +45,7 @@ private fun TopAppBarsDemo() {
elevation = 8.dp, elevation = 8.dp,
navigationIcon = { navigationIcon = {
IconButton(onClick = {}) { IconButton(onClick = {}) {
Icon(Icons.Default.ArrowBack, contentDescription = "ArrowBack") Icon(Icons.AutoMirrored.Default.ArrowBack, contentDescription = "ArrowBack")
} }
} }
) )
@ -54,12 +59,12 @@ private fun TopAppBarsDemo() {
elevation = 8.dp, elevation = 8.dp,
navigationIcon = { navigationIcon = {
IconButton(onClick = {}) { IconButton(onClick = {}) {
Icon(painterResource(ImageResource("composeRes/images/ic_instagram.xml")), contentDescription = "Instagram") Icon(painterResource(Res.drawable.ic_instagram), contentDescription = "Instagram")
} }
}, },
actions = { actions = {
IconButton(onClick = {}) { IconButton(onClick = {}) {
Icon(painterResource(ImageResource("composeRes/images/ic_send.xml")), contentDescription = "Send") Icon(painterResource(Res.drawable.ic_send), contentDescription = "Send")
} }
} }
) )
@ -69,7 +74,7 @@ private fun TopAppBarsDemo() {
TopAppBar( TopAppBar(
title = { title = {
Icon( Icon(
painterResource(ImageResource("composeRes/images/ic_twitter.xml")), painterResource(Res.drawable.ic_twitter),
contentDescription = "Twitter", contentDescription = "Twitter",
tint = twitterColor, tint = twitterColor,
modifier = Modifier.fillMaxWidth() modifier = Modifier.fillMaxWidth()
@ -80,7 +85,7 @@ private fun TopAppBarsDemo() {
elevation = 8.dp, elevation = 8.dp,
navigationIcon = { navigationIcon = {
Image( Image(
painterResource(ImageResource("composeRes/images/p6.jpeg")), painterResource(Res.drawable.p6),
contentDescription = "", contentDescription = "",
modifier = Modifier.padding(vertical = 4.dp, horizontal = 8.dp) modifier = Modifier.padding(vertical = 4.dp, horizontal = 8.dp)
.requiredSize(32.dp).clip(CircleShape) .requiredSize(32.dp).clip(CircleShape)
@ -100,7 +105,7 @@ private fun TopAppBarsDemo() {
@Composable @Composable
private fun BottomAppBarDemo() { private fun BottomAppBarDemo() {
Spacer(modifier = Modifier.height(16.dp)) Spacer(modifier = Modifier.height(16.dp))
SubtitleText("Bottom app bars: Note bottom app bar support FAB cutouts when used with scafolds see demoUI crypto app") SubtitleText("Bottom app bars: Note bottom app bar support FAB cutouts when used with scaffolds see demoUI crypto app")
BottomAppBar( BottomAppBar(
cutoutShape = CircleShape cutoutShape = CircleShape
@ -123,19 +128,19 @@ private fun NavigationBarDemo() {
icon = { Icon(Icons.Outlined.Home, contentDescription = "Home") }, icon = { Icon(Icons.Outlined.Home, contentDescription = "Home") },
selected = navItemState.value == NavType.HOME, selected = navItemState.value == NavType.HOME,
onClick = { navItemState.value = NavType.HOME }, onClick = { navItemState.value = NavType.HOME },
label = { Text(text = Res.strings.spotify_nav_home) }, label = { Text(text = stringResource(Res.string.spotify_nav_home)) },
) )
BottomNavigationItem( BottomNavigationItem(
icon = { Icon(Icons.Outlined.Search, contentDescription = "Search") }, icon = { Icon(Icons.Outlined.Search, contentDescription = "Search") },
selected = navItemState.value == NavType.SEARCH, selected = navItemState.value == NavType.SEARCH,
onClick = { navItemState.value = NavType.SEARCH }, onClick = { navItemState.value = NavType.SEARCH },
label = { Text(text = Res.strings.spotify_nav_search) } label = { Text(text = stringResource(Res.string.spotify_nav_search)) }
) )
BottomNavigationItem( BottomNavigationItem(
icon = { Icon(Icons.Outlined.LibraryMusic, contentDescription = "LibraryMusic") }, icon = { Icon(Icons.Outlined.LibraryMusic, contentDescription = "LibraryMusic") },
selected = navItemState.value == NavType.LIBRARY, selected = navItemState.value == NavType.LIBRARY,
onClick = { navItemState.value = NavType.LIBRARY }, onClick = { navItemState.value = NavType.LIBRARY },
label = { Text(text = Res.strings.spotify_nav_library) } label = { Text(text = stringResource(Res.string.spotify_nav_library)) }
) )
} }
@ -143,7 +148,7 @@ private fun NavigationBarDemo() {
BottomNavigation { BottomNavigation {
BottomNavigationItem( BottomNavigationItem(
icon = { Icon(Icons.Outlined.ReadMore, contentDescription = "ReadMore") }, icon = { Icon(Icons.AutoMirrored.Outlined.ReadMore, contentDescription = "ReadMore") },
selected = navItemState.value == NavType.HOME, selected = navItemState.value == NavType.HOME,
onClick = { navItemState.value = NavType.HOME }, onClick = { navItemState.value = NavType.HOME },
) )

4
examples/widgets-gallery/shared/src/commonMain/kotlin/org/jetbrains/compose/demo/widgets/ui/screens/Buttons.kt

@ -14,14 +14,16 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Brush import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import org.jetbrains.compose.demo.widgets.theme.purple import org.jetbrains.compose.demo.widgets.theme.purple
import org.jetbrains.compose.demo.widgets.theme.purple200 import org.jetbrains.compose.demo.widgets.theme.purple200
import org.jetbrains.compose.demo.widgets.theme.typography import org.jetbrains.compose.demo.widgets.theme.typography
import org.jetbrains.compose.demo.widgets.ui.WidgetsType
@Composable @Composable
fun Buttons() { fun Buttons() {
Column { Column(Modifier.testTag(WidgetsType.BUTTONS.testTag)) {
Button(onClick = {}, modifier = Modifier.padding(8.dp)) { Button(onClick = {}, modifier = Modifier.padding(8.dp)) {
Text(text = "Main Button") Text(text = "Main Button")
} }

78
examples/widgets-gallery/shared/src/commonMain/kotlin/org/jetbrains/compose/demo/widgets/ui/screens/Chips.kt

@ -13,44 +13,62 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import org.jetbrains.compose.demo.widgets.ui.WidgetsType
import org.jetbrains.compose.resources.painterResource import org.jetbrains.compose.resources.painterResource
import org.jetbrains.compose.demo.widgets.ui.utils.SubtitleText import org.jetbrains.compose.demo.widgets.ui.utils.SubtitleText
import org.jetbrains.compose.resources.DrawableResource
import org.jetbrains.compose.resources.ExperimentalResourceApi import org.jetbrains.compose.resources.ExperimentalResourceApi
import org.jetbrains.compose.resources.ImageResource import widgets_gallery.shared.generated.resources.Res
@OptIn(ExperimentalResourceApi::class)
@Composable @Composable
fun Chips() { fun Chips() {
// There is no in-built chips but you can make yours like below Column(Modifier.testTag(WidgetsType.CHIPS.testTag)) {
SubtitleText(subtitle = "Custom chips with surface") // There is no in-built chips but you can make yours like below
Column(modifier = Modifier.padding(8.dp)) { SubtitleText(subtitle = "Custom chips with surface")
YoutubeChip(selected = true, text = "Chip", modifier = Modifier.padding(horizontal = 8.dp)) Column(modifier = Modifier.padding(8.dp)) {
Spacer(modifier = Modifier.padding(8.dp)) YoutubeChip(
YoutubeChip( selected = true,
selected = false, text = "Chip",
text = "Inactive", modifier = Modifier.padding(horizontal = 8.dp)
modifier = Modifier.padding(horizontal = 8.dp) )
) Spacer(modifier = Modifier.padding(8.dp))
Spacer(modifier = Modifier.padding(8.dp)) YoutubeChip(
CustomImageChip(text = "custom", imageId = ImageResource("composeRes/images/p2.jpeg"), selected = true) selected = false,
Spacer(modifier = Modifier.padding(8.dp)) text = "Inactive",
CustomImageChip(text = "custom2", imageId = ImageResource("composeRes/images/p6.jpeg"), selected = false) modifier = Modifier.padding(horizontal = 8.dp)
} )
SubtitleText(subtitle = "Buttons with circle clipping.") Spacer(modifier = Modifier.padding(8.dp))
Column(modifier = Modifier.padding(8.dp)) { CustomImageChip(
Button( text = "custom",
onClick = {}, imageId = Res.drawable.p2,
modifier = Modifier.padding(8.dp).clip(CircleShape) selected = true
) { )
Text(text = "Chip button") Spacer(modifier = Modifier.padding(8.dp))
CustomImageChip(
text = "custom2",
imageId = Res.drawable.p6,
selected = false
)
} }
Button( SubtitleText(subtitle = "Buttons with circle clipping.")
onClick = {}, Column(modifier = Modifier.padding(8.dp)) {
enabled = false, Button(
modifier = Modifier.padding(8.dp).clip(CircleShape) onClick = {},
) { modifier = Modifier.padding(8.dp).clip(CircleShape)
Text(text = "Disabled chip") ) {
Text(text = "Chip button")
}
Button(
onClick = {},
enabled = false,
modifier = Modifier.padding(8.dp).clip(CircleShape)
) {
Text(text = "Disabled chip")
}
} }
} }
} }
@ -62,7 +80,7 @@ fun Chips() {
@Composable @Composable
private fun CustomImageChip( private fun CustomImageChip(
text: String, text: String,
imageId: ImageResource, imageId: DrawableResource,
selected: Boolean, selected: Boolean,
modifier: Modifier = Modifier modifier: Modifier = Modifier
) { ) {

33
examples/widgets-gallery/shared/src/commonMain/kotlin/org/jetbrains/compose/demo/widgets/ui/screens/Loaders.kt

@ -1,41 +1,34 @@
package org.jetbrains.compose.demo.widgets.ui.screens package org.jetbrains.compose.demo.widgets.ui.screens
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.material.CircularProgressIndicator import androidx.compose.material.CircularProgressIndicator
import androidx.compose.material.LinearProgressIndicator import androidx.compose.material.LinearProgressIndicator
import androidx.compose.material.Text import androidx.compose.material.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import org.jetbrains.compose.demo.widgets.ui.WidgetsType
@Composable @Composable
fun Loaders() { fun Loaders() {
AlignedColumn { Column(
modifier = Modifier
.padding(16.dp)
.testTag(WidgetsType.LOADERS.testTag),
verticalArrangement = Arrangement.spacedBy(16.dp)
) {
CircularProgressIndicator() CircularProgressIndicator()
}
AlignedColumn {
CircularProgressIndicator(strokeWidth = 8.dp) CircularProgressIndicator(strokeWidth = 8.dp)
}
AlignedColumn {
LinearProgressIndicator() LinearProgressIndicator()
}
AlignedColumn { Column {
LinearProgressIndicator() LinearProgressIndicator()
Text(text = "Loading with text...", modifier = Modifier.padding(8.dp)) Text(text = "Loading with text...", modifier = Modifier.padding(8.dp))
}
} }
} }
@Composable
private fun AlignedColumn(content: @Composable () -> Unit) {
Column(
modifier = Modifier.fillMaxWidth().padding(16.dp)
) {
content()
}
}

48
examples/widgets-gallery/shared/src/commonMain/kotlin/org/jetbrains/compose/demo/widgets/ui/screens/SnackBars.kt

@ -1,38 +1,46 @@
package org.jetbrains.compose.demo.widgets.ui.screens package org.jetbrains.compose.demo.widgets.ui.screens
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.material.Snackbar import androidx.compose.material.Snackbar
import androidx.compose.material.Text import androidx.compose.material.Text
import androidx.compose.material.TextButton import androidx.compose.material.TextButton
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import org.jetbrains.compose.demo.widgets.theme.typography import org.jetbrains.compose.demo.widgets.ui.WidgetsType
@Composable @Composable
fun SnackBars() { fun SnackBars() {
Snackbar(modifier = Modifier.padding(4.dp)) { Column(
Text(text = "This is a basic snackbar") modifier = Modifier
} .padding(4.dp)
Snackbar( .testTag(WidgetsType.SNACK_BARS.testTag),
modifier = Modifier.padding(4.dp), verticalArrangement = Arrangement.spacedBy(8.dp)
action = { ) {
TextButton(onClick = {}) { Snackbar {
Text(text = "Remove") Text(text = "This is a basic snackbar")
}
Snackbar(
action = {
TextButton(onClick = {}) {
Text(text = "Remove")
}
} }
) {
Text(text = "This is a basic snackbar with action item")
} }
) { Snackbar(
Text(text = "This is a basic Snackbar with action item") actionOnNewLine = true,
} action = {
Snackbar( TextButton(onClick = {}) {
modifier = Modifier.padding(4.dp), Text(text = "Remove")
actionOnNewLine = true, }
action = {
TextButton(onClick = {}) {
Text(text = "Remove")
} }
) {
Text(text = "Snackbar with action item below text")
} }
) {
Text(text = "Snackbar with action item below text")
} }
} }

123
examples/widgets-gallery/shared/src/commonMain/kotlin/org/jetbrains/compose/demo/widgets/ui/screens/TextInputs.kt

@ -1,6 +1,7 @@
package org.jetbrains.compose.demo.widgets.ui.screens package org.jetbrains.compose.demo.widgets.ui.screens
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.foundation.text.KeyboardOptions
@ -13,80 +14,84 @@ import androidx.compose.material.icons.filled.Edit
import androidx.compose.material.icons.filled.Email import androidx.compose.material.icons.filled.Email
import androidx.compose.runtime.* import androidx.compose.runtime.*
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.input.PasswordVisualTransformation import androidx.compose.ui.text.input.PasswordVisualTransformation
import androidx.compose.ui.text.input.TextFieldValue import androidx.compose.ui.text.input.TextFieldValue
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import org.jetbrains.compose.demo.widgets.ui.WidgetsType
@Composable @Composable
fun TextInputs() { fun TextInputs() {
var text by remember { mutableStateOf(TextFieldValue("")) } Column(Modifier.testTag(WidgetsType.TEXT_INPUTS.testTag)) {
var text by remember { mutableStateOf(TextFieldValue("")) }
// TODO Explore CoreTextField // TODO Explore CoreTextField
// CoreTextField( // CoreTextField(
// value = text, // value = text,
// onValueChange = { newValue -> text = newValue }, // onValueChange = { newValue -> text = newValue },
// modifier = Modifier.padding(8.dp).preferredSize(0.dp), // modifier = Modifier.padding(8.dp).preferredSize(0.dp),
// cursorColor = Color.Magenta // cursorColor = Color.Magenta
// ) // )
TextField( TextField(
value = text, value = text,
onValueChange = { newValue -> text = newValue }, onValueChange = { newValue -> text = newValue },
modifier = Modifier.padding(8.dp).fillMaxWidth(), modifier = Modifier.padding(8.dp).fillMaxWidth(),
singleLine = true, singleLine = true,
label = { Text("label") }, label = { Text("label") },
placeholder = { Text("placeholder") }, placeholder = { Text("placeholder") },
) )
OutlinedTextField( OutlinedTextField(
value = text, value = text,
modifier = Modifier.padding(8.dp).fillMaxWidth(), modifier = Modifier.padding(8.dp).fillMaxWidth(),
singleLine = true, singleLine = true,
label = { Text(text = "Password") }, label = { Text(text = "Password") },
placeholder = { Text(text = "12334444") }, placeholder = { Text(text = "12334444") },
visualTransformation = PasswordVisualTransformation(), visualTransformation = PasswordVisualTransformation(),
onValueChange = { onValueChange = {
text = it text = it
}, },
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password) keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password)
) )
OutlinedTextField( OutlinedTextField(
value = text, value = text,
leadingIcon = { Icon(Icons.Default.Email, contentDescription = "Email") }, leadingIcon = { Icon(Icons.Default.Email, contentDescription = "Email") },
modifier = Modifier.padding(8.dp).fillMaxWidth(), modifier = Modifier.padding(8.dp).fillMaxWidth(),
singleLine = true, singleLine = true,
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text), keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text),
label = { Text(text = "Email address") }, label = { Text(text = "Email address") },
placeholder = { Text(text = "Your email") }, placeholder = { Text(text = "Your email") },
onValueChange = { onValueChange = {
text = it text = it
} }
) )
OutlinedTextField( OutlinedTextField(
value = text, value = text,
leadingIcon = { Icon(Icons.Default.Email, contentDescription = "Email") }, leadingIcon = { Icon(Icons.Default.Email, contentDescription = "Email") },
trailingIcon = { Icon(Icons.Default.Edit, contentDescription = "Edit") }, trailingIcon = { Icon(Icons.Default.Edit, contentDescription = "Edit") },
modifier = Modifier.padding(8.dp).fillMaxWidth(), modifier = Modifier.padding(8.dp).fillMaxWidth(),
singleLine = true, singleLine = true,
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text), keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text),
label = { Text(text = "Email address") }, label = { Text(text = "Email address") },
placeholder = { Text(text = "Your email") }, placeholder = { Text(text = "Your email") },
onValueChange = { onValueChange = {
text = it text = it
} }
) )
var numberText by remember { mutableStateOf(TextFieldValue("")) } var numberText by remember { mutableStateOf(TextFieldValue("")) }
OutlinedTextField( OutlinedTextField(
value = numberText, value = numberText,
modifier = Modifier.padding(8.dp).fillMaxWidth(), modifier = Modifier.padding(8.dp).fillMaxWidth(),
singleLine = true, singleLine = true,
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number), keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
label = { Text(text = "Phone number") }, label = { Text(text = "Phone number") },
placeholder = { Text(text = "88888888") }, placeholder = { Text(text = "88888888") },
onValueChange = { onValueChange = {
numberText = it numberText = it
} }
) )
}
} }

5
examples/widgets-gallery/shared/src/commonMain/kotlin/org/jetbrains/compose/demo/widgets/ui/screens/Texts.kt

@ -1,21 +1,22 @@
package org.jetbrains.compose.demo.widgets.ui.screens package org.jetbrains.compose.demo.widgets.ui.screens
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.material.Text import androidx.compose.material.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextDecoration import androidx.compose.ui.text.style.TextDecoration
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import org.jetbrains.compose.demo.widgets.theme.typography import org.jetbrains.compose.demo.widgets.theme.typography
import org.jetbrains.compose.demo.widgets.ui.WidgetsType
import org.jetbrains.compose.demo.widgets.ui.utils.SubtitleText import org.jetbrains.compose.demo.widgets.ui.utils.SubtitleText
@Composable @Composable
fun TextViews() { fun TextViews() {
Column { Column(Modifier.testTag(WidgetsType.TEXT_VIEWS.testTag)) {
val textModifier = Modifier.padding(horizontal = 8.dp) val textModifier = Modifier.padding(horizontal = 8.dp)
SubtitleText(subtitle = "Font weights") SubtitleText(subtitle = "Font weights")

4
examples/widgets-gallery/shared/src/commonMain/kotlin/org/jetbrains/compose/demo/widgets/ui/screens/Toggles.kt

@ -9,11 +9,13 @@ import androidx.compose.material.*
import androidx.compose.runtime.* import androidx.compose.runtime.*
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import org.jetbrains.compose.demo.widgets.ui.WidgetsType
@Composable @Composable
fun Toggles() { fun Toggles() {
Column { Column(Modifier.testTag(WidgetsType.TOGGLES.testTag)) {
var checked by remember { mutableStateOf(true) } var checked by remember { mutableStateOf(true) }
Checkbox( Checkbox(
checked = checked, checked = checked,

167
examples/widgets-gallery/shared/src/commonMain/kotlin/org/jetbrains/compose/demo/widgets/ui/screens/UICards.kt

@ -9,96 +9,109 @@ import androidx.compose.material.icons.filled.ShoppingCart
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import org.jetbrains.compose.demo.widgets.data.DemoDataProvider import org.jetbrains.compose.demo.widgets.data.DemoDataProvider
import org.jetbrains.compose.resources.painterResource import org.jetbrains.compose.resources.painterResource
import org.jetbrains.compose.demo.widgets.theme.typography import org.jetbrains.compose.demo.widgets.theme.typography
import org.jetbrains.compose.demo.widgets.ui.WidgetsType
import org.jetbrains.compose.resources.ExperimentalResourceApi import org.jetbrains.compose.resources.ExperimentalResourceApi
import org.jetbrains.compose.resources.ImageResource import widgets_gallery.shared.generated.resources.Res
@OptIn(ExperimentalMaterialApi::class, ExperimentalResourceApi::class) @OptIn(ExperimentalMaterialApi::class, ExperimentalResourceApi::class)
@Composable @Composable
fun UICards() { fun UICards() {
val item = remember { DemoDataProvider.item } Column(Modifier.testTag(WidgetsType.UI_CARDS.testTag)) {
val item = remember { DemoDataProvider.item }
Text( Text(
text = "Inbuilt box as container for any Clipping/Alignment controls", text = "Inbuilt box as container for any Clipping/Alignment controls",
style = typography.subtitle1, style = typography.subtitle1,
modifier = Modifier.padding(8.dp) modifier = Modifier.padding(8.dp)
) )
Card( Card(
modifier = Modifier.padding(8.dp).fillMaxWidth(), modifier = Modifier.padding(8.dp).fillMaxWidth(),
backgroundColor = MaterialTheme.colors.primary, backgroundColor = MaterialTheme.colors.primary,
shape = RoundedCornerShape(topStart = 16.dp, bottomEnd = 16.dp) shape = RoundedCornerShape(topStart = 16.dp, bottomEnd = 16.dp)
) { ) {
Column { Column {
Text( Text(
text = item.title, text = item.title,
modifier = Modifier.padding(8.dp), modifier = Modifier.padding(8.dp),
color = MaterialTheme.colors.onPrimary color = MaterialTheme.colors.onPrimary
) )
Text( Text(
text = item.subtitle, text = item.subtitle,
modifier = Modifier.padding(8.dp), modifier = Modifier.padding(8.dp),
color = MaterialTheme.colors.onPrimary color = MaterialTheme.colors.onPrimary
) )
}
} }
} Divider()
Divider()
Text(text = "Inbuilt Card", style = typography.subtitle1, modifier = Modifier.padding(8.dp)) Text(text = "Inbuilt Card", style = typography.subtitle1, modifier = Modifier.padding(8.dp))
Card( Card(
modifier = Modifier.padding(16.dp).fillMaxWidth(), modifier = Modifier.padding(16.dp).fillMaxWidth(),
shape = RoundedCornerShape(4.dp), shape = RoundedCornerShape(4.dp),
elevation = 4.dp elevation = 4.dp
) { ) {
Row { Row {
Image( Image(
painterResource(ImageResource("composeRes/images/p3.jpeg")), painterResource(Res.drawable.p3),
contentDescription = null, contentDescription = null,
modifier = Modifier.requiredSize(60.dp) modifier = Modifier.requiredSize(60.dp)
) )
Text(text = item.title, modifier = Modifier.padding(16.dp)) Text(text = item.title, modifier = Modifier.padding(16.dp))
}
} }
} Divider()
Divider()
Text( Text(
text = "In-built ListItems", text = "In-built ListItems",
style = typography.subtitle1, style = typography.subtitle1,
modifier = Modifier.padding(8.dp) modifier = Modifier.padding(8.dp)
)
ListItem(text = { Text(item.title) }, secondaryText = { Text(item.subtitle) })
Divider(modifier = Modifier.padding(4.dp))
ListItem(
text = { Text(item.title) },
secondaryText = { Text(item.subtitle) },
singleLineSecondaryText = false
)
Divider(modifier = Modifier.padding(4.dp))
ListItem(text = { Text(item.title) }, secondaryText = { Text(item.subtitle) }, icon = {
Image(
painterResource(ImageResource("composeRes/images/p3.jpeg")),
contentDescription = null
) )
}) ListItem(text = { Text(item.title) }, secondaryText = { Text(item.subtitle) })
Divider(modifier = Modifier.padding(4.dp)) Divider(modifier = Modifier.padding(4.dp))
//I am not sure why this is not going multiline for secondaryText... ListItem(
ListItem( text = { Text(item.title) },
text = { Text(item.title) }, secondaryText = { Text(item.subtitle) },
secondaryText = { Text(item.subtitle) }, singleLineSecondaryText = false
icon = { Image(painterResource(ImageResource("composeRes/images/p1.jpeg")), contentDescription = null) }, )
overlineText = { Text("Overline text") }, Divider(modifier = Modifier.padding(4.dp))
singleLineSecondaryText = false ListItem(text = { Text(item.title) }, secondaryText = { Text(item.subtitle) }, icon = {
) Image(
Divider() painterResource(Res.drawable.p3),
ListItem( contentDescription = null
text = { Text(item.title) }, )
secondaryText = { Text(item.subtitle) }, })
icon = { Image(painterResource(ImageResource("composeRes/images/p2.jpeg")), contentDescription = null) }, Divider(modifier = Modifier.padding(4.dp))
trailing = { Icon(Icons.Default.ShoppingCart, contentDescription = null) }, //I am not sure why this is not going multiline for secondaryText...
singleLineSecondaryText = false ListItem(
) text = { Text(item.title) },
Divider() secondaryText = { Text(item.subtitle) },
icon = {
Image(
painterResource(Res.drawable.p1),
contentDescription = null
)
},
overlineText = { Text("Overline text") },
singleLineSecondaryText = false
)
Divider()
ListItem(
text = { Text(item.title) },
secondaryText = { Text(item.subtitle) },
icon = {
Image(
painterResource(Res.drawable.p2),
contentDescription = null
)
},
trailing = { Icon(Icons.Default.ShoppingCart, contentDescription = null) },
singleLineSecondaryText = false
)
Divider()
}
} }

9
examples/widgets-gallery/shared/src/commonMain/kotlin/org/jetbrains/compose/demo/widgets/ui/utils/ResizablePanel.kt

@ -8,8 +8,8 @@ import androidx.compose.material.Icon
import androidx.compose.material.LocalContentColor import androidx.compose.material.LocalContentColor
import androidx.compose.material.Text import androidx.compose.material.Text
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowBack import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material.icons.filled.ArrowForward import androidx.compose.material.icons.automirrored.filled.ArrowForward
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
@ -60,7 +60,10 @@ fun ResizablePanel(
.clickable { state.isExpanded = !state.isExpanded } .clickable { state.isExpanded = !state.isExpanded }
) { ) {
Icon( Icon(
if (state.isExpanded) Icons.Default.ArrowBack else Icons.Default.ArrowForward, imageVector = if (state.isExpanded)
Icons.AutoMirrored.Default.ArrowBack
else
Icons.AutoMirrored.Default.ArrowForward,
contentDescription = if (state.isExpanded) "Collapse" else "Expand", contentDescription = if (state.isExpanded) "Collapse" else "Expand",
tint = LocalContentColor.current, tint = LocalContentColor.current,
modifier = Modifier modifier = Modifier

34
examples/widgets-gallery/shared/src/commonTest/kotlin/ExampleTest.kt

@ -0,0 +1,34 @@
import androidx.compose.material.*
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.test.*
import kotlin.test.Test
/**
* This is a simple, sample test.
*/
class ExampleTest {
@OptIn(ExperimentalTestApi::class)
@Test
fun myTest() = runComposeUiTest {
setContent {
var text by remember { mutableStateOf("Hello") }
Text(
text = text,
modifier = Modifier.testTag("text")
)
Button(
onClick = { text = "Compose" },
modifier = Modifier.testTag("button")
){
Text("Click me")
}
}
onNodeWithTag("text").assertTextEquals("Hello")
onNodeWithTag("button").performClick()
onNodeWithTag("text").assertTextEquals("Compose")
}
}

28
examples/widgets-gallery/shared/src/commonTest/kotlin/WidgetsPanelTest.kt

@ -0,0 +1,28 @@
import androidx.compose.ui.test.ExperimentalTestApi
import androidx.compose.ui.test.onNodeWithTag
import androidx.compose.ui.test.performClick
import androidx.compose.ui.test.runComposeUiTest
import org.jetbrains.compose.demo.widgets.ui.WidgetsPanel
import org.jetbrains.compose.demo.widgets.ui.WidgetsType
import org.jetbrains.compose.demo.widgets.ui.listItemTestTag
import kotlin.test.Test
@OptIn(ExperimentalTestApi::class)
class WidgetsPanelTest {
/**
* Tests that clicking on each widget type in the list shows the corresponding widgets view.
*/
@OptIn(ExperimentalTestApi::class)
@Test
fun clickingOnWidgetListItemShowsCorrectWidgetUi() = runComposeUiTest {
setContent {
WidgetsPanel()
}
for (widgetsType in WidgetsType.entries) {
onNodeWithTag(widgetsType.listItemTestTag).performClick()
onNodeWithTag(widgetsType.testTag).assertExists()
}
}
}
Loading…
Cancel
Save