diff --git a/app/src/testDemo/java/com/google/samples/apps/nowinandroid/ui/NiaAppScreenSizesScreenshotTests.kt b/app/src/testDemo/java/com/google/samples/apps/nowinandroid/ui/NiaAppScreenSizesScreenshotTests.kt index 94563abe4..d16d9bd93 100644 --- a/app/src/testDemo/java/com/google/samples/apps/nowinandroid/ui/NiaAppScreenSizesScreenshotTests.kt +++ b/app/src/testDemo/java/com/google/samples/apps/nowinandroid/ui/NiaAppScreenSizesScreenshotTests.kt @@ -1,5 +1,5 @@ /* - * Copyright 2022 The Android Open Source Project + * Copyright 2023 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/build-logic/convention/src/main/kotlin/AndroidLibraryComposeConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidLibraryComposeConventionPlugin.kt index 707ca8055..05f442354 100644 --- a/build-logic/convention/src/main/kotlin/AndroidLibraryComposeConventionPlugin.kt +++ b/build-logic/convention/src/main/kotlin/AndroidLibraryComposeConventionPlugin.kt @@ -18,7 +18,9 @@ import com.android.build.gradle.LibraryExtension import com.google.samples.apps.nowinandroid.configureAndroidCompose import org.gradle.api.Plugin import org.gradle.api.Project +import org.gradle.kotlin.dsl.dependencies import org.gradle.kotlin.dsl.getByType +import org.gradle.kotlin.dsl.kotlin class AndroidLibraryComposeConventionPlugin : Plugin { override fun apply(target: Project) { diff --git a/build-logic/convention/src/main/kotlin/AndroidLibraryConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidLibraryConventionPlugin.kt index a7c245318..ef84cfbb4 100644 --- a/build-logic/convention/src/main/kotlin/AndroidLibraryConventionPlugin.kt +++ b/build-logic/convention/src/main/kotlin/AndroidLibraryConventionPlugin.kt @@ -47,9 +47,11 @@ class AndroidLibraryConventionPlugin : Plugin { disableUnnecessaryAndroidTests(target) } dependencies { - add("androidTestImplementation", kotlin("test")) add("testImplementation", kotlin("test")) + add("testImplementation", project(":core:testing")) + add("androidTestImplementation", kotlin("test")) + add("androidTestImplementation", project(":core:testing")) } } } -} \ No newline at end of file +} diff --git a/core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/Button.kt b/core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/Button.kt index e4b437dfe..966014fd9 100644 --- a/core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/Button.kt +++ b/core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/Button.kt @@ -21,15 +21,20 @@ import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.RowScope import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.sizeIn import androidx.compose.material3.Button import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedButton +import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp +import com.google.samples.apps.nowinandroid.core.designsystem.icon.NiaIcons +import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme /** * Now in Android filled button with generic content slot. Wraps Material 3 [Button]. @@ -260,6 +265,50 @@ private fun NiaButtonContent( } } +@ThemePreviews +@Composable +fun NiaButtonPreview() { + NiaTheme { + NiaBackground(modifier = Modifier.size(150.dp, 50.dp)) { + NiaButton(onClick = {}, text = { Text("Test button") }) + } + } +} + +@ThemePreviews +@Composable +fun NiaOutlinedButtonPreview() { + NiaTheme() { + NiaBackground(modifier = Modifier.size(150.dp, 50.dp)) { + NiaOutlinedButton(onClick = {}, text = { Text("Test button") }) + } + } +} + +@ThemePreviews +@Composable +fun NiaButtonPreview2() { + NiaTheme { + NiaBackground(modifier = Modifier.size(150.dp, 50.dp)) { + NiaButton(onClick = {}, text = { Text("Test button") }) + } + } +} + +@ThemePreviews +@Composable +fun NiaButtonLeadingIconPreview() { + NiaTheme { + NiaBackground(modifier = Modifier.size(150.dp, 50.dp)) { + NiaButton( + onClick = {}, + text = { Text("Test button") }, + leadingIcon = { Icon(imageVector = NiaIcons.Add, contentDescription = null) }, + ) + } + } +} + /** * Now in Android button default values. */ diff --git a/core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/Chip.kt b/core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/Chip.kt index b291b3fa1..d1b7d124d 100644 --- a/core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/Chip.kt +++ b/core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/Chip.kt @@ -16,6 +16,7 @@ package com.google.samples.apps.nowinandroid.core.designsystem.component +import androidx.compose.foundation.layout.size import androidx.compose.foundation.shape.CircleShape import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.FilterChip @@ -23,11 +24,13 @@ import androidx.compose.material3.FilterChipDefaults import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.ProvideTextStyle +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.dp import com.google.samples.apps.nowinandroid.core.designsystem.icon.NiaIcons +import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme /** * Now in Android filter chip with included leading checked icon as well as text content slot. @@ -103,6 +106,18 @@ fun NiaFilterChip( ) } +@ThemePreviews +@Composable +fun ChipPreview() { + NiaTheme { + NiaBackground(modifier = Modifier.size(80.dp, 20.dp)) { + NiaFilterChip(selected = true, onSelectedChange = {}) { + Text("Chip") + } + } + } +} + /** * Now in Android chip default values. */ diff --git a/core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/IconButton.kt b/core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/IconButton.kt index b0dda0af1..503342d30 100644 --- a/core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/IconButton.kt +++ b/core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/IconButton.kt @@ -17,12 +17,15 @@ package com.google.samples.apps.nowinandroid.core.designsystem.component import androidx.compose.material3.FilledIconToggleButton +import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.IconButtonDefaults import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color +import com.google.samples.apps.nowinandroid.core.designsystem.icon.NiaIcons +import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme /** * Now in Android toggle button with icon and checked icon content slots. Wraps Material 3 @@ -68,6 +71,52 @@ fun NiaIconToggleButton( } } +@ThemePreviews +@Composable +fun IconButtonPreview() { + NiaTheme { + NiaIconToggleButton( + checked = true, + onCheckedChange = { }, + icon = { + Icon( + imageVector = NiaIcons.BookmarkBorder, + contentDescription = null, + ) + }, + checkedIcon = { + Icon( + imageVector = NiaIcons.Bookmark, + contentDescription = null, + ) + }, + ) + } +} + +@ThemePreviews +@Composable +fun IconButtonPreviewUnchecked() { + NiaTheme { + NiaIconToggleButton( + checked = false, + onCheckedChange = { }, + icon = { + Icon( + imageVector = NiaIcons.BookmarkBorder, + contentDescription = null, + ) + }, + checkedIcon = { + Icon( + imageVector = NiaIcons.Bookmark, + contentDescription = null, + ) + }, + ) + } +} + /** * Now in Android icon button default values. */ diff --git a/core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/LoadingWheel.kt b/core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/LoadingWheel.kt index 10ef1bfce..21dfbc8c3 100644 --- a/core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/LoadingWheel.kt +++ b/core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/LoadingWheel.kt @@ -88,6 +88,7 @@ fun NiaLoadingWheel( // Specifies the color animation for the base-to-progress line color change val baseLineColor = MaterialTheme.colorScheme.onBackground val progressLineColor = MaterialTheme.colorScheme.inversePrimary + val colorAnimValues = (0 until NUM_OF_LINES).map { index -> infiniteTransition.animateColor( initialValue = baseLineColor, diff --git a/core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/Navigation.kt b/core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/Navigation.kt index 624cf25ac..f1db03f66 100644 --- a/core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/Navigation.kt +++ b/core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/Navigation.kt @@ -18,6 +18,7 @@ package com.google.samples.apps.nowinandroid.core.designsystem.component import androidx.compose.foundation.layout.ColumnScope import androidx.compose.foundation.layout.RowScope +import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.NavigationBar import androidx.compose.material3.NavigationBarItem @@ -25,10 +26,13 @@ import androidx.compose.material3.NavigationBarItemDefaults import androidx.compose.material3.NavigationRail import androidx.compose.material3.NavigationRailItem import androidx.compose.material3.NavigationRailItemDefaults +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.dp +import com.google.samples.apps.nowinandroid.core.designsystem.icon.NiaIcons +import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme /** * Now in Android navigation bar item with icon and label content slots. Wraps Material 3 @@ -161,6 +165,46 @@ fun NiaNavigationRail( ) } +@ThemePreviews +@Composable +fun NiaNavigationPreview() { + val items = listOf("For you", "Saved", "Interests") + val icons = listOf( + NiaIcons.UpcomingBorder, + NiaIcons.BookmarksBorder, + NiaIcons.Grid3x3, + ) + val selectedIcons = listOf( + NiaIcons.Upcoming, + NiaIcons.Bookmarks, + NiaIcons.Grid3x3, + ) + + NiaTheme { + NiaNavigationBar { + items.forEachIndexed { index, item -> + NiaNavigationBarItem( + icon = { + Icon( + imageVector = icons[index], + contentDescription = item, + ) + }, + selectedIcon = { + Icon( + imageVector = selectedIcons[index], + contentDescription = item, + ) + }, + label = { Text(item) }, + selected = index == 0, + onClick = { }, + ) + } + } + } +} + /** * Now in Android navigation default values. */ diff --git a/core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/Tabs.kt b/core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/Tabs.kt index ad2f3799c..92cd9aa8f 100644 --- a/core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/Tabs.kt +++ b/core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/Tabs.kt @@ -24,11 +24,15 @@ import androidx.compose.material3.Tab import androidx.compose.material3.TabRow import androidx.compose.material3.TabRowDefaults import androidx.compose.material3.TabRowDefaults.tabIndicatorOffset +import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp +import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme /** * Now in Android tab. Wraps Material 3 [Tab] and shifts text label down. @@ -97,6 +101,23 @@ fun NiaTabRow( ) } +@ThemePreviews +@Composable +fun TabsPreview() { + NiaTheme { + val titles = listOf("Topics", "People") + NiaTabRow(selectedTabIndex = 0) { + titles.forEachIndexed { index, title -> + NiaTab( + selected = index == 0, + onClick = { }, + text = { Text(text = title) }, + ) + } + } + } +} + object NiaTabDefaults { val TabTopPadding = 7.dp } diff --git a/core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/Tag.kt b/core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/Tag.kt index ba8fde1c9..8ca1588a8 100644 --- a/core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/Tag.kt +++ b/core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/Tag.kt @@ -20,10 +20,12 @@ import androidx.compose.foundation.layout.Box import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.MaterialTheme import androidx.compose.material3.ProvideTextStyle +import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.material3.contentColorFor import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier +import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme @Composable fun NiaTopicTag( @@ -59,6 +61,16 @@ fun NiaTopicTag( } } +@ThemePreviews +@Composable +fun TagPreview() { + NiaTheme { + NiaTopicTag(followed = true, onClick = {}) { + Text("Topic".uppercase()) + } + } +} + /** * Now in Android tag default values. */ diff --git a/core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/TopAppBar.kt b/core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/TopAppBar.kt index 28007a3b1..99f935d2a 100644 --- a/core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/TopAppBar.kt +++ b/core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/TopAppBar.kt @@ -73,35 +73,6 @@ fun NiaTopAppBar( ) } -/** - * Top app bar with action, displayed on the right - */ -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun NiaTopAppBar( - @StringRes titleRes: Int, - actionIcon: ImageVector, - actionIconContentDescription: String?, - modifier: Modifier = Modifier, - colors: TopAppBarColors = TopAppBarDefaults.centerAlignedTopAppBarColors(), - onActionClick: () -> Unit = {}, -) { - CenterAlignedTopAppBar( - title = { Text(text = stringResource(id = titleRes)) }, - actions = { - IconButton(onClick = onActionClick) { - Icon( - imageVector = actionIcon, - contentDescription = actionIconContentDescription, - tint = MaterialTheme.colorScheme.onSurface, - ) - } - }, - colors = colors, - modifier = modifier.testTag("niaTopAppBar"), - ) -} - @OptIn(ExperimentalMaterial3Api::class) @Preview("Top App Bar") @Composable diff --git a/core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/ViewToggle.kt b/core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/ViewToggle.kt index c6ec77a92..d368c46d7 100644 --- a/core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/ViewToggle.kt +++ b/core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/ViewToggle.kt @@ -24,11 +24,15 @@ import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.ProvideTextStyle +import androidx.compose.material3.Surface +import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier +import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.google.samples.apps.nowinandroid.core.designsystem.icon.NiaIcons +import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme /** * Now in Android view toggle button with included trailing icon as well as compact and expanded @@ -105,6 +109,36 @@ private fun NiaViewToggleButtonContent( } } +@ThemePreviews +@Composable +fun ViewTogglePreviewExpanded() { + NiaTheme { + Surface { + NiaViewToggleButton( + expanded = true, + onExpandedChange = { }, + compactText = { Text(text = "Compact view") }, + expandedText = { Text(text = "Expanded view") }, + ) + } + } +} + +@Preview +@Composable +fun ViewTogglePreviewCompact() { + NiaTheme { + Surface { + NiaViewToggleButton( + expanded = false, + onExpandedChange = { }, + compactText = { Text(text = "Compact view") }, + expandedText = { Text(text = "Expanded view") }, + ) + } + } +} + /** * Now in Android view toggle default values. */ diff --git a/core/designsystem/src/test/java/com/google/samples/apps/nowinandroid/core/designsystem/BackgroundScreenshotTests.kt b/core/designsystem/src/test/java/com/google/samples/apps/nowinandroid/core/designsystem/BackgroundScreenshotTests.kt new file mode 100644 index 000000000..d3349de80 --- /dev/null +++ b/core/designsystem/src/test/java/com/google/samples/apps/nowinandroid/core/designsystem/BackgroundScreenshotTests.kt @@ -0,0 +1,63 @@ +/* + * Copyright 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.samples.apps.nowinandroid.core.designsystem + +import androidx.activity.ComponentActivity +import androidx.compose.foundation.layout.size +import androidx.compose.material3.Text +import androidx.compose.ui.Modifier +import androidx.compose.ui.test.junit4.createAndroidComposeRule +import androidx.compose.ui.unit.dp +import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaBackground +import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaGradientBackground +import com.google.samples.apps.nowinandroid.core.testing.util.captureMultiTheme +import dagger.hilt.android.testing.HiltTestApplication +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.RobolectricTestRunner +import org.robolectric.annotation.Config +import org.robolectric.annotation.GraphicsMode +import org.robolectric.annotation.LooperMode + +@RunWith(RobolectricTestRunner::class) +@GraphicsMode(GraphicsMode.Mode.NATIVE) +@Config(application = HiltTestApplication::class, sdk = [33], qualifiers = "480dpi") +@LooperMode(LooperMode.Mode.PAUSED) +class BackgroundScreenshotTests { + + @get:Rule + val composeTestRule = createAndroidComposeRule() + + @Test + fun niaBackground_multipleThemes() { + composeTestRule.captureMultiTheme("Background") { description -> + NiaBackground(Modifier.size(100.dp)) { + Text("$description background") + } + } + } + + @Test + fun niaGradientBackground_multipleThemes() { + composeTestRule.captureMultiTheme("Background", "GradientBackground") { description -> + NiaGradientBackground(Modifier.size(100.dp)) { + Text("$description background") + } + } + } +} diff --git a/core/designsystem/src/test/java/com/google/samples/apps/nowinandroid/core/designsystem/ButtonScreenshotTests.kt b/core/designsystem/src/test/java/com/google/samples/apps/nowinandroid/core/designsystem/ButtonScreenshotTests.kt new file mode 100644 index 000000000..d3aa4224f --- /dev/null +++ b/core/designsystem/src/test/java/com/google/samples/apps/nowinandroid/core/designsystem/ButtonScreenshotTests.kt @@ -0,0 +1,80 @@ +/* + * Copyright 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.samples.apps.nowinandroid.core.designsystem + +import androidx.activity.ComponentActivity +import androidx.compose.material3.Icon +import androidx.compose.material3.Surface +import androidx.compose.material3.Text +import androidx.compose.ui.test.junit4.createAndroidComposeRule +import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaButton +import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaOutlinedButton +import com.google.samples.apps.nowinandroid.core.designsystem.icon.NiaIcons +import com.google.samples.apps.nowinandroid.core.testing.util.captureMultiTheme +import dagger.hilt.android.testing.HiltTestApplication +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.RobolectricTestRunner +import org.robolectric.annotation.Config +import org.robolectric.annotation.GraphicsMode +import org.robolectric.annotation.LooperMode + +@RunWith(RobolectricTestRunner::class) +@GraphicsMode(GraphicsMode.Mode.NATIVE) +@Config(application = HiltTestApplication::class, sdk = [33], qualifiers = "480dpi") +@LooperMode(LooperMode.Mode.PAUSED) +class ButtonScreenshotTests { + + @get:Rule + val composeTestRule = createAndroidComposeRule() + + @Test + fun niaButton_multipleThemes() { + composeTestRule.captureMultiTheme("Button") { description -> + Surface { + NiaButton(onClick = {}, text = { Text("$description Button") }) + } + } + } + + @Test + fun niaOutlineButton_multipleThemes() { + composeTestRule.captureMultiTheme("Button", "OutlineButton") { description -> + Surface { + NiaOutlinedButton(onClick = {}, text = { Text("$description OutlineButton") }) + } + } + } + + @Test + fun niaButton_leadingIcon_multipleThemes() { + composeTestRule.captureMultiTheme( + name = "Button", + overrideFileName = "ButtonLeadingIcon", + shouldCompareAndroidTheme = false, + ) { description -> + Surface { + NiaButton( + onClick = {}, + text = { Text("$description Icon Button") }, + leadingIcon = { Icon(imageVector = NiaIcons.Add, contentDescription = null) }, + ) + } + } + } +} diff --git a/core/designsystem/src/test/java/com/google/samples/apps/nowinandroid/core/designsystem/FilterChipScreenshotTests.kt b/core/designsystem/src/test/java/com/google/samples/apps/nowinandroid/core/designsystem/FilterChipScreenshotTests.kt new file mode 100644 index 000000000..3b2078c8a --- /dev/null +++ b/core/designsystem/src/test/java/com/google/samples/apps/nowinandroid/core/designsystem/FilterChipScreenshotTests.kt @@ -0,0 +1,98 @@ +/* + * Copyright 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.samples.apps.nowinandroid.core.designsystem + +import androidx.activity.ComponentActivity +import androidx.compose.material3.Surface +import androidx.compose.material3.Text +import androidx.compose.runtime.CompositionLocalProvider +import androidx.compose.ui.platform.LocalInspectionMode +import androidx.compose.ui.test.junit4.createAndroidComposeRule +import androidx.compose.ui.test.onRoot +import androidx.compose.ui.unit.DpSize +import androidx.compose.ui.unit.dp +import com.github.takahirom.roborazzi.captureRoboImage +import com.google.accompanist.testharness.TestHarness +import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaBackground +import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaFilterChip +import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme +import com.google.samples.apps.nowinandroid.core.testing.util.DefaultRoborazziOptions +import com.google.samples.apps.nowinandroid.core.testing.util.captureMultiTheme +import dagger.hilt.android.testing.HiltTestApplication +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.RobolectricTestRunner +import org.robolectric.annotation.Config +import org.robolectric.annotation.GraphicsMode +import org.robolectric.annotation.LooperMode + +@RunWith(RobolectricTestRunner::class) +@GraphicsMode(GraphicsMode.Mode.NATIVE) +@Config(application = HiltTestApplication::class, sdk = [33], qualifiers = "480dpi") +@LooperMode(LooperMode.Mode.PAUSED) +class FilterChipScreenshotTests() { + + @get:Rule + val composeTestRule = createAndroidComposeRule() + + @Test + fun filterChip_multipleThemes() { + composeTestRule.captureMultiTheme("FilterChip") { description -> + Surface { + NiaFilterChip(selected = false, onSelectedChange = {}) { + Text("Unselected chip") + } + } + } + } + + @Test + fun filterChip_multipleThemes_selected() { + composeTestRule.captureMultiTheme("FilterChip", "FilterChipSelected") { description -> + Surface { + NiaFilterChip(selected = true, onSelectedChange = {}) { + Text("Selected Chip") + } + } + } + } + + @Test + fun filterChip_hugeFont() { + composeTestRule.setContent { + CompositionLocalProvider( + LocalInspectionMode provides true, + ) { + TestHarness(fontScale = 2f, size = DpSize(80.dp, 40.dp)) { + NiaTheme { + NiaBackground { + NiaFilterChip(selected = true, onSelectedChange = {}) { + Text("Chip") + } + } + } + } + } + } + composeTestRule.onRoot() + .captureRoboImage( + "src/test/screenshots/FilterChip/FilterChip_fontScale2.png", + roborazziOptions = DefaultRoborazziOptions, + ) + } +} diff --git a/core/designsystem/src/test/java/com/google/samples/apps/nowinandroid/core/designsystem/IconButtonScreenshotTests.kt b/core/designsystem/src/test/java/com/google/samples/apps/nowinandroid/core/designsystem/IconButtonScreenshotTests.kt new file mode 100644 index 000000000..4d40f3bce --- /dev/null +++ b/core/designsystem/src/test/java/com/google/samples/apps/nowinandroid/core/designsystem/IconButtonScreenshotTests.kt @@ -0,0 +1,80 @@ +/* + * Copyright 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.samples.apps.nowinandroid.core.designsystem + +import androidx.activity.ComponentActivity +import androidx.compose.material3.Icon +import androidx.compose.material3.Surface +import androidx.compose.runtime.Composable +import androidx.compose.ui.test.junit4.createAndroidComposeRule +import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaIconToggleButton +import com.google.samples.apps.nowinandroid.core.designsystem.icon.NiaIcons +import com.google.samples.apps.nowinandroid.core.testing.util.captureMultiTheme +import dagger.hilt.android.testing.HiltTestApplication +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.RobolectricTestRunner +import org.robolectric.annotation.Config +import org.robolectric.annotation.GraphicsMode +import org.robolectric.annotation.LooperMode + +@RunWith(RobolectricTestRunner::class) +@GraphicsMode(GraphicsMode.Mode.NATIVE) +@Config(application = HiltTestApplication::class, sdk = [33], qualifiers = "480dpi") +@LooperMode(LooperMode.Mode.PAUSED) +class IconButtonScreenshotTests { + + @get:Rule + val composeTestRule = createAndroidComposeRule() + + @Test + fun iconButton_multipleThemes() { + composeTestRule.captureMultiTheme("IconButton") { description -> + NiaIconToggleExample(false) + } + } + + @Test + fun iconButton_unchecked_multipleThemes() { + composeTestRule.captureMultiTheme("IconButton", "IconButtonUnchecked") { description -> + Surface { + NiaIconToggleExample(true) + } + } + } + + @Composable + private fun NiaIconToggleExample(checked: Boolean) { + NiaIconToggleButton( + checked = checked, + onCheckedChange = { }, + icon = { + Icon( + imageVector = NiaIcons.BookmarkBorder, + contentDescription = null, + ) + }, + checkedIcon = { + Icon( + imageVector = NiaIcons.Bookmark, + contentDescription = null, + ) + }, + ) + } +} diff --git a/core/designsystem/src/test/java/com/google/samples/apps/nowinandroid/core/designsystem/LoadingWheelScreenshotTests.kt b/core/designsystem/src/test/java/com/google/samples/apps/nowinandroid/core/designsystem/LoadingWheelScreenshotTests.kt new file mode 100644 index 000000000..412f42370 --- /dev/null +++ b/core/designsystem/src/test/java/com/google/samples/apps/nowinandroid/core/designsystem/LoadingWheelScreenshotTests.kt @@ -0,0 +1,83 @@ +/* + * Copyright 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.samples.apps.nowinandroid.core.designsystem + +import androidx.activity.ComponentActivity +import androidx.compose.material3.Surface +import androidx.compose.ui.test.junit4.createAndroidComposeRule +import androidx.compose.ui.test.onRoot +import com.github.takahirom.roborazzi.captureRoboImage +import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaLoadingWheel +import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaOverlayLoadingWheel +import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme +import com.google.samples.apps.nowinandroid.core.testing.util.DefaultRoborazziOptions +import com.google.samples.apps.nowinandroid.core.testing.util.captureMultiTheme +import dagger.hilt.android.testing.HiltTestApplication +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.RobolectricTestRunner +import org.robolectric.annotation.Config +import org.robolectric.annotation.GraphicsMode +import org.robolectric.annotation.LooperMode + +@RunWith(RobolectricTestRunner::class) +@GraphicsMode(GraphicsMode.Mode.NATIVE) +@Config(application = HiltTestApplication::class, sdk = [33], qualifiers = "480dpi") +@LooperMode(LooperMode.Mode.PAUSED) +class LoadingWheelScreenshotTests() { + + @get:Rule + val composeTestRule = createAndroidComposeRule() + + @Test + fun loadingWheel_multipleThemes() { + composeTestRule.captureMultiTheme("LoadingWheel") { + Surface { + NiaLoadingWheel(contentDesc = "test") + } + } + } + + @Test + fun overlayLoadingWheel_multipleThemes() { + composeTestRule.captureMultiTheme("LoadingWheel", "OverlayLoadingWheel") { + Surface { + NiaOverlayLoadingWheel(contentDesc = "test") + } + } + } + + @Test + fun loadingWheelAnimation() { + composeTestRule.mainClock.autoAdvance = false + composeTestRule.setContent { + NiaTheme() { + NiaLoadingWheel(contentDesc = "") + } + } + // Try multiple frames of the animation; some arbitrary, some synchronized with duration. + listOf(20L, 115L, 724L, 1000L).forEach { deltaTime -> + composeTestRule.mainClock.advanceTimeBy(deltaTime) + composeTestRule.onRoot() + .captureRoboImage( + "src/test/screenshots/LoadingWheel/LoadingWheel_animation_$deltaTime.png", + roborazziOptions = DefaultRoborazziOptions, + ) + } + } +} diff --git a/core/designsystem/src/test/java/com/google/samples/apps/nowinandroid/core/designsystem/NavigationScreenshotTests.kt b/core/designsystem/src/test/java/com/google/samples/apps/nowinandroid/core/designsystem/NavigationScreenshotTests.kt new file mode 100644 index 000000000..05976ba47 --- /dev/null +++ b/core/designsystem/src/test/java/com/google/samples/apps/nowinandroid/core/designsystem/NavigationScreenshotTests.kt @@ -0,0 +1,108 @@ +/* + * Copyright 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.samples.apps.nowinandroid.core.designsystem + +import androidx.activity.ComponentActivity +import androidx.compose.material3.Icon +import androidx.compose.material3.Surface +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.CompositionLocalProvider +import androidx.compose.ui.platform.LocalInspectionMode +import androidx.compose.ui.test.junit4.createAndroidComposeRule +import androidx.compose.ui.test.onRoot +import com.github.takahirom.roborazzi.captureRoboImage +import com.google.accompanist.testharness.TestHarness +import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaNavigationBar +import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaNavigationBarItem +import com.google.samples.apps.nowinandroid.core.designsystem.icon.NiaIcons +import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme +import com.google.samples.apps.nowinandroid.core.testing.util.DefaultRoborazziOptions +import com.google.samples.apps.nowinandroid.core.testing.util.captureMultiTheme +import dagger.hilt.android.testing.HiltTestApplication +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.RobolectricTestRunner +import org.robolectric.annotation.Config +import org.robolectric.annotation.GraphicsMode +import org.robolectric.annotation.LooperMode + +@RunWith(RobolectricTestRunner::class) +@GraphicsMode(GraphicsMode.Mode.NATIVE) +@Config(application = HiltTestApplication::class, sdk = [33], qualifiers = "480dpi") +@LooperMode(LooperMode.Mode.PAUSED) +class NavigationScreenshotTests() { + + @get:Rule + val composeTestRule = createAndroidComposeRule() + + @Test + fun navigation_multipleThemes() { + composeTestRule.captureMultiTheme("Navigation") { + Surface { + NiaNavigationBarExample() + } + } + } + + @Test + fun navigation_hugeFont() { + composeTestRule.setContent { + CompositionLocalProvider( + LocalInspectionMode provides true, + ) { + TestHarness(fontScale = 2f) { + NiaTheme { + NiaNavigationBarExample("Looong item") + } + } + } + } + composeTestRule.onRoot() + .captureRoboImage( + "src/test/screenshots/Navigation" + + "/Navigation_fontScale2.png", + roborazziOptions = DefaultRoborazziOptions, + ) + } + + @Composable + private fun NiaNavigationBarExample(label: String = "Item") { + NiaNavigationBar { + (0..2).forEach { index -> + NiaNavigationBarItem( + icon = { + Icon( + imageVector = NiaIcons.UpcomingBorder, + contentDescription = "", + ) + }, + selectedIcon = { + Icon( + imageVector = NiaIcons.Upcoming, + contentDescription = "", + ) + }, + label = { Text(label) }, + selected = index == 0, + onClick = { }, + ) + } + } + } +} diff --git a/core/designsystem/src/test/java/com/google/samples/apps/nowinandroid/core/designsystem/TabsScreenshotTests.kt b/core/designsystem/src/test/java/com/google/samples/apps/nowinandroid/core/designsystem/TabsScreenshotTests.kt new file mode 100644 index 000000000..76117db2e --- /dev/null +++ b/core/designsystem/src/test/java/com/google/samples/apps/nowinandroid/core/designsystem/TabsScreenshotTests.kt @@ -0,0 +1,94 @@ +/* + * Copyright 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.samples.apps.nowinandroid.core.designsystem + +import androidx.activity.ComponentActivity +import androidx.compose.material3.Surface +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.CompositionLocalProvider +import androidx.compose.ui.platform.LocalInspectionMode +import androidx.compose.ui.test.junit4.createAndroidComposeRule +import androidx.compose.ui.test.onRoot +import com.github.takahirom.roborazzi.captureRoboImage +import com.google.accompanist.testharness.TestHarness +import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaTab +import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaTabRow +import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme +import com.google.samples.apps.nowinandroid.core.testing.util.DefaultRoborazziOptions +import com.google.samples.apps.nowinandroid.core.testing.util.captureMultiTheme +import dagger.hilt.android.testing.HiltTestApplication +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.RobolectricTestRunner +import org.robolectric.annotation.Config +import org.robolectric.annotation.GraphicsMode +import org.robolectric.annotation.LooperMode + +@RunWith(RobolectricTestRunner::class) +@GraphicsMode(GraphicsMode.Mode.NATIVE) +@Config(application = HiltTestApplication::class, sdk = [33], qualifiers = "480dpi") +@LooperMode(LooperMode.Mode.PAUSED) +class TabsScreenshotTests() { + + @get:Rule + val composeTestRule = createAndroidComposeRule() + + @Test + fun tabs_multipleThemes() { + composeTestRule.captureMultiTheme("Tabs") { + NiaTabsExample() + } + } + + @Test + fun tabs_hugeFont() { + composeTestRule.setContent { + CompositionLocalProvider( + LocalInspectionMode provides true, + ) { + TestHarness(fontScale = 2f) { + NiaTheme { + NiaTabsExample("Looooong item") + } + } + } + } + composeTestRule.onRoot() + .captureRoboImage( + "src/test/screenshots/Tabs/Tabs_fontScale2.png", + roborazziOptions = DefaultRoborazziOptions, + ) + } + + @Composable + private fun NiaTabsExample(label: String = "Topics") { + Surface { + val titles = listOf(label, "People") + NiaTabRow(selectedTabIndex = 0) { + titles.forEachIndexed { index, title -> + NiaTab( + selected = index == 0, + onClick = { }, + text = { Text(text = title) }, + ) + } + } + } + } +} diff --git a/core/designsystem/src/test/java/com/google/samples/apps/nowinandroid/core/designsystem/TagScreenshotTests.kt b/core/designsystem/src/test/java/com/google/samples/apps/nowinandroid/core/designsystem/TagScreenshotTests.kt new file mode 100644 index 000000000..9db4d02a3 --- /dev/null +++ b/core/designsystem/src/test/java/com/google/samples/apps/nowinandroid/core/designsystem/TagScreenshotTests.kt @@ -0,0 +1,79 @@ +/* + * Copyright 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.samples.apps.nowinandroid.core.designsystem + +import androidx.activity.ComponentActivity +import androidx.compose.material3.Text +import androidx.compose.runtime.CompositionLocalProvider +import androidx.compose.ui.platform.LocalInspectionMode +import androidx.compose.ui.test.junit4.createAndroidComposeRule +import androidx.compose.ui.test.onRoot +import com.github.takahirom.roborazzi.captureRoboImage +import com.google.accompanist.testharness.TestHarness +import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaTopicTag +import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme +import com.google.samples.apps.nowinandroid.core.testing.util.DefaultRoborazziOptions +import com.google.samples.apps.nowinandroid.core.testing.util.captureMultiTheme +import dagger.hilt.android.testing.HiltTestApplication +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.RobolectricTestRunner +import org.robolectric.annotation.Config +import org.robolectric.annotation.GraphicsMode +import org.robolectric.annotation.LooperMode + +@RunWith(RobolectricTestRunner::class) +@GraphicsMode(GraphicsMode.Mode.NATIVE) +@Config(application = HiltTestApplication::class, sdk = [33], qualifiers = "480dpi") +@LooperMode(LooperMode.Mode.PAUSED) +class TagScreenshotTests() { + + @get:Rule + val composeTestRule = createAndroidComposeRule() + + @Test + fun Tag_multipleThemes() { + composeTestRule.captureMultiTheme("Tag") { + NiaTopicTag(followed = true, onClick = {}) { + Text("TOPIC") + } + } + } + + @Test + fun tag_hugeFont() { + composeTestRule.setContent { + CompositionLocalProvider( + LocalInspectionMode provides true, + ) { + TestHarness(fontScale = 2f) { + NiaTheme { + NiaTopicTag(followed = true, onClick = {}) { + Text("LOOOOONG TOPIC") + } + } + } + } + } + composeTestRule.onRoot() + .captureRoboImage( + "src/test/screenshots/Tag/Tag_fontScale2.png", + roborazziOptions = DefaultRoborazziOptions, + ) + } +} diff --git a/core/designsystem/src/test/java/com/google/samples/apps/nowinandroid/core/designsystem/TopAppBarScreenshotTests.kt b/core/designsystem/src/test/java/com/google/samples/apps/nowinandroid/core/designsystem/TopAppBarScreenshotTests.kt new file mode 100644 index 000000000..29404da79 --- /dev/null +++ b/core/designsystem/src/test/java/com/google/samples/apps/nowinandroid/core/designsystem/TopAppBarScreenshotTests.kt @@ -0,0 +1,90 @@ +/* + * Copyright 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.samples.apps.nowinandroid.core.designsystem + +import android.R.string +import androidx.activity.ComponentActivity +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.runtime.Composable +import androidx.compose.runtime.CompositionLocalProvider +import androidx.compose.ui.platform.LocalInspectionMode +import androidx.compose.ui.test.junit4.createAndroidComposeRule +import androidx.compose.ui.test.onRoot +import com.github.takahirom.roborazzi.captureRoboImage +import com.google.accompanist.testharness.TestHarness +import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaTopAppBar +import com.google.samples.apps.nowinandroid.core.designsystem.icon.NiaIcons +import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme +import com.google.samples.apps.nowinandroid.core.testing.util.DefaultRoborazziOptions +import com.google.samples.apps.nowinandroid.core.testing.util.captureMultiTheme +import dagger.hilt.android.testing.HiltTestApplication +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.RobolectricTestRunner +import org.robolectric.annotation.Config +import org.robolectric.annotation.GraphicsMode +import org.robolectric.annotation.LooperMode + +@OptIn(ExperimentalMaterial3Api::class) +@RunWith(RobolectricTestRunner::class) +@GraphicsMode(GraphicsMode.Mode.NATIVE) +@Config(application = HiltTestApplication::class, sdk = [33], qualifiers = "480dpi") +@LooperMode(LooperMode.Mode.PAUSED) +class TopAppBarScreenshotTests() { + + @get:Rule + val composeTestRule = createAndroidComposeRule() + + @Test + fun topAppBar_multipleThemes() { + composeTestRule.captureMultiTheme("TopAppBar") { + NiaTopAppBarExample() + } + } + + @Test + fun topAppBar_hugeFont() { + composeTestRule.setContent { + CompositionLocalProvider( + LocalInspectionMode provides true, + ) { + TestHarness(fontScale = 2f) { + NiaTheme { + NiaTopAppBarExample() + } + } + } + } + composeTestRule.onRoot() + .captureRoboImage( + "src/test/screenshots/TopAppBar/TopAppBar_fontScale2.png", + roborazziOptions = DefaultRoborazziOptions, + ) + } + + @Composable + private fun NiaTopAppBarExample() { + NiaTopAppBar( + titleRes = android.R.string.untitled, + navigationIcon = NiaIcons.Search, + navigationIconContentDescription = "Navigation icon", + actionIcon = NiaIcons.MoreVert, + actionIconContentDescription = "Action icon", + ) + } +} diff --git a/core/designsystem/src/test/screenshots/Background/Background_dark_androidTheme_notDynamic.png b/core/designsystem/src/test/screenshots/Background/Background_dark_androidTheme_notDynamic.png new file mode 100644 index 000000000..34b6b9589 Binary files /dev/null and b/core/designsystem/src/test/screenshots/Background/Background_dark_androidTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Background/Background_dark_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/Background/Background_dark_defaultTheme_dynamic.png new file mode 100644 index 000000000..c4a4d7440 Binary files /dev/null and b/core/designsystem/src/test/screenshots/Background/Background_dark_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Background/Background_dark_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/Background/Background_dark_defaultTheme_notDynamic.png new file mode 100644 index 000000000..4eb46a8e6 Binary files /dev/null and b/core/designsystem/src/test/screenshots/Background/Background_dark_defaultTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Background/Background_light_androidTheme_notDynamic.png b/core/designsystem/src/test/screenshots/Background/Background_light_androidTheme_notDynamic.png new file mode 100644 index 000000000..d2914c451 Binary files /dev/null and b/core/designsystem/src/test/screenshots/Background/Background_light_androidTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Background/Background_light_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/Background/Background_light_defaultTheme_dynamic.png new file mode 100644 index 000000000..9b4d62d86 Binary files /dev/null and b/core/designsystem/src/test/screenshots/Background/Background_light_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Background/Background_light_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/Background/Background_light_defaultTheme_notDynamic.png new file mode 100644 index 000000000..22eaf5833 Binary files /dev/null and b/core/designsystem/src/test/screenshots/Background/Background_light_defaultTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Background/GradientBackground_dark_androidTheme_notDynamic.png b/core/designsystem/src/test/screenshots/Background/GradientBackground_dark_androidTheme_notDynamic.png new file mode 100644 index 000000000..34b6b9589 Binary files /dev/null and b/core/designsystem/src/test/screenshots/Background/GradientBackground_dark_androidTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Background/GradientBackground_dark_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/Background/GradientBackground_dark_defaultTheme_dynamic.png new file mode 100644 index 000000000..35449ae14 Binary files /dev/null and b/core/designsystem/src/test/screenshots/Background/GradientBackground_dark_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Background/GradientBackground_dark_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/Background/GradientBackground_dark_defaultTheme_notDynamic.png new file mode 100644 index 000000000..ce588b0ee Binary files /dev/null and b/core/designsystem/src/test/screenshots/Background/GradientBackground_dark_defaultTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Background/GradientBackground_light_androidTheme_notDynamic.png b/core/designsystem/src/test/screenshots/Background/GradientBackground_light_androidTheme_notDynamic.png new file mode 100644 index 000000000..d2914c451 Binary files /dev/null and b/core/designsystem/src/test/screenshots/Background/GradientBackground_light_androidTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Background/GradientBackground_light_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/Background/GradientBackground_light_defaultTheme_dynamic.png new file mode 100644 index 000000000..84a3dcaa7 Binary files /dev/null and b/core/designsystem/src/test/screenshots/Background/GradientBackground_light_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Background/GradientBackground_light_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/Background/GradientBackground_light_defaultTheme_notDynamic.png new file mode 100644 index 000000000..cc8ccd997 Binary files /dev/null and b/core/designsystem/src/test/screenshots/Background/GradientBackground_light_defaultTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Button/ButtonLeadingIcon_dark_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/Button/ButtonLeadingIcon_dark_defaultTheme_dynamic.png new file mode 100644 index 000000000..9ddd58d4b Binary files /dev/null and b/core/designsystem/src/test/screenshots/Button/ButtonLeadingIcon_dark_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Button/ButtonLeadingIcon_dark_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/Button/ButtonLeadingIcon_dark_defaultTheme_notDynamic.png new file mode 100644 index 000000000..9514112f1 Binary files /dev/null and b/core/designsystem/src/test/screenshots/Button/ButtonLeadingIcon_dark_defaultTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Button/ButtonLeadingIcon_light_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/Button/ButtonLeadingIcon_light_defaultTheme_dynamic.png new file mode 100644 index 000000000..c867bf469 Binary files /dev/null and b/core/designsystem/src/test/screenshots/Button/ButtonLeadingIcon_light_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Button/ButtonLeadingIcon_light_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/Button/ButtonLeadingIcon_light_defaultTheme_notDynamic.png new file mode 100644 index 000000000..8858fb493 Binary files /dev/null and b/core/designsystem/src/test/screenshots/Button/ButtonLeadingIcon_light_defaultTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Button/Button_dark_androidTheme_notDynamic.png b/core/designsystem/src/test/screenshots/Button/Button_dark_androidTheme_notDynamic.png new file mode 100644 index 000000000..a5d3d4a3d Binary files /dev/null and b/core/designsystem/src/test/screenshots/Button/Button_dark_androidTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Button/Button_dark_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/Button/Button_dark_defaultTheme_dynamic.png new file mode 100644 index 000000000..386760d24 Binary files /dev/null and b/core/designsystem/src/test/screenshots/Button/Button_dark_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Button/Button_dark_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/Button/Button_dark_defaultTheme_notDynamic.png new file mode 100644 index 000000000..cd0c07df1 Binary files /dev/null and b/core/designsystem/src/test/screenshots/Button/Button_dark_defaultTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Button/Button_light_androidTheme_notDynamic.png b/core/designsystem/src/test/screenshots/Button/Button_light_androidTheme_notDynamic.png new file mode 100644 index 000000000..ab113beec Binary files /dev/null and b/core/designsystem/src/test/screenshots/Button/Button_light_androidTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Button/Button_light_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/Button/Button_light_defaultTheme_dynamic.png new file mode 100644 index 000000000..d817e5c3f Binary files /dev/null and b/core/designsystem/src/test/screenshots/Button/Button_light_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Button/Button_light_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/Button/Button_light_defaultTheme_notDynamic.png new file mode 100644 index 000000000..b567adf84 Binary files /dev/null and b/core/designsystem/src/test/screenshots/Button/Button_light_defaultTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Button/OutlineButton_dark_androidTheme_notDynamic.png b/core/designsystem/src/test/screenshots/Button/OutlineButton_dark_androidTheme_notDynamic.png new file mode 100644 index 000000000..a9ba099c0 Binary files /dev/null and b/core/designsystem/src/test/screenshots/Button/OutlineButton_dark_androidTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Button/OutlineButton_dark_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/Button/OutlineButton_dark_defaultTheme_dynamic.png new file mode 100644 index 000000000..4a8fe7a98 Binary files /dev/null and b/core/designsystem/src/test/screenshots/Button/OutlineButton_dark_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Button/OutlineButton_dark_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/Button/OutlineButton_dark_defaultTheme_notDynamic.png new file mode 100644 index 000000000..ce30b66ba Binary files /dev/null and b/core/designsystem/src/test/screenshots/Button/OutlineButton_dark_defaultTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Button/OutlineButton_light_androidTheme_notDynamic.png b/core/designsystem/src/test/screenshots/Button/OutlineButton_light_androidTheme_notDynamic.png new file mode 100644 index 000000000..bb6aa592f Binary files /dev/null and b/core/designsystem/src/test/screenshots/Button/OutlineButton_light_androidTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Button/OutlineButton_light_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/Button/OutlineButton_light_defaultTheme_dynamic.png new file mode 100644 index 000000000..4dce1bcab Binary files /dev/null and b/core/designsystem/src/test/screenshots/Button/OutlineButton_light_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Button/OutlineButton_light_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/Button/OutlineButton_light_defaultTheme_notDynamic.png new file mode 100644 index 000000000..d2059e4d7 Binary files /dev/null and b/core/designsystem/src/test/screenshots/Button/OutlineButton_light_defaultTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/FilterChip/FilterChipSelected_dark_androidTheme_notDynamic.png b/core/designsystem/src/test/screenshots/FilterChip/FilterChipSelected_dark_androidTheme_notDynamic.png new file mode 100644 index 000000000..5881f76b7 Binary files /dev/null and b/core/designsystem/src/test/screenshots/FilterChip/FilterChipSelected_dark_androidTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/FilterChip/FilterChipSelected_dark_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/FilterChip/FilterChipSelected_dark_defaultTheme_dynamic.png new file mode 100644 index 000000000..d73f023c8 Binary files /dev/null and b/core/designsystem/src/test/screenshots/FilterChip/FilterChipSelected_dark_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/FilterChip/FilterChipSelected_dark_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/FilterChip/FilterChipSelected_dark_defaultTheme_notDynamic.png new file mode 100644 index 000000000..f2e863865 Binary files /dev/null and b/core/designsystem/src/test/screenshots/FilterChip/FilterChipSelected_dark_defaultTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/FilterChip/FilterChipSelected_light_androidTheme_notDynamic.png b/core/designsystem/src/test/screenshots/FilterChip/FilterChipSelected_light_androidTheme_notDynamic.png new file mode 100644 index 000000000..1e3b04e50 Binary files /dev/null and b/core/designsystem/src/test/screenshots/FilterChip/FilterChipSelected_light_androidTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/FilterChip/FilterChipSelected_light_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/FilterChip/FilterChipSelected_light_defaultTheme_dynamic.png new file mode 100644 index 000000000..e363c8dad Binary files /dev/null and b/core/designsystem/src/test/screenshots/FilterChip/FilterChipSelected_light_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/FilterChip/FilterChipSelected_light_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/FilterChip/FilterChipSelected_light_defaultTheme_notDynamic.png new file mode 100644 index 000000000..be73f060d Binary files /dev/null and b/core/designsystem/src/test/screenshots/FilterChip/FilterChipSelected_light_defaultTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/FilterChip/FilterChip_dark_androidTheme_notDynamic.png b/core/designsystem/src/test/screenshots/FilterChip/FilterChip_dark_androidTheme_notDynamic.png new file mode 100644 index 000000000..364f59a47 Binary files /dev/null and b/core/designsystem/src/test/screenshots/FilterChip/FilterChip_dark_androidTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/FilterChip/FilterChip_dark_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/FilterChip/FilterChip_dark_defaultTheme_dynamic.png new file mode 100644 index 000000000..7c0371ddc Binary files /dev/null and b/core/designsystem/src/test/screenshots/FilterChip/FilterChip_dark_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/FilterChip/FilterChip_dark_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/FilterChip/FilterChip_dark_defaultTheme_notDynamic.png new file mode 100644 index 000000000..5303eb64e Binary files /dev/null and b/core/designsystem/src/test/screenshots/FilterChip/FilterChip_dark_defaultTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/FilterChip/FilterChip_fontScale2.png b/core/designsystem/src/test/screenshots/FilterChip/FilterChip_fontScale2.png new file mode 100644 index 000000000..56ddf9792 Binary files /dev/null and b/core/designsystem/src/test/screenshots/FilterChip/FilterChip_fontScale2.png differ diff --git a/core/designsystem/src/test/screenshots/FilterChip/FilterChip_light_androidTheme_notDynamic.png b/core/designsystem/src/test/screenshots/FilterChip/FilterChip_light_androidTheme_notDynamic.png new file mode 100644 index 000000000..fadd074d8 Binary files /dev/null and b/core/designsystem/src/test/screenshots/FilterChip/FilterChip_light_androidTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/FilterChip/FilterChip_light_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/FilterChip/FilterChip_light_defaultTheme_dynamic.png new file mode 100644 index 000000000..c73df7f89 Binary files /dev/null and b/core/designsystem/src/test/screenshots/FilterChip/FilterChip_light_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/FilterChip/FilterChip_light_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/FilterChip/FilterChip_light_defaultTheme_notDynamic.png new file mode 100644 index 000000000..0cfaaefae Binary files /dev/null and b/core/designsystem/src/test/screenshots/FilterChip/FilterChip_light_defaultTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/IconButton/IconButtonUnchecked_dark_androidTheme_notDynamic.png b/core/designsystem/src/test/screenshots/IconButton/IconButtonUnchecked_dark_androidTheme_notDynamic.png new file mode 100644 index 000000000..a1512fa75 Binary files /dev/null and b/core/designsystem/src/test/screenshots/IconButton/IconButtonUnchecked_dark_androidTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/IconButton/IconButtonUnchecked_dark_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/IconButton/IconButtonUnchecked_dark_defaultTheme_dynamic.png new file mode 100644 index 000000000..5e732c373 Binary files /dev/null and b/core/designsystem/src/test/screenshots/IconButton/IconButtonUnchecked_dark_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/IconButton/IconButtonUnchecked_dark_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/IconButton/IconButtonUnchecked_dark_defaultTheme_notDynamic.png new file mode 100644 index 000000000..f912ce3c1 Binary files /dev/null and b/core/designsystem/src/test/screenshots/IconButton/IconButtonUnchecked_dark_defaultTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/IconButton/IconButtonUnchecked_light_androidTheme_notDynamic.png b/core/designsystem/src/test/screenshots/IconButton/IconButtonUnchecked_light_androidTheme_notDynamic.png new file mode 100644 index 000000000..339479779 Binary files /dev/null and b/core/designsystem/src/test/screenshots/IconButton/IconButtonUnchecked_light_androidTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/IconButton/IconButtonUnchecked_light_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/IconButton/IconButtonUnchecked_light_defaultTheme_dynamic.png new file mode 100644 index 000000000..b7eb3db4a Binary files /dev/null and b/core/designsystem/src/test/screenshots/IconButton/IconButtonUnchecked_light_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/IconButton/IconButtonUnchecked_light_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/IconButton/IconButtonUnchecked_light_defaultTheme_notDynamic.png new file mode 100644 index 000000000..24580adf2 Binary files /dev/null and b/core/designsystem/src/test/screenshots/IconButton/IconButtonUnchecked_light_defaultTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/IconButton/IconButton_dark_androidTheme_notDynamic.png b/core/designsystem/src/test/screenshots/IconButton/IconButton_dark_androidTheme_notDynamic.png new file mode 100644 index 000000000..ce2cdf804 Binary files /dev/null and b/core/designsystem/src/test/screenshots/IconButton/IconButton_dark_androidTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/IconButton/IconButton_dark_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/IconButton/IconButton_dark_defaultTheme_dynamic.png new file mode 100644 index 000000000..ce2cdf804 Binary files /dev/null and b/core/designsystem/src/test/screenshots/IconButton/IconButton_dark_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/IconButton/IconButton_dark_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/IconButton/IconButton_dark_defaultTheme_notDynamic.png new file mode 100644 index 000000000..ce2cdf804 Binary files /dev/null and b/core/designsystem/src/test/screenshots/IconButton/IconButton_dark_defaultTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/IconButton/IconButton_light_androidTheme_notDynamic.png b/core/designsystem/src/test/screenshots/IconButton/IconButton_light_androidTheme_notDynamic.png new file mode 100644 index 000000000..ce2cdf804 Binary files /dev/null and b/core/designsystem/src/test/screenshots/IconButton/IconButton_light_androidTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/IconButton/IconButton_light_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/IconButton/IconButton_light_defaultTheme_dynamic.png new file mode 100644 index 000000000..ce2cdf804 Binary files /dev/null and b/core/designsystem/src/test/screenshots/IconButton/IconButton_light_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/IconButton/IconButton_light_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/IconButton/IconButton_light_defaultTheme_notDynamic.png new file mode 100644 index 000000000..ce2cdf804 Binary files /dev/null and b/core/designsystem/src/test/screenshots/IconButton/IconButton_light_defaultTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_animation_1000.png b/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_animation_1000.png new file mode 100644 index 000000000..450d55a09 Binary files /dev/null and b/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_animation_1000.png differ diff --git a/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_animation_115.png b/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_animation_115.png new file mode 100644 index 000000000..6d023a207 Binary files /dev/null and b/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_animation_115.png differ diff --git a/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_animation_20.png b/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_animation_20.png new file mode 100644 index 000000000..c125faccf Binary files /dev/null and b/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_animation_20.png differ diff --git a/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_animation_724.png b/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_animation_724.png new file mode 100644 index 000000000..03bf6709e Binary files /dev/null and b/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_animation_724.png differ diff --git a/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_dark_androidTheme_notDynamic.png b/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_dark_androidTheme_notDynamic.png new file mode 100644 index 000000000..cf35893fd Binary files /dev/null and b/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_dark_androidTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_dark_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_dark_defaultTheme_dynamic.png new file mode 100644 index 000000000..7109265c7 Binary files /dev/null and b/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_dark_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_dark_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_dark_defaultTheme_notDynamic.png new file mode 100644 index 000000000..19265495c Binary files /dev/null and b/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_dark_defaultTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_light_androidTheme_notDynamic.png b/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_light_androidTheme_notDynamic.png new file mode 100644 index 000000000..156fc1983 Binary files /dev/null and b/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_light_androidTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_light_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_light_defaultTheme_dynamic.png new file mode 100644 index 000000000..e42f9855c Binary files /dev/null and b/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_light_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_light_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_light_defaultTheme_notDynamic.png new file mode 100644 index 000000000..89ea5e37c Binary files /dev/null and b/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_light_defaultTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/LoadingWheel/OverlayLoadingWheel_dark_androidTheme_notDynamic.png b/core/designsystem/src/test/screenshots/LoadingWheel/OverlayLoadingWheel_dark_androidTheme_notDynamic.png new file mode 100644 index 000000000..ac0065cc7 Binary files /dev/null and b/core/designsystem/src/test/screenshots/LoadingWheel/OverlayLoadingWheel_dark_androidTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/LoadingWheel/OverlayLoadingWheel_dark_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/LoadingWheel/OverlayLoadingWheel_dark_defaultTheme_dynamic.png new file mode 100644 index 000000000..41dbc1aea Binary files /dev/null and b/core/designsystem/src/test/screenshots/LoadingWheel/OverlayLoadingWheel_dark_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/LoadingWheel/OverlayLoadingWheel_dark_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/LoadingWheel/OverlayLoadingWheel_dark_defaultTheme_notDynamic.png new file mode 100644 index 000000000..2f1d9767c Binary files /dev/null and b/core/designsystem/src/test/screenshots/LoadingWheel/OverlayLoadingWheel_dark_defaultTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/LoadingWheel/OverlayLoadingWheel_light_androidTheme_notDynamic.png b/core/designsystem/src/test/screenshots/LoadingWheel/OverlayLoadingWheel_light_androidTheme_notDynamic.png new file mode 100644 index 000000000..d90547cd8 Binary files /dev/null and b/core/designsystem/src/test/screenshots/LoadingWheel/OverlayLoadingWheel_light_androidTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/LoadingWheel/OverlayLoadingWheel_light_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/LoadingWheel/OverlayLoadingWheel_light_defaultTheme_dynamic.png new file mode 100644 index 000000000..1541e6133 Binary files /dev/null and b/core/designsystem/src/test/screenshots/LoadingWheel/OverlayLoadingWheel_light_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/LoadingWheel/OverlayLoadingWheel_light_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/LoadingWheel/OverlayLoadingWheel_light_defaultTheme_notDynamic.png new file mode 100644 index 000000000..6949a8908 Binary files /dev/null and b/core/designsystem/src/test/screenshots/LoadingWheel/OverlayLoadingWheel_light_defaultTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Navigation/Navigation_dark_androidTheme_notDynamic.png b/core/designsystem/src/test/screenshots/Navigation/Navigation_dark_androidTheme_notDynamic.png new file mode 100644 index 000000000..a698536d8 Binary files /dev/null and b/core/designsystem/src/test/screenshots/Navigation/Navigation_dark_androidTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Navigation/Navigation_dark_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/Navigation/Navigation_dark_defaultTheme_dynamic.png new file mode 100644 index 000000000..01183397f Binary files /dev/null and b/core/designsystem/src/test/screenshots/Navigation/Navigation_dark_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Navigation/Navigation_dark_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/Navigation/Navigation_dark_defaultTheme_notDynamic.png new file mode 100644 index 000000000..92317be34 Binary files /dev/null and b/core/designsystem/src/test/screenshots/Navigation/Navigation_dark_defaultTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Navigation/Navigation_fontScale2.png b/core/designsystem/src/test/screenshots/Navigation/Navigation_fontScale2.png new file mode 100644 index 000000000..a432cc93c Binary files /dev/null and b/core/designsystem/src/test/screenshots/Navigation/Navigation_fontScale2.png differ diff --git a/core/designsystem/src/test/screenshots/Navigation/Navigation_light_androidTheme_notDynamic.png b/core/designsystem/src/test/screenshots/Navigation/Navigation_light_androidTheme_notDynamic.png new file mode 100644 index 000000000..238b60c25 Binary files /dev/null and b/core/designsystem/src/test/screenshots/Navigation/Navigation_light_androidTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Navigation/Navigation_light_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/Navigation/Navigation_light_defaultTheme_dynamic.png new file mode 100644 index 000000000..ff60eb547 Binary files /dev/null and b/core/designsystem/src/test/screenshots/Navigation/Navigation_light_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Navigation/Navigation_light_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/Navigation/Navigation_light_defaultTheme_notDynamic.png new file mode 100644 index 000000000..badd8e1c7 Binary files /dev/null and b/core/designsystem/src/test/screenshots/Navigation/Navigation_light_defaultTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Tabs/Tabs_dark_androidTheme_notDynamic.png b/core/designsystem/src/test/screenshots/Tabs/Tabs_dark_androidTheme_notDynamic.png new file mode 100644 index 000000000..bdf5d18f3 Binary files /dev/null and b/core/designsystem/src/test/screenshots/Tabs/Tabs_dark_androidTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Tabs/Tabs_dark_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/Tabs/Tabs_dark_defaultTheme_dynamic.png new file mode 100644 index 000000000..dbfb08f1f Binary files /dev/null and b/core/designsystem/src/test/screenshots/Tabs/Tabs_dark_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Tabs/Tabs_dark_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/Tabs/Tabs_dark_defaultTheme_notDynamic.png new file mode 100644 index 000000000..074f3dc8c Binary files /dev/null and b/core/designsystem/src/test/screenshots/Tabs/Tabs_dark_defaultTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Tabs/Tabs_fontScale2.png b/core/designsystem/src/test/screenshots/Tabs/Tabs_fontScale2.png new file mode 100644 index 000000000..9a60923d9 Binary files /dev/null and b/core/designsystem/src/test/screenshots/Tabs/Tabs_fontScale2.png differ diff --git a/core/designsystem/src/test/screenshots/Tabs/Tabs_light_androidTheme_notDynamic.png b/core/designsystem/src/test/screenshots/Tabs/Tabs_light_androidTheme_notDynamic.png new file mode 100644 index 000000000..5c38870dc Binary files /dev/null and b/core/designsystem/src/test/screenshots/Tabs/Tabs_light_androidTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Tabs/Tabs_light_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/Tabs/Tabs_light_defaultTheme_dynamic.png new file mode 100644 index 000000000..a11d82680 Binary files /dev/null and b/core/designsystem/src/test/screenshots/Tabs/Tabs_light_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Tabs/Tabs_light_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/Tabs/Tabs_light_defaultTheme_notDynamic.png new file mode 100644 index 000000000..759641c93 Binary files /dev/null and b/core/designsystem/src/test/screenshots/Tabs/Tabs_light_defaultTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Tag/Tag_dark_androidTheme_notDynamic.png b/core/designsystem/src/test/screenshots/Tag/Tag_dark_androidTheme_notDynamic.png new file mode 100644 index 000000000..522dcd301 Binary files /dev/null and b/core/designsystem/src/test/screenshots/Tag/Tag_dark_androidTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Tag/Tag_dark_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/Tag/Tag_dark_defaultTheme_dynamic.png new file mode 100644 index 000000000..2d819edf7 Binary files /dev/null and b/core/designsystem/src/test/screenshots/Tag/Tag_dark_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Tag/Tag_dark_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/Tag/Tag_dark_defaultTheme_notDynamic.png new file mode 100644 index 000000000..d6cfb48d0 Binary files /dev/null and b/core/designsystem/src/test/screenshots/Tag/Tag_dark_defaultTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Tag/Tag_fontScale2.png b/core/designsystem/src/test/screenshots/Tag/Tag_fontScale2.png new file mode 100644 index 000000000..fc66ddf58 Binary files /dev/null and b/core/designsystem/src/test/screenshots/Tag/Tag_fontScale2.png differ diff --git a/core/designsystem/src/test/screenshots/Tag/Tag_light_androidTheme_notDynamic.png b/core/designsystem/src/test/screenshots/Tag/Tag_light_androidTheme_notDynamic.png new file mode 100644 index 000000000..38ebe8b42 Binary files /dev/null and b/core/designsystem/src/test/screenshots/Tag/Tag_light_androidTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Tag/Tag_light_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/Tag/Tag_light_defaultTheme_dynamic.png new file mode 100644 index 000000000..5683b4c6b Binary files /dev/null and b/core/designsystem/src/test/screenshots/Tag/Tag_light_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Tag/Tag_light_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/Tag/Tag_light_defaultTheme_notDynamic.png new file mode 100644 index 000000000..53b1da266 Binary files /dev/null and b/core/designsystem/src/test/screenshots/Tag/Tag_light_defaultTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/TopAppBar/TopAppBar_dark_androidTheme_notDynamic.png b/core/designsystem/src/test/screenshots/TopAppBar/TopAppBar_dark_androidTheme_notDynamic.png new file mode 100644 index 000000000..753c13605 Binary files /dev/null and b/core/designsystem/src/test/screenshots/TopAppBar/TopAppBar_dark_androidTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/TopAppBar/TopAppBar_dark_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/TopAppBar/TopAppBar_dark_defaultTheme_dynamic.png new file mode 100644 index 000000000..0e53746d9 Binary files /dev/null and b/core/designsystem/src/test/screenshots/TopAppBar/TopAppBar_dark_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/TopAppBar/TopAppBar_dark_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/TopAppBar/TopAppBar_dark_defaultTheme_notDynamic.png new file mode 100644 index 000000000..1baa2362c Binary files /dev/null and b/core/designsystem/src/test/screenshots/TopAppBar/TopAppBar_dark_defaultTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/TopAppBar/TopAppBar_fontScale2.png b/core/designsystem/src/test/screenshots/TopAppBar/TopAppBar_fontScale2.png new file mode 100644 index 000000000..ed2f04eb1 Binary files /dev/null and b/core/designsystem/src/test/screenshots/TopAppBar/TopAppBar_fontScale2.png differ diff --git a/core/designsystem/src/test/screenshots/TopAppBar/TopAppBar_light_androidTheme_notDynamic.png b/core/designsystem/src/test/screenshots/TopAppBar/TopAppBar_light_androidTheme_notDynamic.png new file mode 100644 index 000000000..7c0348b04 Binary files /dev/null and b/core/designsystem/src/test/screenshots/TopAppBar/TopAppBar_light_androidTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/TopAppBar/TopAppBar_light_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/TopAppBar/TopAppBar_light_defaultTheme_dynamic.png new file mode 100644 index 000000000..00e313d2b Binary files /dev/null and b/core/designsystem/src/test/screenshots/TopAppBar/TopAppBar_light_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/TopAppBar/TopAppBar_light_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/TopAppBar/TopAppBar_light_defaultTheme_notDynamic.png new file mode 100644 index 000000000..078378bea Binary files /dev/null and b/core/designsystem/src/test/screenshots/TopAppBar/TopAppBar_light_defaultTheme_notDynamic.png differ diff --git a/core/testing/build.gradle.kts b/core/testing/build.gradle.kts index 6cba0086d..51f21355e 100644 --- a/core/testing/build.gradle.kts +++ b/core/testing/build.gradle.kts @@ -42,6 +42,7 @@ dependencies { implementation(project(":core:common")) implementation(project(":core:data")) + implementation(project(":core:designsystem")) implementation(project(":core:domain")) implementation(project(":core:model")) implementation(project(":core:notifications")) diff --git a/core/testing/src/main/java/com/google/samples/apps/nowinandroid/core/testing/util/ScreenshotHelper.kt b/core/testing/src/main/java/com/google/samples/apps/nowinandroid/core/testing/util/ScreenshotHelper.kt index 85a95b796..e84fe7d33 100644 --- a/core/testing/src/main/java/com/google/samples/apps/nowinandroid/core/testing/util/ScreenshotHelper.kt +++ b/core/testing/src/main/java/com/google/samples/apps/nowinandroid/core/testing/util/ScreenshotHelper.kt @@ -20,6 +20,10 @@ import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider +import androidx.compose.runtime.getValue +import androidx.compose.runtime.key +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.setValue import androidx.compose.ui.platform.LocalInspectionMode import androidx.compose.ui.test.junit4.AndroidComposeTestRule import androidx.compose.ui.test.onRoot @@ -29,6 +33,7 @@ import com.github.takahirom.roborazzi.RoborazziOptions.CompareOptions import com.github.takahirom.roborazzi.RoborazziOptions.RecordOptions import com.github.takahirom.roborazzi.captureRoboImage import com.google.accompanist.testharness.TestHarness +import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme import org.robolectric.RuntimeEnvironment val DefaultRoborazziOptions = @@ -80,6 +85,113 @@ fun AndroidComposeTestRule, A>.c ) } +/** + * Takes six screenshots combining light/dark and default/Android themes and whether dynamic color + * is enabled. + */ +fun AndroidComposeTestRule, A>.captureMultiTheme( + name: String, + overrideFileName: String? = null, + shouldCompareDarkMode: Boolean = true, + shouldCompareDynamicColor: Boolean = true, + shouldCompareAndroidTheme: Boolean = true, + content: @Composable (desc: String) -> Unit, +) { + val darkModeValues = if (shouldCompareDarkMode) listOf(true, false) else listOf(false) + val dynamicThemingValues = if (shouldCompareDynamicColor) listOf(true, false) else listOf(false) + val androidThemeValues = if (shouldCompareAndroidTheme) listOf(true, false) else listOf(false) + + var darkMode by mutableStateOf(true) + var dynamicTheming by mutableStateOf(false) + var androidTheme by mutableStateOf(false) + + this.setContent { + CompositionLocalProvider( + LocalInspectionMode provides true, + ) { + NiaTheme( + androidTheme = androidTheme, + darkTheme = darkMode, + disableDynamicTheming = !dynamicTheming, + ) { + // Keying is necessary in some cases (e.g. animations) + key(androidTheme, darkMode, dynamicTheming) { + val description = generateDescription( + shouldCompareDarkMode, + darkMode, + shouldCompareAndroidTheme, + androidTheme, + shouldCompareDynamicColor, + dynamicTheming, + ) + content(description) + } + } + } + } + + // Create permutations + darkModeValues.forEach { isDarkMode -> + darkMode = isDarkMode + val darkModeDesc = if (isDarkMode) "dark" else "light" + + androidThemeValues.forEach { isAndroidTheme -> + androidTheme = isAndroidTheme + val androidThemeDesc = if (isAndroidTheme) "androidTheme" else "defaultTheme" + + dynamicThemingValues.forEach dynamicTheme@{ isDynamicTheming -> + // Skip tests with both Android Theme and Dynamic color as they're incompatible. + if (isAndroidTheme && isDynamicTheming) return@dynamicTheme + + dynamicTheming = isDynamicTheming + val dynamicThemingDesc = if (isDynamicTheming) "dynamic" else "notDynamic" + + val filename = overrideFileName ?: name + + this.onRoot() + .captureRoboImage( + "src/test/screenshots/" + + "$name/$filename" + + "_$darkModeDesc" + + "_$androidThemeDesc" + + "_$dynamicThemingDesc" + + ".png", + roborazziOptions = DefaultRoborazziOptions, + ) + } + } + } +} + +@Composable +private fun generateDescription( + shouldCompareDarkMode: Boolean, + darkMode: Boolean, + shouldCompareAndroidTheme: Boolean, + androidTheme: Boolean, + shouldCompareDynamicColor: Boolean, + dynamicTheming: Boolean, +): String { + val description = "" + + if (shouldCompareDarkMode) { + if (darkMode) "Dark" else "Light" + } else { + "" + } + + if (shouldCompareAndroidTheme) { + if (androidTheme) " Android" else " Default" + } else { + "" + } + + if (shouldCompareDynamicColor) { + if (dynamicTheming) " Dynamic" else "" + } else { + "" + } + + return description.trim() +} + /** * Extracts some properties from the spec string. Note that this function is not exhaustive. */