diff --git a/.idea/runConfigurations/Generate_Baseline_Profile.xml b/.idea/runConfigurations/Generate_Baseline_Profile.xml new file mode 100644 index 000000000..574863222 --- /dev/null +++ b/.idea/runConfigurations/Generate_Baseline_Profile.xml @@ -0,0 +1,27 @@ + + + + + + + true + true + false + false + + + diff --git a/baselineprofile/.gitignore b/baselineprofile/.gitignore new file mode 100644 index 000000000..796b96d1c --- /dev/null +++ b/baselineprofile/.gitignore @@ -0,0 +1 @@ +/build diff --git a/baselineprofile/build.gradle.kts b/baselineprofile/build.gradle.kts new file mode 100644 index 000000000..68e9e0e98 --- /dev/null +++ b/baselineprofile/build.gradle.kts @@ -0,0 +1,63 @@ +@file:Suppress("UnstableApiUsage") + +import com.android.build.api.dsl.ManagedVirtualDevice + +plugins { + kotlin("android") + id("com.android.test") + id("androidx.baselineprofile") + id("org.jmailen.kotlinter") +} + +android { + namespace = "kiwi.orbit.compose.baselineprofile" + compileSdk = libs.versions.compileSdk.get().toInt() + + defaultConfig { + minSdk = 28 // required by the BaselineProfileRule + targetSdk = libs.versions.targetSdk.get().toInt() + + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + } + + compileOptions { + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 + } + + lint { + abortOnError = true + warningsAsErrors = true + } + + targetProjectPath = ":catalog" + + testOptions { + animationsDisabled = true + + managedDevices.devices { + create("pixel6Api33") { + device = "Pixel 6" + apiLevel = 33 + systemImageSource = "google-atd" + } + } + } +} + +kotlinter { + reporters = arrayOf("json") +} + +baselineProfile { + managedDevices += "pixel6Api33" + useConnectedDevices = false +} + +dependencies { + implementation(projects.catalog.semantics) + + implementation(libs.androidx.benchmark.macro) + implementation(libs.androidx.test.runner) + implementation(libs.androidx.test.uiAutomator) +} diff --git a/baselineprofile/src/main/kotlin/kiwi/orbit/baselineprofile/BaselineProfileGenerator.kt b/baselineprofile/src/main/kotlin/kiwi/orbit/baselineprofile/BaselineProfileGenerator.kt new file mode 100644 index 000000000..7285d4c95 --- /dev/null +++ b/baselineprofile/src/main/kotlin/kiwi/orbit/baselineprofile/BaselineProfileGenerator.kt @@ -0,0 +1,153 @@ +package kiwi.orbit.baselineprofile + +import androidx.benchmark.macro.MacrobenchmarkScope +import androidx.benchmark.macro.junit4.BaselineProfileRule +import androidx.test.filters.LargeTest +import androidx.test.uiautomator.By +import androidx.test.uiautomator.UiScrollable +import androidx.test.uiautomator.UiSelector +import androidx.test.uiautomator.Until +import kiwi.orbit.compose.catalog.semantics.AlertScreenSemantics +import kiwi.orbit.compose.catalog.semantics.ButtonScreenSemantics +import kiwi.orbit.compose.catalog.semantics.DialogScreenSemantics +import kiwi.orbit.compose.catalog.semantics.MainScreenSemantics +import kiwi.orbit.compose.catalog.semantics.PillButtonScreenSemantics +import kiwi.orbit.compose.catalog.semantics.SelectFieldScreenSemantics +import kiwi.orbit.compose.catalog.semantics.SubScreenSemantics +import kiwi.orbit.compose.catalog.semantics.ToastScreenSemantics +import kiwi.orbit.compose.catalog.semantics.TopAppBarScreenSemantics +import org.junit.Rule +import org.junit.Test + +/** + * This test class generates a basic startup baseline profile for the target package. + * + * We recommend you start with this but add important user flows to the profile to improve their performance. + * Refer to the [baseline profile documentation](https://d.android.com/topic/performance/baselineprofiles) + * for more information. + * + * You can run the generator with the Generate Baseline Profile run configuration, + * or directly with `generateBaselineProfile` Gradle task: + * ``` + * ./gradlew :catalog:generateReleaseBaselineProfile -Pandroid.testInstrumentationRunnerArguments.androidx.benchmark.enabledRules=BaselineProfile + * ``` + * The run configuration runs the Gradle task and applies filtering to run only the generators. + * + * Check [documentation](https://d.android.com/topic/performance/benchmarking/macrobenchmark-instrumentation-args) + * for more information about available instrumentation arguments. + * + * After you run the generator, you can verify the improvements running the [StartupBenchmarks] benchmark. + **/ +@LargeTest +internal class BaselineProfileGenerator { + + private companion object { + const val TIMEOUT = 5000L + } + + @get:Rule + val rule = BaselineProfileRule() + + @Test + fun generate() { + rule.collect( + packageName = "kiwi.orbit.compose.catalog", + maxIterations = 5, + stableIterations = 2, + ) { + pressHome() + startActivityAndWait() + + profileSubScreen(MainScreenSemantics.ColorsItemTag) + profileSubScreen(MainScreenSemantics.IconsItemTag) + profileSubScreen(MainScreenSemantics.IllustrationsItemTag) + profileSubScreen(MainScreenSemantics.TypographyItemTag) + + profileSubScreen(MainScreenSemantics.AlertItemTag) { + device.findObject(By.res(AlertScreenSemantics.NormalTabTag)).click() + device.findObject(By.res(AlertScreenSemantics.SuppressedTabTag)).click() + device.findObject(By.res(AlertScreenSemantics.InlineTabTag)).click() + } + profileSubScreen(MainScreenSemantics.BadgeItemTag) + profileSubScreen(MainScreenSemantics.BadgeListItemTag) + profileSubScreen(MainScreenSemantics.ButtonItemTag) { + device.findObject(By.res(ButtonScreenSemantics.ButtonTabTag)).click() + device.findObject(By.res(ButtonScreenSemantics.ButtonLinkTabTag)).click() + } + profileSubScreen(MainScreenSemantics.CardItemTag) + profileSubScreen(MainScreenSemantics.CheckboxItemTag) + profileSubScreen(MainScreenSemantics.ChoiceTileItemTag) + profileSubScreen(MainScreenSemantics.CollapseItemTag) + profileSubScreen(MainScreenSemantics.DialogItemTag) { + device.findObject(By.res(DialogScreenSemantics.OrbitDialogButtonTag)) + .clickAndWait(Until.newWindow(), TIMEOUT) + device.pressBack() + device.findObject(By.res(DialogScreenSemantics.M3DialogButtonTag)) + .clickAndWait(Until.newWindow(), TIMEOUT) + device.pressBack() + device.findObject(By.res(DialogScreenSemantics.M3TimePickerButtonTag)) + .clickAndWait(Until.newWindow(), TIMEOUT) + device.pressBack() + device.findObject(By.res(DialogScreenSemantics.M3DatePickerButtonTag)) + .clickAndWait(Until.newWindow(), TIMEOUT) + device.pressBack() + } + profileSubScreen(MainScreenSemantics.EmptyStateItemTag) + profileSubScreen(MainScreenSemantics.KeyValueItemTag) + profileSubScreen(MainScreenSemantics.ListItemTag) + profileSubScreen(MainScreenSemantics.ListChoiceItemTag) + profileSubScreen(MainScreenSemantics.LoadingItemTag) + profileSubScreen(MainScreenSemantics.PillButtonItemTag) { + device.findObject(By.res(PillButtonScreenSemantics.ShowWithIconButtonTag)).click() + } + profileSubScreen(MainScreenSemantics.ProgressIndicatorItemTag) + profileSubScreen(MainScreenSemantics.RadioItemTag) + profileSubScreen(MainScreenSemantics.SeatItemTag) + profileSubScreen(MainScreenSemantics.SegmentedSwitchItemTag) + profileSubScreen(MainScreenSemantics.SelectFieldItemTag) { + device.findObject(By.res(SelectFieldScreenSemantics.CountrySelectFieldTag)).click() // open + device.findObject(By.res(SelectFieldScreenSemantics.CountrySelectFieldTag)).click() // close + Thread.sleep(1000L) // back navigation is blocked until the popup is fully closed + } + profileSubScreen(MainScreenSemantics.SliderItemTag) + profileSubScreen(MainScreenSemantics.StepperItemTag) + profileSubScreen(MainScreenSemantics.SurfaceCardItemTag) + profileSubScreen(MainScreenSemantics.SwitchItemTag) + profileSubScreen(MainScreenSemantics.TabsItemTag) + profileSubScreen(MainScreenSemantics.TagItemTag) + profileSubScreen(MainScreenSemantics.TextFieldItemTag) + profileSubScreen(MainScreenSemantics.TileItemTag) + profileSubScreen(MainScreenSemantics.TileGroupItemTag) + profileSubScreen(MainScreenSemantics.TimelineItemTag) + profileSubScreen(MainScreenSemantics.ToastItemTag) { + device.findObject(By.res(ToastScreenSemantics.ToastSignedInButtonTag)).click() + } + profileSubScreen(MainScreenSemantics.TopAppBarItemTag) { + device.findObject(By.res(TopAppBarScreenSemantics.NormalSimpleButtonTag)).click() + device.wait(Until.hasObject(By.res(TopAppBarScreenSemantics.NormalSimpleScreenTag)), TIMEOUT) + device.pressBack() + device.wait(Until.hasObject(By.res(SubScreenSemantics.Tag)), TIMEOUT) + device.findObject(By.res(TopAppBarScreenSemantics.LargeSimpleButtonTag)).click() + device.wait(Until.hasObject(By.res(TopAppBarScreenSemantics.LargeSimpleScreenTag)), TIMEOUT) + device.pressBack() + } + } + } + + private fun MacrobenchmarkScope.profileSubScreen( + mainScreenItemTag: String, + profileContent: MacrobenchmarkScope.() -> Unit = {}, + ) { + val mainScreenScrollable = UiScrollable(UiSelector().scrollable(true)) + mainScreenScrollable.scrollIntoView(UiSelector().resourceId(mainScreenItemTag)) + device.wait(Until.hasObject(By.res(mainScreenItemTag)), TIMEOUT) + + device.findObject(By.res(mainScreenItemTag)).click() + device.wait(Until.hasObject(By.res(SubScreenSemantics.Tag)), TIMEOUT) + + profileContent() + + device.pressBack() + device.wait(Until.hasObject(By.res(MainScreenSemantics.Tag)), TIMEOUT) + } +} diff --git a/baselineprofile/src/main/kotlin/kiwi/orbit/baselineprofile/StartupBenchmarks.kt b/baselineprofile/src/main/kotlin/kiwi/orbit/baselineprofile/StartupBenchmarks.kt new file mode 100644 index 000000000..32152e6a2 --- /dev/null +++ b/baselineprofile/src/main/kotlin/kiwi/orbit/baselineprofile/StartupBenchmarks.kt @@ -0,0 +1,59 @@ +package kiwi.orbit.baselineprofile + +import androidx.benchmark.macro.BaselineProfileMode +import androidx.benchmark.macro.CompilationMode +import androidx.benchmark.macro.StartupMode +import androidx.benchmark.macro.StartupTimingMetric +import androidx.benchmark.macro.junit4.MacrobenchmarkRule +import androidx.test.filters.LargeTest +import org.junit.Rule +import org.junit.Test + +/** + * This test class benchmarks the speed of app startup. + * Run this benchmark to verify how effective a Baseline Profile is. + * It does this by comparing [CompilationMode.None], which represents the app with no Baseline + * Profiles optimizations, and [CompilationMode.Partial], which uses Baseline Profiles. + * + * Run this benchmark to see startup measurements and captured system traces for verifying + * the effectiveness of your Baseline Profiles. You can run it directly from Android + * Studio as an instrumentation test, or run all benchmarks with this Gradle task: + * ``` + * ./gradlew :baselineprofile:connectedAndroidTest -Pandroid.testInstrumentationRunnerArguments.androidx.benchmark.enabledRules=Macrobenchmark + * ``` + * + * You should run the benchmarks on a physical device, not an Android emulator, because the + * emulator doesn't represent real world performance and shares system resources with its host. + * + * For more information, see the [Macrobenchmark documentation](https://d.android.com/macrobenchmark#create-macrobenchmark) + * and the [instrumentation arguments documentation](https://d.android.com/topic/performance/benchmarking/macrobenchmark-instrumentation-args). + **/ +@LargeTest +internal class StartupBenchmarks { + + @get:Rule + val rule = MacrobenchmarkRule() + + @Test + fun startupCompilationNone() { + benchmark(CompilationMode.None()) + } + + @Test + fun startupCompilationBaselineProfiles() { + benchmark(CompilationMode.Partial(BaselineProfileMode.Require)) + } + + private fun benchmark(compilationMode: CompilationMode) { + rule.measureRepeated( + packageName = "kiwi.orbit.compose.catalog", + metrics = listOf(StartupTimingMetric()), + compilationMode = compilationMode, + startupMode = StartupMode.COLD, + iterations = 10, + setupBlock = { pressHome() }, + ) { + startActivityAndWait() + } + } +} diff --git a/build.gradle.kts b/build.gradle.kts index 07c65ebb6..ce05debb0 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -14,6 +14,8 @@ plugins { kotlin("multiplatform") version "1.9.10" apply false kotlin("plugin.serialization") version "1.9.10" apply false id("com.android.library") version "8.1.1" apply false + id("com.android.test") version "8.1.1" apply false + id("androidx.baselineprofile") version "1.2.0-beta01" apply false id("app.cash.paparazzi") version "1.3.1" apply false id("com.google.firebase.appdistribution") version "4.0.0" apply false id("com.vanniktech.maven.publish.base") version "0.25.3" apply false diff --git a/catalog/build.gradle.kts b/catalog/build.gradle.kts index 6ac8470aa..c726ccca5 100644 --- a/catalog/build.gradle.kts +++ b/catalog/build.gradle.kts @@ -7,6 +7,7 @@ plugins { kotlin("android") kotlin("plugin.serialization") id("com.android.application") + id("androidx.baselineprofile") id("org.jmailen.kotlinter") id("com.google.firebase.appdistribution") kotlin("plugin.parcelize") @@ -127,6 +128,7 @@ dependencies { implementation(projects.ui) implementation(projects.icons) implementation(projects.illustrations) + implementation(projects.catalog.semantics) implementation(libs.androidx.core) implementation(libs.androidx.activityCompose) @@ -152,6 +154,8 @@ dependencies { implementation(libs.accompanist.systemController) implementation(libs.kiwi.navigationComposeTyped) + baselineProfile(projects.baselineprofile) + coreLibraryDesugaring(libs.android.desugarJdk) debugImplementation(libs.compose.tooling) @@ -159,5 +163,5 @@ dependencies { debugImplementation(libs.androidx.customViewPoolingContainer) lintChecks(libs.slack.composeLintChecks) - lintChecks(project(":lint")) + lintChecks(projects.lint) } diff --git a/catalog/semantics/.gitignore b/catalog/semantics/.gitignore new file mode 100644 index 000000000..796b96d1c --- /dev/null +++ b/catalog/semantics/.gitignore @@ -0,0 +1 @@ +/build diff --git a/catalog/semantics/build.gradle.kts b/catalog/semantics/build.gradle.kts new file mode 100644 index 000000000..c517862b6 --- /dev/null +++ b/catalog/semantics/build.gradle.kts @@ -0,0 +1,28 @@ +plugins { + kotlin("android") + id("com.android.library") + id("org.jmailen.kotlinter") +} + +android { + namespace = "kiwi.orbit.compose.catalog.semantics" + compileSdk = libs.versions.compileSdk.get().toInt() + + defaultConfig { + minSdk = libs.versions.minSdk.get().toInt() + } + + compileOptions { + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 + } + + lint { + abortOnError = true + warningsAsErrors = true + } +} + +kotlinter { + reporters = arrayOf("json") +} diff --git a/catalog/semantics/src/main/kotlin/kiwi/orbit/compose/catalog/semantics/AlertScreenSemantics.kt b/catalog/semantics/src/main/kotlin/kiwi/orbit/compose/catalog/semantics/AlertScreenSemantics.kt new file mode 100644 index 000000000..67a710f80 --- /dev/null +++ b/catalog/semantics/src/main/kotlin/kiwi/orbit/compose/catalog/semantics/AlertScreenSemantics.kt @@ -0,0 +1,7 @@ +package kiwi.orbit.compose.catalog.semantics + +object AlertScreenSemantics { + const val NormalTabTag = "alert_screen_normal_tab_tag" + const val SuppressedTabTag = "alert_screen_suppressed_tab_tag" + const val InlineTabTag = "alert_screen_inline_tab_tag" +} diff --git a/catalog/semantics/src/main/kotlin/kiwi/orbit/compose/catalog/semantics/ButtonScreenSemantics.kt b/catalog/semantics/src/main/kotlin/kiwi/orbit/compose/catalog/semantics/ButtonScreenSemantics.kt new file mode 100644 index 000000000..ae565c7e6 --- /dev/null +++ b/catalog/semantics/src/main/kotlin/kiwi/orbit/compose/catalog/semantics/ButtonScreenSemantics.kt @@ -0,0 +1,6 @@ +package kiwi.orbit.compose.catalog.semantics + +object ButtonScreenSemantics { + const val ButtonTabTag = "button_screen_button_tab_tag" + const val ButtonLinkTabTag = "button_screen_button_link_tab_tag" +} diff --git a/catalog/semantics/src/main/kotlin/kiwi/orbit/compose/catalog/semantics/DialogScreenSemantics.kt b/catalog/semantics/src/main/kotlin/kiwi/orbit/compose/catalog/semantics/DialogScreenSemantics.kt new file mode 100644 index 000000000..a4f7a7910 --- /dev/null +++ b/catalog/semantics/src/main/kotlin/kiwi/orbit/compose/catalog/semantics/DialogScreenSemantics.kt @@ -0,0 +1,8 @@ +package kiwi.orbit.compose.catalog.semantics + +object DialogScreenSemantics { + const val OrbitDialogButtonTag = "dialog_screen_orbit_dialog_button_tag" + const val M3DialogButtonTag = "dialog_screen_m3_dialog_button_tag" + const val M3TimePickerButtonTag = "dialog_screen_m3_time_picker_button_tag" + const val M3DatePickerButtonTag = "dialog_screen_m3_date_picker_button_tag" +} diff --git a/catalog/semantics/src/main/kotlin/kiwi/orbit/compose/catalog/semantics/MainScreenSemantics.kt b/catalog/semantics/src/main/kotlin/kiwi/orbit/compose/catalog/semantics/MainScreenSemantics.kt new file mode 100644 index 000000000..6f80430a5 --- /dev/null +++ b/catalog/semantics/src/main/kotlin/kiwi/orbit/compose/catalog/semantics/MainScreenSemantics.kt @@ -0,0 +1,43 @@ +package kiwi.orbit.compose.catalog.semantics + +object MainScreenSemantics { + const val Tag = "main_screen" + + const val ColorsItemTag = "main_screen_colors_item_item" + const val IconsItemTag = "main_screen_icons_item" + const val IllustrationsItemTag = "main_screen_illustrations_item" + const val TypographyItemTag = "main_screen_typography_item" + + const val AlertItemTag = "main_screen_alert_item" + const val BadgeItemTag = "main_screen_badge_item" + const val BadgeListItemTag = "main_screen_badge_list_item" + const val ButtonItemTag = "main_screen_button_item" + const val CardItemTag = "main_screen_card_item" + const val CheckboxItemTag = "main_screen_checkbox_item" + const val ChoiceTileItemTag = "main_screen_choice_tile_item" + const val CollapseItemTag = "main_screen_collapse_item" + const val DialogItemTag = "main_screen_dialog_item" + const val EmptyStateItemTag = "main_screen_empty_state_item" + const val KeyValueItemTag = "main_screen_key_value_item" + const val ListItemTag = "main_screen_list_item" + const val ListChoiceItemTag = "main_screen_list_choice_item" + const val LoadingItemTag = "main_screen_loading_item" + const val PillButtonItemTag = "main_screen_pill_button_item" + const val ProgressIndicatorItemTag = "main_screen_progress_indicator_item" + const val RadioItemTag = "main_screen_radio_item" + const val SeatItemTag = "main_screen_seat_item" + const val SegmentedSwitchItemTag = "main_screen_segmented_switch_item" + const val SelectFieldItemTag = "main_screen_select_field_item" + const val SliderItemTag = "main_screen_slider_item" + const val StepperItemTag = "main_screen_stepper_item" + const val SurfaceCardItemTag = "main_screen_surface_card_item" + const val SwitchItemTag = "main_screen_switch_item" + const val TabsItemTag = "main_screen_tabs_item" + const val TagItemTag = "main_screen_tag_item" + const val TextFieldItemTag = "main_screen_text_field_item" + const val TileItemTag = "main_screen_tile_item" + const val TileGroupItemTag = "main_screen_tile_group_item" + const val TimelineItemTag = "main_screen_timeline_item" + const val ToastItemTag = "main_screen_toast_item" + const val TopAppBarItemTag = "main_screen_top_app_bar_item" +} diff --git a/catalog/semantics/src/main/kotlin/kiwi/orbit/compose/catalog/semantics/PillButtonScreenSemantics.kt b/catalog/semantics/src/main/kotlin/kiwi/orbit/compose/catalog/semantics/PillButtonScreenSemantics.kt new file mode 100644 index 000000000..3b34451a9 --- /dev/null +++ b/catalog/semantics/src/main/kotlin/kiwi/orbit/compose/catalog/semantics/PillButtonScreenSemantics.kt @@ -0,0 +1,5 @@ +package kiwi.orbit.compose.catalog.semantics + +object PillButtonScreenSemantics { + const val ShowWithIconButtonTag = "pill_button_screen_show_with_icon_button_tag" +} diff --git a/catalog/semantics/src/main/kotlin/kiwi/orbit/compose/catalog/semantics/SelectFieldScreenSemantics.kt b/catalog/semantics/src/main/kotlin/kiwi/orbit/compose/catalog/semantics/SelectFieldScreenSemantics.kt new file mode 100644 index 000000000..ff6bca254 --- /dev/null +++ b/catalog/semantics/src/main/kotlin/kiwi/orbit/compose/catalog/semantics/SelectFieldScreenSemantics.kt @@ -0,0 +1,5 @@ +package kiwi.orbit.compose.catalog.semantics + +object SelectFieldScreenSemantics { + const val CountrySelectFieldTag = "select_field_screen_country_select_field_tag" +} diff --git a/catalog/semantics/src/main/kotlin/kiwi/orbit/compose/catalog/semantics/SubScreenSemantics.kt b/catalog/semantics/src/main/kotlin/kiwi/orbit/compose/catalog/semantics/SubScreenSemantics.kt new file mode 100644 index 000000000..8390fe9df --- /dev/null +++ b/catalog/semantics/src/main/kotlin/kiwi/orbit/compose/catalog/semantics/SubScreenSemantics.kt @@ -0,0 +1,5 @@ +package kiwi.orbit.compose.catalog.semantics + +object SubScreenSemantics { + const val Tag = "sub_screen" +} diff --git a/catalog/semantics/src/main/kotlin/kiwi/orbit/compose/catalog/semantics/ToastScreenSemantics.kt b/catalog/semantics/src/main/kotlin/kiwi/orbit/compose/catalog/semantics/ToastScreenSemantics.kt new file mode 100644 index 000000000..dc5dda5be --- /dev/null +++ b/catalog/semantics/src/main/kotlin/kiwi/orbit/compose/catalog/semantics/ToastScreenSemantics.kt @@ -0,0 +1,5 @@ +package kiwi.orbit.compose.catalog.semantics + +object ToastScreenSemantics { + const val ToastSignedInButtonTag = "toast_screen_toast_signed_in_button_tag" +} diff --git a/catalog/semantics/src/main/kotlin/kiwi/orbit/compose/catalog/semantics/TopAppBarScreenSemantics.kt b/catalog/semantics/src/main/kotlin/kiwi/orbit/compose/catalog/semantics/TopAppBarScreenSemantics.kt new file mode 100644 index 000000000..55283a63e --- /dev/null +++ b/catalog/semantics/src/main/kotlin/kiwi/orbit/compose/catalog/semantics/TopAppBarScreenSemantics.kt @@ -0,0 +1,8 @@ +package kiwi.orbit.compose.catalog.semantics + +object TopAppBarScreenSemantics { + const val NormalSimpleButtonTag = "top_app_bar_screen_normal_simple_button_tag" + const val LargeSimpleButtonTag = "top_app_bar_screen_large_simple_button_tag" + const val NormalSimpleScreenTag = "top_app_bar_screen_normal_simple_screen_tag" + const val LargeSimpleScreenTag = "top_app_bar_screen_large_simple_screen_tag" +} diff --git a/catalog/src/main/java/kiwi/orbit/compose/catalog/CatalogApplication.kt b/catalog/src/main/java/kiwi/orbit/compose/catalog/CatalogApplication.kt index 1bd32fa9d..30cf8c701 100644 --- a/catalog/src/main/java/kiwi/orbit/compose/catalog/CatalogApplication.kt +++ b/catalog/src/main/java/kiwi/orbit/compose/catalog/CatalogApplication.kt @@ -16,8 +16,12 @@ import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue +import androidx.compose.ui.ExperimentalComposeUiApi +import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalDensity +import androidx.compose.ui.semantics.semantics +import androidx.compose.ui.semantics.testTagsAsResourceId import androidx.compose.ui.unit.Density import androidx.compose.ui.unit.dp import androidx.navigation.compose.NavHost @@ -93,7 +97,7 @@ fun CatalogApplication() { } } -@OptIn(ExperimentalSerializationApi::class) +@OptIn(ExperimentalSerializationApi::class, ExperimentalComposeUiApi::class) @Composable private fun NavGraph( onToggleTheme: () -> Unit, @@ -104,6 +108,7 @@ private fun NavGraph( NavHost( navController = navController, startDestination = createRoutePattern(), + modifier = Modifier.semantics { testTagsAsResourceId = true }, enterTransition = { SharedXAxisEnterTransition(density) }, exitTransition = { SharedXAxisExitTransition(density) }, popEnterTransition = { SharedXAxisPopEnterTransition(density) }, diff --git a/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/AlertScreen.kt b/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/AlertScreen.kt index 950ee314d..fd314e1aa 100644 --- a/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/AlertScreen.kt +++ b/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/AlertScreen.kt @@ -18,6 +18,7 @@ import androidx.compose.foundation.verticalScroll import androidx.compose.runtime.Composable import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.testTag import androidx.compose.ui.text.SpanStyle import androidx.compose.ui.text.buildAnnotatedString import androidx.compose.ui.text.font.FontWeight @@ -26,6 +27,8 @@ import androidx.compose.ui.text.withStyle import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.LayoutDirection import androidx.compose.ui.unit.dp +import kiwi.orbit.compose.catalog.semantics.AlertScreenSemantics +import kiwi.orbit.compose.catalog.semantics.SubScreenSemantics import kiwi.orbit.compose.icons.Icons import kiwi.orbit.compose.ui.OrbitTheme import kiwi.orbit.compose.ui.controls.AlertCritical @@ -52,6 +55,7 @@ internal fun AlertScreen(onNavigateUp: () -> Unit) { val state = rememberPagerState(0) { 3 } val scope = rememberCoroutineScope() Scaffold( + modifier = Modifier.testTag(SubScreenSemantics.Tag), topBar = { TopAppBar( title = { Text("Alert") }, @@ -61,16 +65,19 @@ internal fun AlertScreen(onNavigateUp: () -> Unit) { Tab( selected = state.currentPage == 0, onClick = { scope.launch { state.animateScrollToPage(0) } }, + modifier = Modifier.testTag(AlertScreenSemantics.NormalTabTag), text = { Text("Normal") }, ) Tab( selected = state.currentPage == 1, onClick = { scope.launch { state.animateScrollToPage(1) } }, + modifier = Modifier.testTag(AlertScreenSemantics.SuppressedTabTag), text = { Text("Suppressed") }, ) Tab( selected = state.currentPage == 2, onClick = { scope.launch { state.animateScrollToPage(2) } }, + modifier = Modifier.testTag(AlertScreenSemantics.InlineTabTag), text = { Text("Inline") }, ) } diff --git a/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/BadgeListScreen.kt b/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/BadgeListScreen.kt index 91ea4f2fa..93859e00b 100644 --- a/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/BadgeListScreen.kt +++ b/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/BadgeListScreen.kt @@ -10,8 +10,10 @@ import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.testTag import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp +import kiwi.orbit.compose.catalog.semantics.SubScreenSemantics import kiwi.orbit.compose.icons.Icons import kiwi.orbit.compose.ui.OrbitTheme import kiwi.orbit.compose.ui.controls.BadgeList @@ -30,6 +32,7 @@ import kiwi.orbit.compose.ui.foundation.ContentEmphasis @Composable internal fun BadgeListScreen(onNavigateUp: () -> Unit) { Scaffold( + modifier = Modifier.testTag(SubScreenSemantics.Tag), topBar = { TopAppBar( title = { Text("BadgeList") }, diff --git a/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/BadgeScreen.kt b/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/BadgeScreen.kt index 054780577..ba4d1dbf4 100644 --- a/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/BadgeScreen.kt +++ b/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/BadgeScreen.kt @@ -16,8 +16,10 @@ import androidx.compose.foundation.verticalScroll import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.testTag import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp +import kiwi.orbit.compose.catalog.semantics.SubScreenSemantics import kiwi.orbit.compose.icons.Icons import kiwi.orbit.compose.ui.OrbitTheme import kiwi.orbit.compose.ui.controls.BadgeBundleBasic @@ -55,6 +57,7 @@ import kiwi.orbit.compose.ui.controls.TopAppBar @Composable internal fun BadgeScreen(onNavigateUp: () -> Unit) { Scaffold( + modifier = Modifier.testTag(SubScreenSemantics.Tag), topBar = { TopAppBar( title = { Text("Badge") }, diff --git a/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/ButtonScreen.kt b/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/ButtonScreen.kt index 1649f445a..2b798f3fb 100644 --- a/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/ButtonScreen.kt +++ b/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/ButtonScreen.kt @@ -25,11 +25,14 @@ import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.testTag import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.LayoutDirection import androidx.compose.ui.unit.dp import kiwi.orbit.compose.catalog.AppTheme +import kiwi.orbit.compose.catalog.semantics.ButtonScreenSemantics +import kiwi.orbit.compose.catalog.semantics.SubScreenSemantics import kiwi.orbit.compose.icons.Icons import kiwi.orbit.compose.ui.OrbitTheme import kiwi.orbit.compose.ui.controls.ButtonBundleBasic @@ -63,6 +66,7 @@ internal fun ButtonScreen(onNavigateUp: () -> Unit) { val state = rememberPagerState(0) { 2 } val scope = rememberCoroutineScope() Scaffold( + modifier = Modifier.testTag(SubScreenSemantics.Tag), topBar = { TopAppBar( title = { Text("Buttons") }, @@ -72,11 +76,13 @@ internal fun ButtonScreen(onNavigateUp: () -> Unit) { Tab( selected = state.currentPage == 0, onClick = { scope.launch { state.animateScrollToPage(0) } }, + modifier = Modifier.testTag(ButtonScreenSemantics.ButtonTabTag), text = { Text("Button") }, ) Tab( selected = state.currentPage == 1, onClick = { scope.launch { state.animateScrollToPage(1) } }, + modifier = Modifier.testTag(ButtonScreenSemantics.ButtonLinkTabTag), text = { Text("ButtonLink") }, ) } diff --git a/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/CardScreen.kt b/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/CardScreen.kt index 61e4cc4bb..c044fbe10 100644 --- a/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/CardScreen.kt +++ b/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/CardScreen.kt @@ -10,10 +10,12 @@ import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.testTag import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import kiwi.orbit.compose.catalog.AppTheme import kiwi.orbit.compose.catalog.components.CustomPlaceholder +import kiwi.orbit.compose.catalog.semantics.SubScreenSemantics import kiwi.orbit.compose.icons.Icons import kiwi.orbit.compose.ui.OrbitTheme import kiwi.orbit.compose.ui.controls.ButtonTextLinkPrimary @@ -29,6 +31,7 @@ internal fun CardScreen( onNavigateUp: () -> Unit, ) { Scaffold( + modifier = Modifier.testTag(SubScreenSemantics.Tag), topBar = { TopAppBar( title = { Text("Card") }, diff --git a/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/CheckboxScreen.kt b/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/CheckboxScreen.kt index 835613eb6..b756f696f 100644 --- a/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/CheckboxScreen.kt +++ b/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/CheckboxScreen.kt @@ -17,8 +17,10 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.testTag import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp +import kiwi.orbit.compose.catalog.semantics.SubScreenSemantics import kiwi.orbit.compose.ui.controls.Checkbox import kiwi.orbit.compose.ui.controls.CheckboxField import kiwi.orbit.compose.ui.controls.Scaffold @@ -28,6 +30,7 @@ import kiwi.orbit.compose.ui.controls.TopAppBar @Composable internal fun CheckboxScreen(onNavigateUp: () -> Unit) { Scaffold( + modifier = Modifier.testTag(SubScreenSemantics.Tag), topBar = { TopAppBar( title = { Text("Checkbox Button") }, diff --git a/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/ChoiceTileScreen.kt b/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/ChoiceTileScreen.kt index e7cfd12f0..7d8ba2806 100644 --- a/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/ChoiceTileScreen.kt +++ b/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/ChoiceTileScreen.kt @@ -24,9 +24,11 @@ import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.testTag import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import kiwi.orbit.compose.catalog.components.CustomPlaceholder +import kiwi.orbit.compose.catalog.semantics.SubScreenSemantics import kiwi.orbit.compose.icons.Icons import kiwi.orbit.compose.ui.controls.BadgeInfoSubtle import kiwi.orbit.compose.ui.controls.ChoiceTile @@ -39,6 +41,7 @@ import kiwi.orbit.compose.ui.controls.TopAppBar @Composable internal fun ChoiceTileScreen(onNavigateUp: () -> Unit) { Scaffold( + modifier = Modifier.testTag(SubScreenSemantics.Tag), topBar = { TopAppBar( title = { Text("ChoiceTile") }, diff --git a/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/CollapseScreen.kt b/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/CollapseScreen.kt index f05f168b8..466125429 100644 --- a/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/CollapseScreen.kt +++ b/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/CollapseScreen.kt @@ -13,8 +13,10 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.testTag import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp +import kiwi.orbit.compose.catalog.semantics.SubScreenSemantics import kiwi.orbit.compose.ui.controls.Collapse import kiwi.orbit.compose.ui.controls.Scaffold import kiwi.orbit.compose.ui.controls.Text @@ -23,6 +25,7 @@ import kiwi.orbit.compose.ui.controls.TopAppBar @Composable internal fun CollapseScreen(onNavigateUp: () -> Unit) { Scaffold( + modifier = Modifier.testTag(SubScreenSemantics.Tag), topBar = { TopAppBar( title = { Text("Collapse") }, diff --git a/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/ColorsScreen.kt b/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/ColorsScreen.kt index 937524988..d6110c2f7 100644 --- a/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/ColorsScreen.kt +++ b/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/ColorsScreen.kt @@ -20,8 +20,10 @@ import androidx.compose.ui.graphics.Brush import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.takeOrElse import androidx.compose.ui.graphics.toArgb +import androidx.compose.ui.platform.testTag import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp +import kiwi.orbit.compose.catalog.semantics.SubScreenSemantics import kiwi.orbit.compose.ui.OrbitTheme import kiwi.orbit.compose.ui.controls.Scaffold import kiwi.orbit.compose.ui.controls.Surface @@ -35,6 +37,7 @@ import kiwi.orbit.compose.ui.foundation.contentColorFor @Composable internal fun ColorsScreen(onNavigateUp: () -> Unit) { Scaffold( + modifier = Modifier.testTag(SubScreenSemantics.Tag), topBar = { TopAppBar( title = { Text("Colors") }, diff --git a/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/DialogsScreen.kt b/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/DialogsScreen.kt index 49e18402e..a1b6c398e 100644 --- a/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/DialogsScreen.kt +++ b/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/DialogsScreen.kt @@ -15,12 +15,15 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.testTag import androidx.compose.ui.unit.dp import androidx.navigation.NavController import com.kiwi.navigationcompose.typed.DialogResultEffect import com.kiwi.navigationcompose.typed.createRoutePattern import com.kiwi.navigationcompose.typed.navigate import kiwi.orbit.compose.catalog.Destinations +import kiwi.orbit.compose.catalog.semantics.DialogScreenSemantics +import kiwi.orbit.compose.catalog.semantics.SubScreenSemantics import kiwi.orbit.compose.ui.controls.ButtonSecondary import kiwi.orbit.compose.ui.controls.Scaffold import kiwi.orbit.compose.ui.controls.Separator @@ -51,6 +54,7 @@ internal fun DialogsScreen( } Scaffold( + modifier = Modifier.testTag(SubScreenSemantics.Tag), topBar = { TopAppBar( title = { Text("Dialogs") }, @@ -90,11 +94,27 @@ private fun DialogsScreenInner( verticalArrangement = Arrangement.spacedBy(8.dp), horizontalAlignment = Alignment.CenterHorizontally, ) { - ButtonSecondary(onClick = onShowOrbitDialog) { Text("Show Orbit Dialog") } + ButtonSecondary( + onClick = onShowOrbitDialog, + modifier = Modifier.testTag(DialogScreenSemantics.OrbitDialogButtonTag), + content = { Text("Show Orbit Dialog") }, + ) Separator(Modifier.padding(vertical = 16.dp)) - ButtonSecondary(onClick = onShowMaterialDialog) { Text("Show M3 Dialog") } - ButtonSecondary(onClick = onShowMaterialTimePicker) { Text("Show M3 TimePicker") } - ButtonSecondary(onClick = onShowMaterialDatePicker) { Text("Show M3 DatePicker") } + ButtonSecondary( + onClick = onShowMaterialDialog, + modifier = Modifier.testTag(DialogScreenSemantics.M3DialogButtonTag), + content = { Text("Show M3 Dialog") }, + ) + ButtonSecondary( + onClick = onShowMaterialTimePicker, + modifier = Modifier.testTag(DialogScreenSemantics.M3TimePickerButtonTag), + content = { Text("Show M3 TimePicker") }, + ) + ButtonSecondary( + onClick = onShowMaterialDatePicker, + modifier = Modifier.testTag(DialogScreenSemantics.M3DatePickerButtonTag), + content = { Text("Show M3 DatePicker") }, + ) Text("Picked Time: $time") Text("Picked Date: $date") } diff --git a/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/EmptyStateScreen.kt b/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/EmptyStateScreen.kt index fb3760c55..c35a09bc2 100644 --- a/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/EmptyStateScreen.kt +++ b/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/EmptyStateScreen.kt @@ -9,8 +9,10 @@ import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.testTag import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp +import kiwi.orbit.compose.catalog.semantics.SubScreenSemantics import kiwi.orbit.compose.illustrations.Illustrations import kiwi.orbit.compose.ui.OrbitTheme import kiwi.orbit.compose.ui.controls.ButtonPrimary @@ -24,6 +26,7 @@ import kiwi.orbit.compose.ui.controls.TopAppBar @Composable internal fun EmptyStateScreen(onNavigateUp: () -> Unit) { Scaffold( + modifier = Modifier.testTag(SubScreenSemantics.Tag), topBar = { TopAppBar( title = { Text("EmptyState") }, diff --git a/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/IconsScreen.kt b/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/IconsScreen.kt index c87e0559a..3eb4e64f9 100644 --- a/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/IconsScreen.kt +++ b/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/IconsScreen.kt @@ -14,9 +14,11 @@ import androidx.compose.runtime.currentComposer import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.painter.Painter +import androidx.compose.ui.platform.testTag import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp +import kiwi.orbit.compose.catalog.semantics.SubScreenSemantics import kiwi.orbit.compose.icons.ColoredIcons import kiwi.orbit.compose.icons.Icons import kiwi.orbit.compose.ui.OrbitTheme @@ -31,6 +33,7 @@ import kotlin.reflect.full.memberProperties @Composable internal fun IconsScreen(onNavigateUp: () -> Unit) { Scaffold( + modifier = Modifier.testTag(SubScreenSemantics.Tag), topBar = { TopAppBar( title = { Text("Icons") }, diff --git a/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/IllustrationsScreen.kt b/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/IllustrationsScreen.kt index ebdc48f6e..29cae3dd2 100644 --- a/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/IllustrationsScreen.kt +++ b/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/IllustrationsScreen.kt @@ -12,8 +12,10 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.currentComposer import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.painter.Painter +import androidx.compose.ui.platform.testTag import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp +import kiwi.orbit.compose.catalog.semantics.SubScreenSemantics import kiwi.orbit.compose.illustrations.Illustrations import kiwi.orbit.compose.ui.OrbitTheme import kiwi.orbit.compose.ui.controls.Scaffold @@ -26,6 +28,7 @@ import kotlin.reflect.full.memberProperties @Composable internal fun IllustrationsScreen(onNavigateUp: () -> Unit) { Scaffold( + modifier = Modifier.testTag(SubScreenSemantics.Tag), topBar = { TopAppBar( title = { Text("Illustrations") }, diff --git a/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/KeyValueScreen.kt b/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/KeyValueScreen.kt index 9fd25e760..ed725e69c 100644 --- a/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/KeyValueScreen.kt +++ b/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/KeyValueScreen.kt @@ -11,8 +11,10 @@ import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.testTag import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp +import kiwi.orbit.compose.catalog.semantics.SubScreenSemantics import kiwi.orbit.compose.ui.controls.KeyValue import kiwi.orbit.compose.ui.controls.KeyValueLarge import kiwi.orbit.compose.ui.controls.Scaffold @@ -22,6 +24,7 @@ import kiwi.orbit.compose.ui.controls.TopAppBar @Composable internal fun KeyValueScreen(onNavigateUp: () -> Unit) { Scaffold( + modifier = Modifier.testTag(SubScreenSemantics.Tag), topBar = { TopAppBar( title = { Text("KeyValue") }, diff --git a/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/LinearProgressIndicatorScreen.kt b/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/LinearProgressIndicatorScreen.kt index 677fb954d..a2fcb115a 100644 --- a/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/LinearProgressIndicatorScreen.kt +++ b/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/LinearProgressIndicatorScreen.kt @@ -17,9 +17,11 @@ import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.draw.alpha +import androidx.compose.ui.platform.testTag import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import kiwi.orbit.compose.catalog.AppTheme +import kiwi.orbit.compose.catalog.semantics.SubScreenSemantics import kiwi.orbit.compose.ui.controls.ButtonSecondary import kiwi.orbit.compose.ui.controls.LinearIndeterminateProgressIndicator import kiwi.orbit.compose.ui.controls.LinearProgressIndicator @@ -30,6 +32,7 @@ import kiwi.orbit.compose.ui.controls.TopAppBar @Composable internal fun LinearProgressIndicatorScreen(onNavigateUp: () -> Unit) { Scaffold( + modifier = Modifier.testTag(SubScreenSemantics.Tag), topBar = { TopAppBar( title = { Text("Linear Progress Indicator") }, diff --git a/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/ListChoiceScreen.kt b/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/ListChoiceScreen.kt index 4c8421cc3..ad0e9224f 100644 --- a/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/ListChoiceScreen.kt +++ b/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/ListChoiceScreen.kt @@ -17,9 +17,11 @@ import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.testTag import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import kiwi.orbit.compose.catalog.AppTheme +import kiwi.orbit.compose.catalog.semantics.SubScreenSemantics import kiwi.orbit.compose.icons.Icons import kiwi.orbit.compose.ui.controls.BadgeCircleInfoSubtle import kiwi.orbit.compose.ui.controls.ButtonPrimarySubtle @@ -35,6 +37,7 @@ internal fun ListChoiceScreen( onNavigateUp: () -> Unit, ) { Scaffold( + modifier = Modifier.testTag(SubScreenSemantics.Tag), topBar = { TopAppBar( title = { Text("ListChoice") }, diff --git a/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/ListScreen.kt b/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/ListScreen.kt index d524e6bbd..085cd5bfb 100644 --- a/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/ListScreen.kt +++ b/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/ListScreen.kt @@ -9,9 +9,11 @@ import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.testTag import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import kiwi.orbit.compose.catalog.AppTheme +import kiwi.orbit.compose.catalog.semantics.SubScreenSemantics import kiwi.orbit.compose.icons.Icons import kiwi.orbit.compose.ui.OrbitTheme import kiwi.orbit.compose.ui.controls.Icon @@ -27,6 +29,7 @@ internal fun ListScreen( onNavigateUp: () -> Unit, ) { Scaffold( + modifier = Modifier.testTag(SubScreenSemantics.Tag), topBar = { TopAppBar( title = { Text("List") }, diff --git a/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/LoadingScreen.kt b/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/LoadingScreen.kt index 9c7e272b7..c16622c7e 100644 --- a/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/LoadingScreen.kt +++ b/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/LoadingScreen.kt @@ -15,8 +15,10 @@ import androidx.compose.foundation.verticalScroll import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.testTag import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp +import kiwi.orbit.compose.catalog.semantics.SubScreenSemantics import kiwi.orbit.compose.ui.OrbitTheme import kiwi.orbit.compose.ui.controls.CircularProgressIndicator import kiwi.orbit.compose.ui.controls.InlineLoading @@ -30,6 +32,7 @@ internal fun LoadingScreen( onNavigateUp: () -> Unit, ) { Scaffold( + modifier = Modifier.testTag(SubScreenSemantics.Tag), topBar = { TopAppBar( title = { Text("Loading") }, diff --git a/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/MainScreen.kt b/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/MainScreen.kt index b115d78cd..776b668aa 100644 --- a/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/MainScreen.kt +++ b/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/MainScreen.kt @@ -1,5 +1,6 @@ package kiwi.orbit.compose.catalog.screens +import androidx.activity.compose.ReportDrawn import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Row @@ -40,6 +41,7 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.painter.Painter import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.platform.testTag import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import com.kiwi.navigationcompose.typed.Destination @@ -57,10 +59,12 @@ import kiwi.orbit.compose.ui.utils.plus import kotlinx.serialization.ExperimentalSerializationApi import androidx.compose.material.icons.Icons.Outlined as OMIcons import androidx.compose.material.icons.Icons.Rounded as MIcons +import kiwi.orbit.compose.catalog.semantics.MainScreenSemantics as Semantics private data class MenuItem( val title: String, val icon: Any, + val testTag: String, val onClick: () -> Unit, ) @@ -70,51 +74,60 @@ internal fun MainScreen( onNavigate: (Destination) -> Unit, onToggleTheme: () -> Unit, ) { - fun MenuItem(title: String, icon: Any, onNavigate: () -> Destination): MenuItem = - MenuItem(title, icon, onClick = { onNavigate(onNavigate()) }) + fun MenuItem(title: String, icon: Any, testTag: String, onNavigate: () -> Destination): MenuItem = + MenuItem(title, icon, testTag, onClick = { onNavigate(onNavigate()) }) val foundation = listOf( - MenuItem("Colors", MIcons.Palette) { Destinations.Colors }, - MenuItem("Icons", Icons.Airplane) { Destinations.Icons }, - MenuItem("Illustrations", Icons.Gallery) { Destinations.Illustrations }, - MenuItem("Typography", MIcons.FormatSize) { Destinations.Typography }, + MenuItem("Colors", MIcons.Palette, Semantics.ColorsItemTag) { Destinations.Colors }, + MenuItem("Icons", Icons.Airplane, Semantics.IconsItemTag) { Destinations.Icons }, + MenuItem("Illustrations", Icons.Gallery, Semantics.IllustrationsItemTag) { + Destinations.Illustrations + }, + MenuItem("Typography", MIcons.FormatSize, Semantics.TypographyItemTag) { Destinations.Typography }, ) val controls = listOf( - MenuItem("Alert", Icons.Alert) { Destinations.Alert }, - MenuItem("Badge", Icons.Deals) { Destinations.Badge }, - MenuItem("BadgeList", Icons.List) { Destinations.BadgeList }, - MenuItem("Button", MIcons.SmartButton) { Destinations.Button }, - MenuItem("Card", MIcons.Rectangle) { Destinations.Card }, - MenuItem("Checkbox", MIcons.CheckBox) { Destinations.Checkbox }, - MenuItem("Choice Tile", MIcons.Ballot) { Destinations.ChoiceTile }, - MenuItem("Collapse", Icons.ChevronDown) { Destinations.Collapse }, - MenuItem("Dialog", Icons.Chat) { Destinations.Dialog }, - MenuItem("EmptyState", MIcons.SignalWifiOff) { Destinations.EmptyState }, - MenuItem("KeyValue", MIcons.DragHandle) { Destinations.KeyValue }, - MenuItem("List", MIcons.DensitySmall) { Destinations.List }, - MenuItem("ListChoice", Icons.MenuHamburger) { Destinations.ListChoice }, - MenuItem("Loading", Icons.MenuMeatballs) { Destinations.Loading }, - MenuItem("PillButton", MIcons.EditAttributes) { Destinations.PillButton }, - MenuItem("Progress Indicator", OMIcons.ToggleOff) { Destinations.LinearProgressIndicator }, - MenuItem("Radio", Icons.CircleFilled) { Destinations.Radio }, - MenuItem("Seat", Icons.Seat) { Destinations.Seat }, - MenuItem("Segmented Switch", MIcons.ToggleOn) { Destinations.SegmentedSwitch }, - MenuItem("Select Field", MIcons.MenuOpen) { Destinations.SelectField }, - MenuItem("Slider", MIcons.LinearScale) { Destinations.Slider }, - MenuItem("Stepper", Icons.PlusCircle) { Destinations.Stepper }, - MenuItem("SurfaceCard", MIcons.Article) { Destinations.SurfaceCard }, - MenuItem("Switch", MIcons.ToggleOn) { Destinations.Switch }, - MenuItem("Tabs", MIcons.Tab) { Destinations.Tabs }, - MenuItem("Tag", MIcons.LabelImportant) { Destinations.Tag }, - MenuItem("Text Field", MIcons.Keyboard) { Destinations.TextField }, - MenuItem("Tile", MIcons.Crop169) { Destinations.Tile }, - MenuItem("TileGroup", MIcons.ListAlt) { Destinations.TileGroup }, - MenuItem("Timeline", Icons.RouteTwoStops) { Destinations.Timeline }, - MenuItem("Toast", MIcons.Announcement) { Destinations.Toast }, - MenuItem("TopAppBar", MIcons.WebAsset) { Destinations.TopAppBar }, + MenuItem("Alert", Icons.Alert, Semantics.AlertItemTag) { Destinations.Alert }, + MenuItem("Badge", Icons.Deals, Semantics.BadgeItemTag) { Destinations.Badge }, + MenuItem("BadgeList", Icons.List, Semantics.BadgeListItemTag) { Destinations.BadgeList }, + MenuItem("Button", MIcons.SmartButton, Semantics.ButtonItemTag) { Destinations.Button }, + MenuItem("Card", MIcons.Rectangle, Semantics.CardItemTag) { Destinations.Card }, + MenuItem("Checkbox", MIcons.CheckBox, Semantics.CheckboxItemTag) { Destinations.Checkbox }, + MenuItem("Choice Tile", MIcons.Ballot, Semantics.ChoiceTileItemTag) { Destinations.ChoiceTile }, + MenuItem("Collapse", Icons.ChevronDown, Semantics.CollapseItemTag) { Destinations.Collapse }, + MenuItem("Dialog", Icons.Chat, Semantics.DialogItemTag) { Destinations.Dialog }, + MenuItem("EmptyState", MIcons.SignalWifiOff, Semantics.EmptyStateItemTag) { Destinations.EmptyState }, + MenuItem("KeyValue", MIcons.DragHandle, Semantics.KeyValueItemTag) { Destinations.KeyValue }, + MenuItem("List", MIcons.DensitySmall, Semantics.ListItemTag) { Destinations.List }, + MenuItem("ListChoice", Icons.MenuHamburger, Semantics.ListChoiceItemTag) { Destinations.ListChoice }, + MenuItem("Loading", Icons.MenuMeatballs, Semantics.LoadingItemTag) { Destinations.Loading }, + MenuItem("PillButton", MIcons.EditAttributes, Semantics.PillButtonItemTag) { + Destinations.PillButton + }, + MenuItem("Progress Indicator", OMIcons.ToggleOff, Semantics.ProgressIndicatorItemTag) { + Destinations.LinearProgressIndicator + }, + MenuItem("Radio", Icons.CircleFilled, Semantics.RadioItemTag) { Destinations.Radio }, + MenuItem("Seat", Icons.Seat, Semantics.SeatItemTag) { Destinations.Seat }, + MenuItem("Segmented Switch", MIcons.ToggleOn, Semantics.SegmentedSwitchItemTag) { + Destinations.SegmentedSwitch + }, + MenuItem("Select Field", MIcons.MenuOpen, Semantics.SelectFieldItemTag) { Destinations.SelectField }, + MenuItem("Slider", MIcons.LinearScale, Semantics.SliderItemTag) { Destinations.Slider }, + MenuItem("Stepper", Icons.PlusCircle, Semantics.StepperItemTag) { Destinations.Stepper }, + MenuItem("SurfaceCard", MIcons.Article, Semantics.SurfaceCardItemTag) { Destinations.SurfaceCard }, + MenuItem("Switch", MIcons.ToggleOn, Semantics.SwitchItemTag) { Destinations.Switch }, + MenuItem("Tabs", MIcons.Tab, Semantics.TabsItemTag) { Destinations.Tabs }, + MenuItem("Tag", MIcons.LabelImportant, Semantics.TagItemTag) { Destinations.Tag }, + MenuItem("Text Field", MIcons.Keyboard, Semantics.TextFieldItemTag) { Destinations.TextField }, + MenuItem("Tile", MIcons.Crop169, Semantics.TileItemTag) { Destinations.Tile }, + MenuItem("TileGroup", MIcons.ListAlt, Semantics.TileGroupItemTag) { Destinations.TileGroup }, + MenuItem("Timeline", Icons.RouteTwoStops, Semantics.TimelineItemTag) { Destinations.Timeline }, + MenuItem("Toast", MIcons.Announcement, Semantics.ToastItemTag) { Destinations.Toast }, + MenuItem("TopAppBar", MIcons.WebAsset, Semantics.TopAppBarItemTag) { Destinations.TopAppBar }, ) Scaffold( + modifier = Modifier.testTag(Semantics.Tag), topBar = { TopAppBarLarge( title = { Text("Orbit Compose Catalog") }, @@ -137,6 +150,8 @@ internal fun MainScreen( cardItems("Controls", controls) } } + + ReportDrawn() } private fun LazyGridScope.cardItems( @@ -156,7 +171,9 @@ private fun LazyGridScope.cardItems( @Composable private fun Item(menuItem: MenuItem) { SurfaceCard( - modifier = Modifier.fillMaxWidth(), + modifier = Modifier + .testTag(menuItem.testTag) + .fillMaxWidth(), onClick = menuItem.onClick, ) { Row( diff --git a/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/PillButtonScreen.kt b/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/PillButtonScreen.kt index 79e521758..dcefbd2d3 100644 --- a/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/PillButtonScreen.kt +++ b/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/PillButtonScreen.kt @@ -15,9 +15,12 @@ import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.testTag import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import kiwi.orbit.compose.catalog.AppTheme +import kiwi.orbit.compose.catalog.semantics.PillButtonScreenSemantics +import kiwi.orbit.compose.catalog.semantics.SubScreenSemantics import kiwi.orbit.compose.icons.Icons import kiwi.orbit.compose.ui.controls.ButtonSecondary import kiwi.orbit.compose.ui.controls.Icon @@ -32,6 +35,7 @@ internal fun PillButtonScreen( onNavigateUp: () -> Unit, ) { Scaffold( + modifier = Modifier.testTag(SubScreenSemantics.Tag), topBar = { TopAppBar( title = { Text("PillButton") }, @@ -85,6 +89,7 @@ private fun PillButtonScreenInner( show = true showIcon = true }, + modifier = Modifier.testTag(PillButtonScreenSemantics.ShowWithIconButtonTag), ) { Text("Show with icon") } } } diff --git a/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/RadioScreen.kt b/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/RadioScreen.kt index 782cc6342..0b1873179 100644 --- a/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/RadioScreen.kt +++ b/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/RadioScreen.kt @@ -17,8 +17,10 @@ import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.testTag import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp +import kiwi.orbit.compose.catalog.semantics.SubScreenSemantics import kiwi.orbit.compose.ui.controls.Radio import kiwi.orbit.compose.ui.controls.RadioField import kiwi.orbit.compose.ui.controls.Scaffold @@ -28,6 +30,7 @@ import kiwi.orbit.compose.ui.controls.TopAppBar @Composable internal fun RadioScreen(onNavigateUp: () -> Unit) { Scaffold( + modifier = Modifier.testTag(SubScreenSemantics.Tag), topBar = { TopAppBar( title = { Text("Radio") }, diff --git a/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/SeatScreen.kt b/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/SeatScreen.kt index c03c2796f..6fccd69fb 100644 --- a/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/SeatScreen.kt +++ b/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/SeatScreen.kt @@ -15,7 +15,9 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.testTag import androidx.compose.ui.unit.dp +import kiwi.orbit.compose.catalog.semantics.SubScreenSemantics import kiwi.orbit.compose.ui.controls.Scaffold import kiwi.orbit.compose.ui.controls.SeatExtraLegroom import kiwi.orbit.compose.ui.controls.SeatLegendExtraLegroom @@ -29,6 +31,7 @@ import kiwi.orbit.compose.ui.controls.TopAppBar @Composable internal fun SeatScreen(onNavigateUp: () -> Unit) { Scaffold( + modifier = Modifier.testTag(SubScreenSemantics.Tag), topBar = { TopAppBar( title = { Text("Seat") }, diff --git a/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/SegmentedSwitchScreen.kt b/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/SegmentedSwitchScreen.kt index 50302c96c..07057edbc 100644 --- a/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/SegmentedSwitchScreen.kt +++ b/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/SegmentedSwitchScreen.kt @@ -14,8 +14,10 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.testTag import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp +import kiwi.orbit.compose.catalog.semantics.SubScreenSemantics import kiwi.orbit.compose.ui.controls.Scaffold import kiwi.orbit.compose.ui.controls.SegmentedSwitch import kiwi.orbit.compose.ui.controls.Text @@ -24,6 +26,7 @@ import kiwi.orbit.compose.ui.controls.TopAppBar @Composable internal fun SegmentedSwitchScreen(onNavigateUp: () -> Unit) { Scaffold( + modifier = Modifier.testTag(SubScreenSemantics.Tag), topBar = { TopAppBar( title = { Text("SegmentedSwitch") }, diff --git a/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/SelectFieldScreen.kt b/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/SelectFieldScreen.kt index 360421848..db43f8325 100644 --- a/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/SelectFieldScreen.kt +++ b/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/SelectFieldScreen.kt @@ -17,8 +17,11 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.testTag import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp +import kiwi.orbit.compose.catalog.semantics.SelectFieldScreenSemantics +import kiwi.orbit.compose.catalog.semantics.SubScreenSemantics import kiwi.orbit.compose.ui.controls.CountryFlag import kiwi.orbit.compose.ui.controls.Scaffold import kiwi.orbit.compose.ui.controls.SelectField @@ -29,6 +32,7 @@ import kotlinx.parcelize.Parcelize @Composable internal fun SelectFieldScreen(onNavigateUp: () -> Unit) { Scaffold( + modifier = Modifier.testTag(SubScreenSemantics.Tag), topBar = { TopAppBar( title = { Text("Select Field") }, @@ -78,7 +82,9 @@ private fun SelectFieldScreenInner() { placeholder = { Text("Select country") }, onOptionSelect = { selected = it }, label = { Text("Country") }, - modifier = Modifier.fillMaxWidth(), + modifier = Modifier + .testTag(SelectFieldScreenSemantics.CountrySelectFieldTag) + .fillMaxWidth(), ) { country -> CountryFlag(country.code, country.name) Spacer(Modifier.size(16.dp)) diff --git a/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/SliderScreen.kt b/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/SliderScreen.kt index 832dbdf15..e811af4a3 100644 --- a/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/SliderScreen.kt +++ b/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/SliderScreen.kt @@ -16,7 +16,9 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.testTag import androidx.compose.ui.unit.dp +import kiwi.orbit.compose.catalog.semantics.SubScreenSemantics import kiwi.orbit.compose.ui.OrbitTheme import kiwi.orbit.compose.ui.controls.RangeSlider import kiwi.orbit.compose.ui.controls.Scaffold @@ -27,6 +29,7 @@ import kiwi.orbit.compose.ui.controls.TopAppBar @Composable internal fun SliderScreen(onNavigateUp: () -> Unit) { Scaffold( + modifier = Modifier.testTag(SubScreenSemantics.Tag), topBar = { TopAppBar( title = { Text("Slider") }, diff --git a/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/StepperScreen.kt b/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/StepperScreen.kt index 79e7b1f84..d8b0c9b4f 100644 --- a/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/StepperScreen.kt +++ b/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/StepperScreen.kt @@ -16,8 +16,10 @@ import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.testTag import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp +import kiwi.orbit.compose.catalog.semantics.SubScreenSemantics import kiwi.orbit.compose.ui.OrbitTheme import kiwi.orbit.compose.ui.controls.Scaffold import kiwi.orbit.compose.ui.controls.Stepper @@ -27,6 +29,7 @@ import kiwi.orbit.compose.ui.controls.TopAppBar @Composable internal fun StepperScreen(onNavigateUp: () -> Unit) { Scaffold( + modifier = Modifier.testTag(SubScreenSemantics.Tag), topBar = { TopAppBar( title = { Text("Stepper") }, diff --git a/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/SurfaceCardScreen.kt b/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/SurfaceCardScreen.kt index 998670dce..891b7323e 100644 --- a/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/SurfaceCardScreen.kt +++ b/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/SurfaceCardScreen.kt @@ -17,7 +17,9 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.testTag import androidx.compose.ui.unit.dp +import kiwi.orbit.compose.catalog.semantics.SubScreenSemantics import kiwi.orbit.compose.illustrations.Illustrations import kiwi.orbit.compose.ui.OrbitTheme import kiwi.orbit.compose.ui.controls.Scaffold @@ -29,6 +31,7 @@ import kiwi.orbit.compose.ui.controls.TopAppBar @Composable internal fun SurfaceCardScreen(onNavigateUp: () -> Unit) { Scaffold( + modifier = Modifier.testTag(SubScreenSemantics.Tag), topBar = { TopAppBar( title = { Text("SurfaceCard") }, diff --git a/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/SwitchScreen.kt b/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/SwitchScreen.kt index 98a822cbe..7fa7f5676 100644 --- a/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/SwitchScreen.kt +++ b/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/SwitchScreen.kt @@ -15,8 +15,10 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.testTag import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp +import kiwi.orbit.compose.catalog.semantics.SubScreenSemantics import kiwi.orbit.compose.ui.controls.Scaffold import kiwi.orbit.compose.ui.controls.Separator import kiwi.orbit.compose.ui.controls.Switch @@ -26,6 +28,7 @@ import kiwi.orbit.compose.ui.controls.TopAppBar @Composable internal fun SwitchScreen(onNavigateUp: () -> Unit) { Scaffold( + modifier = Modifier.testTag(SubScreenSemantics.Tag), topBar = { TopAppBar( title = { Text("Switch") }, diff --git a/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/TabsScreen.kt b/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/TabsScreen.kt index 9d4efbd78..090a9889b 100644 --- a/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/TabsScreen.kt +++ b/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/TabsScreen.kt @@ -6,7 +6,10 @@ import androidx.compose.foundation.pager.HorizontalPager import androidx.compose.foundation.pager.rememberPagerState import androidx.compose.runtime.Composable import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.testTag import androidx.compose.ui.tooling.preview.Preview +import kiwi.orbit.compose.catalog.semantics.SubScreenSemantics import kiwi.orbit.compose.ui.controls.Scaffold import kiwi.orbit.compose.ui.controls.Tab import kiwi.orbit.compose.ui.controls.TabRow @@ -20,6 +23,7 @@ internal fun TabsScreen(onNavigateUp: () -> Unit) { val pagerState = rememberPagerState(0) { 3 } val scope = rememberCoroutineScope() Scaffold( + modifier = Modifier.testTag(SubScreenSemantics.Tag), topBar = { TopAppBar( title = { Text("Tabs") }, diff --git a/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/TagScreen.kt b/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/TagScreen.kt index 01c3cc303..e3a9118b1 100644 --- a/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/TagScreen.kt +++ b/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/TagScreen.kt @@ -17,8 +17,10 @@ import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.testTag import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp +import kiwi.orbit.compose.catalog.semantics.SubScreenSemantics import kiwi.orbit.compose.icons.Icons import kiwi.orbit.compose.ui.OrbitTheme import kiwi.orbit.compose.ui.controls.Scaffold @@ -32,6 +34,7 @@ import kotlinx.coroutines.launch internal fun TagScreen(onNavigateUp: () -> Unit) { val toastHostState = remember { ToastHostState() } Scaffold( + modifier = Modifier.testTag(SubScreenSemantics.Tag), topBar = { TopAppBar( title = { Text("Tag") }, diff --git a/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/TextFieldScreen.kt b/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/TextFieldScreen.kt index b9f61677d..aefdf8339 100644 --- a/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/TextFieldScreen.kt +++ b/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/TextFieldScreen.kt @@ -27,10 +27,12 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.focus.FocusRequester import androidx.compose.ui.focus.focusRequester +import androidx.compose.ui.platform.testTag import androidx.compose.ui.text.input.ImeAction import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp +import kiwi.orbit.compose.catalog.semantics.SubScreenSemantics import kiwi.orbit.compose.icons.Icons import kiwi.orbit.compose.ui.controls.ButtonPrimary import kiwi.orbit.compose.ui.controls.Icon @@ -48,6 +50,7 @@ import kiwi.orbit.compose.ui.controls.field.LabelLastBaseLine internal fun TextFieldScreen(onNavigateUp: () -> Unit) { var showAction by rememberSaveable { mutableStateOf(true) } Scaffold( + modifier = Modifier.testTag(SubScreenSemantics.Tag), topBar = { TopAppBar( title = { Text("Text Field") }, diff --git a/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/TileGroupScreen.kt b/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/TileGroupScreen.kt index 192420650..23620f150 100644 --- a/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/TileGroupScreen.kt +++ b/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/TileGroupScreen.kt @@ -8,10 +8,12 @@ import androidx.compose.foundation.verticalScroll import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.testTag import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import kiwi.orbit.compose.catalog.AppTheme import kiwi.orbit.compose.catalog.components.CustomPlaceholder +import kiwi.orbit.compose.catalog.semantics.SubScreenSemantics import kiwi.orbit.compose.icons.Icons import kiwi.orbit.compose.ui.OrbitTheme import kiwi.orbit.compose.ui.controls.Icon @@ -26,6 +28,7 @@ internal fun TileGroupScreen( onNavigateUp: () -> Unit, ) { Scaffold( + modifier = Modifier.testTag(SubScreenSemantics.Tag), topBar = { TopAppBar( title = { Text("TileGroup") }, diff --git a/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/TileScreen.kt b/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/TileScreen.kt index 42fd64e6b..85ff5a32c 100644 --- a/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/TileScreen.kt +++ b/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/TileScreen.kt @@ -15,10 +15,12 @@ import androidx.compose.foundation.verticalScroll import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.testTag import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import kiwi.orbit.compose.catalog.AppTheme import kiwi.orbit.compose.catalog.components.CustomPlaceholder +import kiwi.orbit.compose.catalog.semantics.SubScreenSemantics import kiwi.orbit.compose.icons.Icons import kiwi.orbit.compose.illustrations.Illustrations import kiwi.orbit.compose.ui.OrbitTheme @@ -33,6 +35,7 @@ internal fun TileScreen( onNavigateUp: () -> Unit, ) { Scaffold( + modifier = Modifier.testTag(SubScreenSemantics.Tag), topBar = { TopAppBar( title = { Text("Tile") }, diff --git a/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/TimelineScreen.kt b/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/TimelineScreen.kt index b4923624d..1acbab520 100644 --- a/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/TimelineScreen.kt +++ b/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/TimelineScreen.kt @@ -14,9 +14,11 @@ import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.testTag import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import kiwi.orbit.compose.catalog.AppTheme +import kiwi.orbit.compose.catalog.semantics.SubScreenSemantics import kiwi.orbit.compose.ui.controls.Scaffold import kiwi.orbit.compose.ui.controls.Separator import kiwi.orbit.compose.ui.controls.Text @@ -28,6 +30,7 @@ import kiwi.orbit.compose.ui.controls.TopAppBar @Composable internal fun TimelineScreen(onNavigateUp: () -> Unit) { Scaffold( + modifier = Modifier.testTag(SubScreenSemantics.Tag), topBar = { TopAppBar( title = { Text("Timeline") }, diff --git a/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/ToastScreen.kt b/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/ToastScreen.kt index 515562a58..310e42f73 100644 --- a/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/ToastScreen.kt +++ b/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/ToastScreen.kt @@ -15,7 +15,10 @@ import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.painter.Painter +import androidx.compose.ui.platform.testTag import androidx.compose.ui.unit.dp +import kiwi.orbit.compose.catalog.semantics.SubScreenSemantics +import kiwi.orbit.compose.catalog.semantics.ToastScreenSemantics import kiwi.orbit.compose.icons.Icons import kiwi.orbit.compose.ui.controls.ButtonSecondary import kiwi.orbit.compose.ui.controls.Scaffold @@ -31,6 +34,7 @@ internal fun ToastScreen( val toastHostState = remember { ToastHostState() } val scope = rememberCoroutineScope() Scaffold( + modifier = Modifier.testTag(SubScreenSemantics.Tag), topBar = { TopAppBar( title = { Text("Toast") }, @@ -70,6 +74,7 @@ private fun ToastScreenInner( onClick = { onToast("You’re signed in as jon.snow@wall.7k.") { Icons.CheckCircle } }, + modifier = Modifier.testTag(ToastScreenSemantics.ToastSignedInButtonTag), ) { Text("Toast – signed in") } ButtonSecondary( diff --git a/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/TopAppBarScreen.kt b/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/TopAppBarScreen.kt index bb591a3bf..efcc22dc6 100644 --- a/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/TopAppBarScreen.kt +++ b/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/TopAppBarScreen.kt @@ -12,6 +12,7 @@ import androidx.compose.foundation.verticalScroll import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.testTag import androidx.compose.ui.unit.dp import androidx.navigation.NavController import androidx.navigation.NavGraphBuilder @@ -20,6 +21,8 @@ import com.kiwi.navigationcompose.typed.composable import com.kiwi.navigationcompose.typed.createRoutePattern import com.kiwi.navigationcompose.typed.navigate import com.kiwi.navigationcompose.typed.navigation +import kiwi.orbit.compose.catalog.semantics.SubScreenSemantics +import kiwi.orbit.compose.catalog.semantics.TopAppBarScreenSemantics import kiwi.orbit.compose.ui.OrbitTheme import kiwi.orbit.compose.ui.controls.ButtonSecondary import kiwi.orbit.compose.ui.controls.Scaffold @@ -107,6 +110,7 @@ internal fun TopAppBarScreenInner( onSelect: (Destination) -> Unit, ) { Scaffold( + modifier = Modifier.testTag(SubScreenSemantics.Tag), topBar = { TopAppBar(title = { Text("TopAppBar") }, onNavigateUp = onNavigateUp) }, @@ -124,6 +128,7 @@ internal fun TopAppBarScreenInner( Text("Normal", style = OrbitTheme.typography.title3) ButtonSecondary( onClick = { onSelect(TopAppBarDestination.Normal) }, + modifier = Modifier.testTag(TopAppBarScreenSemantics.NormalSimpleButtonTag), ) { Text("Simple") } @@ -147,6 +152,7 @@ internal fun TopAppBarScreenInner( Text("Large", style = OrbitTheme.typography.title3) ButtonSecondary( onClick = { onSelect(TopAppBarDestination.Large) }, + modifier = Modifier.testTag(TopAppBarScreenSemantics.LargeSimpleButtonTag), ) { Text("Simple") } diff --git a/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/TopAppBarScreensLarge.kt b/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/TopAppBarScreensLarge.kt index a7363cebd..51c9ef642 100644 --- a/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/TopAppBarScreensLarge.kt +++ b/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/TopAppBarScreensLarge.kt @@ -23,9 +23,11 @@ import androidx.compose.ui.draw.clip import androidx.compose.ui.input.nestedscroll.nestedScroll import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.platform.testTag import androidx.compose.ui.unit.dp import coil.compose.AsyncImage import coil.request.ImageRequest +import kiwi.orbit.compose.catalog.semantics.TopAppBarScreenSemantics import kiwi.orbit.compose.icons.Icons import kiwi.orbit.compose.ui.OrbitTheme import kiwi.orbit.compose.ui.controls.Icon @@ -43,6 +45,7 @@ internal fun TopAppBarLargeScreen( onNavigateUp: () -> Unit, ) { Scaffold( + modifier = Modifier.testTag(TopAppBarScreenSemantics.LargeSimpleScreenTag), topBar = { TopAppBarLarge( title = { Text("Simple") }, diff --git a/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/TopAppBarScreensNormal.kt b/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/TopAppBarScreensNormal.kt index eb970b937..b9f1a6d7d 100644 --- a/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/TopAppBarScreensNormal.kt +++ b/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/TopAppBarScreensNormal.kt @@ -16,8 +16,10 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.input.nestedscroll.nestedScroll +import androidx.compose.ui.platform.testTag import androidx.compose.ui.unit.dp import kiwi.orbit.compose.catalog.components.CustomPlaceholder +import kiwi.orbit.compose.catalog.semantics.TopAppBarScreenSemantics import kiwi.orbit.compose.icons.Icons import kiwi.orbit.compose.ui.OrbitTheme import kiwi.orbit.compose.ui.controls.Icon @@ -35,6 +37,7 @@ internal fun TopAppBarNormalScreen( onNavigateUp: () -> Unit, ) { Scaffold( + modifier = Modifier.testTag(TopAppBarScreenSemantics.NormalSimpleScreenTag), topBar = { TopAppBar( title = { Text("Simple") }, diff --git a/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/TypographyScreen.kt b/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/TypographyScreen.kt index 3b2972ca9..70505d500 100644 --- a/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/TypographyScreen.kt +++ b/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/TypographyScreen.kt @@ -13,9 +13,11 @@ import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.testTag import androidx.compose.ui.text.TextStyle import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp +import kiwi.orbit.compose.catalog.semantics.SubScreenSemantics import kiwi.orbit.compose.ui.OrbitTheme import kiwi.orbit.compose.ui.controls.Scaffold import kiwi.orbit.compose.ui.controls.Text @@ -26,6 +28,7 @@ import kotlin.math.roundToInt @Composable internal fun TypographyScreen(onNavigateUp: () -> Unit) { Scaffold( + modifier = Modifier.testTag(SubScreenSemantics.Tag), topBar = { TopAppBar( title = { Text("Typography") }, diff --git a/contributing.md b/contributing.md index 08d0a164e..d3f7db8d6 100644 --- a/contributing.md +++ b/contributing.md @@ -27,6 +27,7 @@ Our code review will focus on: - add catalog demonstration; - add entry into `component-status.yaml`; - add documentation to docs (component.mdx) including UI testing documentation; resolve the correct name using [the Orbit repo](https://github.com/kiwicom/orbit/tree/master/docs/src/documentation) and naming pattern using the dir name as a file name; +- add baseline profile generating function to `BaselineProfileGenerator`; make sure the test uses all the code of the new component and is **stable**; ## Screenshot Testing diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index d71783754..acad62e32 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -33,10 +33,13 @@ android-lint-impl = { module = "com.android.tools.lint:lint", version.ref = "and android-lint-tests = { module = "com.android.tools.lint:lint-tests", version.ref = "android-lint" } androidx-activityCompose = { module = "androidx.activity:activity-compose", version.ref = "androidx-activityCompose" } androidx-activityComposeCatalog = { module = "androidx.activity:activity-compose", version.ref = "androidx-activityComposeCatalog" } +androidx-benchmark-macro = { module = "androidx.benchmark:benchmark-macro-junit4", version = "1.2.0-beta05" } androidx-core = { module = "androidx.core:core-ktx", version.ref = "androidx-core" } androidx-constraintLayout = { module = "androidx.constraintlayout:constraintlayout-compose", version.ref = "androidx-constraint-layout" } androidx-customView = { module = "androidx.customview:customview", version = "1.1.0" } androidx-customViewPoolingContainer = { module = "androidx.customview:customview-poolingcontainer", version = "1.0.0" } +androidx-test-runner = { module = "androidx.test:runner", version = "1.5.2" } +androidx-test-uiAutomator = { module = "androidx.test.uiautomator:uiautomator", version = "2.2.0" } accompanist-systemController = "com.google.accompanist:accompanist-systemuicontroller:0.32.0" coil = { module = "io.coil-kt:coil-compose", version = "2.4.0" } compose-animation = { module = "androidx.compose.animation:animation" } diff --git a/icons/build.gradle.kts b/icons/build.gradle.kts index 4eab80045..ba3c568e6 100644 --- a/icons/build.gradle.kts +++ b/icons/build.gradle.kts @@ -3,6 +3,7 @@ plugins { kotlin("multiplatform") id("com.android.library") + id("androidx.baselineprofile") id("org.jetbrains.dokka") id("org.jmailen.kotlinter") id("com.vanniktech.maven.publish.base") @@ -54,6 +55,14 @@ kotlinter { reporters = arrayOf("json") } +baselineProfile { + baselineProfileOutputDir = "." + + filter { + include("kiwi.orbit.compose.icons.**") + } +} + dependencies { implementation(platform(libs.compose.bom)) @@ -61,4 +70,6 @@ dependencies { implementation(libs.androidx.core) implementation(libs.compose.runtime) implementation(libs.compose.ui) + + baselineProfile(projects.baselineprofile) } diff --git a/illustrations/build.gradle.kts b/illustrations/build.gradle.kts index c4764b4f4..86e8aad16 100644 --- a/illustrations/build.gradle.kts +++ b/illustrations/build.gradle.kts @@ -3,6 +3,7 @@ plugins { kotlin("multiplatform") id("com.android.library") + id("androidx.baselineprofile") id("org.jetbrains.dokka") id("org.jmailen.kotlinter") id("com.vanniktech.maven.publish.base") @@ -51,6 +52,14 @@ kotlinter { reporters = arrayOf("json") } +baselineProfile { + baselineProfileOutputDir = "." + + filter { + include("kiwi.orbit.compose.illustrations.**") + } +} + dependencies { implementation(platform(libs.compose.bom)) @@ -58,4 +67,6 @@ dependencies { implementation(libs.androidx.core) implementation(libs.compose.runtime) implementation(libs.compose.ui) + + baselineProfile(projects.baselineprofile) } diff --git a/settings.gradle.kts b/settings.gradle.kts index 89f77801a..4530877fc 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -31,9 +31,11 @@ dependencyResolutionManagement { } } +include(":baselineprofile") include(":catalog") -include(":ui") +include(":catalog:semantics") +include(":generator") include(":icons") include(":illustrations") include(":lint") -include(":generator") +include(":ui") diff --git a/ui/build.gradle.kts b/ui/build.gradle.kts index 90fac9752..5276c6fc1 100644 --- a/ui/build.gradle.kts +++ b/ui/build.gradle.kts @@ -5,6 +5,7 @@ import org.jmailen.gradle.kotlinter.tasks.ConfigurableKtLintTask plugins { kotlin("multiplatform") id("com.android.library") + id("androidx.baselineprofile") id("org.jetbrains.dokka") id("org.jmailen.kotlinter") id("com.vanniktech.maven.publish.base") @@ -77,6 +78,14 @@ tasks.withType { exclude { it.file.absoluteFile.endsWith("SwipeableV2.kt") } } +baselineProfile { + baselineProfileOutputDir = "." + + filter { + include("kiwi.orbit.compose.ui.**") + } +} + dependencies { implementation(platform(libs.compose.bom)) @@ -93,6 +102,8 @@ dependencies { implementation(libs.compose.uiUtil) implementation(libs.kotlin.stdlib) + baselineProfile(projects.baselineprofile) + debugImplementation(libs.compose.tooling) debugImplementation(libs.androidx.activityCompose) debugImplementation(libs.androidx.customView)