New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Show snackbar in large screen #1296
base: main
Are you sure you want to change the base?
Show snackbar in large screen #1296
Conversation
Change-Id: I3af6fbfff20392749a7ff3eb72426b18fbf2f37e
Change-Id: I15a3c68a0a590e067a65c5e28ec753c06a4dfa46
Change-Id: I6e77ff7c0c3e6a40eb6aa28650c2f8c9f97cda4a
Change-Id: Ifc1e70441c6bb10af101abc658fa067d04b57007
Change-Id: I54be63d7641873c8209836948a3a8aebd6f23156
- compactWidth_WhenNotConnectedAndForYou_ConnectSnackBarShowUp - compactWidth_WhenNotConnectedAndSaved_ConnectSnackBarShowUp - compactWidth_WhenNotConnectedAndInterests_ConnectSnackBarShowUp - mediumWidth_WhenNotConnectedAndForYou_ConnectSnackBarShowUp - mediumWidth_WhenNotConnectedAndSaved_ConnectSnackBarShowUp - mediumWidth_WhenNotConnectedAndInterests_ConnectSnackBarShowUp - expandedWidth_WhenNotConnectedAndForYou_ConnectSnackBarShowUp - expandedWidth_WhenNotConnectedAndSaved_ConnectSnackBarShowUp - expandedWidth_WhenNotConnectedAndInterests_ConnectSnackBarShowUp Change-Id: I59404391ef0d62e278677014b5c972b59392660c
Change-Id: I52eb78e836eba9c9acdb2beec9baa4cc3fe969ef
Any chance to cover this with an UI behavior or screenshot regression test? |
@JoseAlcerreca
Does it exception cause because of I am using Windows 11? |
How are you running the test? |
Oh It had discussed in issues. I forgotten. • Run test directly, you can see above mentioned exception. By this reason, It is hard to make screenshot test on my own. |
I finally found the formular to check position, but it only work when the simulator was Foldable(Resizable), not Phone and Tablet. Test Code/*
* Copyright 2024 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.ui
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.BoxWithConstraints
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.safeDrawing
import androidx.compose.material3.windowsizeclass.ExperimentalMaterial3WindowSizeClassApi
import androidx.compose.material3.windowsizeclass.WindowSizeClass
import androidx.compose.runtime.Composable
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.test.SemanticsNodeInteraction
import androidx.compose.ui.test.assertIsDisplayed
import androidx.compose.ui.test.assertIsSelected
import androidx.compose.ui.test.assertTopPositionInRootIsEqualTo
import androidx.compose.ui.test.hasAnyDescendant
import androidx.compose.ui.test.hasTestTag
import androidx.compose.ui.test.hasText
import androidx.compose.ui.test.isSelectable
import androidx.compose.ui.test.junit4.createAndroidComposeRule
import androidx.compose.ui.test.performClick
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.DpSize
import androidx.compose.ui.unit.dp
import com.google.accompanist.testharness.TestHarness
import com.google.samples.apps.nowinandroid.MainActivity
import com.google.samples.apps.nowinandroid.R
import com.google.samples.apps.nowinandroid.core.data.repository.CompositeUserNewsResourceRepository
import com.google.samples.apps.nowinandroid.core.data.test.networkmonitor.AlwaysOfflineNetworkMonitor
import com.google.samples.apps.nowinandroid.core.data.util.NetworkMonitor
import com.google.samples.apps.nowinandroid.core.data.util.TimeZoneMonitor
import com.google.samples.apps.nowinandroid.core.rules.GrantPostNotificationsPermissionRule
import com.google.samples.apps.nowinandroid.extensions.stringResource
import dagger.hilt.android.testing.BindValue
import dagger.hilt.android.testing.HiltAndroidRule
import dagger.hilt.android.testing.HiltAndroidTest
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.rules.TemporaryFolder
import javax.inject.Inject
@HiltAndroidTest
class ConnectSnackBarTest {
/**
* Manages the components' state and is used to perform injection on your test
*/
@get:Rule(order = 0)
val hiltRule = HiltAndroidRule(this)
/**
* Create a temporary folder used to create a Data Store file. This guarantees that
* the file is removed in between each test, preventing a crash.
*/
@BindValue
@get:Rule(order = 1)
val tmpFolder: TemporaryFolder = TemporaryFolder.builder().assureDeletion().build()
/**
* Grant [android.Manifest.permission.POST_NOTIFICATIONS] permission.
*/
@get:Rule(order = 2)
val postNotificationsPermission = GrantPostNotificationsPermissionRule()
/**
* Use the primary activity to initialize the app normally.
*/
@get:Rule(order = 3)
val composeTestRule = createAndroidComposeRule<MainActivity>()
@Inject
lateinit var userNewsResourceRepository: CompositeUserNewsResourceRepository
@Inject
lateinit var timeZoneMonitor: TimeZoneMonitor
private val networkMonitor: NetworkMonitor = AlwaysOfflineNetworkMonitor()
private val forYou by composeTestRule.stringResource(com.google.samples.apps.nowinandroid.feature.foryou.R.string.feature_foryou_title)
private val interests by composeTestRule.stringResource(com.google.samples.apps.nowinandroid.feature.interests.R.string.feature_interests_title)
private val saved by composeTestRule.stringResource(com.google.samples.apps.nowinandroid.feature.bookmarks.R.string.feature_bookmarks_title)
private val netConnected by composeTestRule.stringResource(R.string.not_connected)
private var height = 0.dp
private var bottomSafeDrawingHeight = 0.dp
@Before
fun setup() = hiltRule.inject()
@Test
fun mediumWidth_WhenNotConnectedAndForYou_ConnectSnackBarShowUp() {
composeTestRule.activity.apply {
setContent {
TestHarness(size = DpSize(610.dp, 1000.dp)) {
BoxWithConstraints {
val density = LocalDensity.current
height = maxHeight
bottomSafeDrawingHeight =
WindowInsets.safeDrawing.getBottom(density = density).dp
NiaApp(
appState = fakeAppState(maxWidth, maxHeight),
)
}
}
}
}
composeTestRule.apply {
findNavigationButton(forYou).apply {
performClick()
assertIsSelected()
}
findSnackbarWithMessage(message = netConnected)
.assertIsDisplayed()
.assertTopPositionInRootIsEqualTo(height - bottomSafeDrawingHeight)
}
}
private fun findSnackbarWithMessage(message: String): SemanticsNodeInteraction =
composeTestRule.onNode(
matcher = hasTestTag("Snackbar") and
hasAnyDescendant(matcher = hasText(message)),
)
private fun findNavigationButton(string: String): SemanticsNodeInteraction =
composeTestRule.onNode(matcher = isSelectable() and hasText(string))
@OptIn(ExperimentalMaterial3WindowSizeClassApi::class)
@Composable
private fun fakeAppState(maxWidth: Dp, maxHeight: Dp) = rememberNiaAppState(
windowSizeClass = WindowSizeClass.calculateFromSize(DpSize(maxWidth, maxHeight)),
networkMonitor = networkMonitor,
userNewsResourceRepository = userNewsResourceRepository,
timeZoneMonitor = timeZoneMonitor,
)
} |
Change-Id: Iaaf41bfc4d6a0a604d7a731ba80b9dee06ecd3b2
Change-Id: Ieea183d9e66d598e663db26a75322da770ad8a54
Change-Id: Ic292512fb024e58a64db455fdfd2ace56a1e8ef5
Change-Id: Ic8655c5102ed94edc3772e6f0bc170115fa3f19b
Change-Id: I836bdbbe40c714048c62e7c2246ab5a251b6bf21
Change-Id: I252dd48426bc34bf0597a515ee6557d36f07fda2
- compactWidth_WhenNotConnectedAndForYou_ConnectSnackBarShowUp - compactWidth_WhenNotConnectedAndSaved_ConnectSnackBarShowUp - compactWidth_WhenNotConnectedAndInterests_ConnectSnackBarShowUp - mediumWidth_WhenNotConnectedAndForYou_ConnectSnackBarShowUp - mediumWidth_WhenNotConnectedAndSaved_ConnectSnackBarShowUp - mediumWidth_WhenNotConnectedAndInterests_ConnectSnackBarShowUp - expandedWidth_WhenNotConnectedAndForYou_ConnectSnackBarShowUp - expandedWidth_WhenNotConnectedAndSaved_ConnectSnackBarShowUp - expandedWidth_WhenNotConnectedAndInterests_ConnectSnackBarShowUp Change-Id: I736fcb3624da6b05e5a43f4407062aed22c3143a
…st' into show-snackbar-in-large-screen-test Change-Id: I36a8863c4918f171af4068302a0d18815872c995
Edit: |
Change-Id: I75e8d49b0448fd96eaceadb70cfee5c5c3741fc7
Change-Id: I11586ce6e134539a573e9d518f4fcd2d88f21996
Change-Id: I3b445d1b48c5c4e4a30f76c955d759ad5603c8b2
Change-Id: Id22296bf04f9611702cef42a74aa4f1ddd48225d
This reverts commit ae6c427.
Change-Id: I2c7cb9c0ef3d5e239007dd9526b0c5b021ddb043
Change-Id: I13d2bc4471d7b904dd9c779af004b639754b67c0
…d-remote-main Change-Id: I49b7e75fec1dc12f8f0f6ac3f59f93f9a96c644a
Change-Id: I01a1d3b759847db89c7b129358407cd3530eb7ad
Change-Id: I60c2a46bd98afd4663fd85ac1aa7b022ab84a75d
Change-Id: I55a6fcfc53f1c96f376cab77079e248bdc2df44f
18c1eee
to
57eeb76
Compare
Does Anyone have ideas giving the fake insets to val bottomNavigationHeight = density.run {
WindowInsets.safeDrawing
.getBottom(density = density)
.toDp()
} Kindly leave your ideas in #1347 If you think my instrumented test |
Change-Id: Ib94dbb319e74f83d6c76fa30ad9c065ea54aa156
Change-Id: Idb2e617263963a6dd10240ed477cf971a5fffd3c
Change-Id: I3ce9a857cc266b74eac35b319d757d1c57bbf11f
Change-Id: Iae760e99678e291e6757f97d38c71eca22429ebc
Change-Id: Ifdc722c5e093a584322c30b51764e7319b166ef8
I'd added screenshots. Done. |
Change-Id: Ic85b4c18b86664c8ca1c964818d703b04467147a # Conflicts: # app/src/testDemo/kotlin/com/google/samples/apps/nowinandroid/ui/SnackbarScreenshotTests.kt # app/src/testDemo/screenshots/snackbar_expanded_expanded.png # app/src/testDemo/screenshots/snackbar_medium_medium.png
Change-Id: I629ff6093a13378bf0df8014e9a3cfa9d71b9123
This reverts commit afe53f9.
Add CI screenshots.
What I have done and why
Add
SafeDrawing bottom padding
to show snackbar overbottom navigation bar
Fixes #1295
Foldable
Tablet
Open to contribute anyone on test code if you want.