Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions Jetchat/app/proguard-rules.pro
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,8 @@


-keep class androidx.compose.ui.platform.AndroidCompositionLocals_androidKt { *; }

# Keep RoomDatabase implementations and their parameterless constructor for R8 Full Mode
-keep class * extends androidx.room.RoomDatabase {
<init>();
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,10 @@ import com.example.compose.jetchat.conversation.ConversationContent
import com.example.compose.jetchat.conversation.ConversationTestTag
import com.example.compose.jetchat.conversation.ConversationUiState
import com.example.compose.jetchat.data.exampleUiState
import com.example.compose.jetchat.data.resetFakeData
import com.example.compose.jetchat.theme.JetchatTheme
import kotlinx.coroutines.flow.MutableStateFlow
import org.junit.After
import org.junit.Before
import org.junit.Rule
import org.junit.Test
Expand All @@ -49,18 +51,25 @@ class ConversationTest {

@Before
fun setUp() {
resetFakeData()
val uiState = createConversationTestUiState()
// Launch the conversation screen
composeTestRule.setContent {
JetchatTheme(isDarkTheme = themeIsDark.collectAsStateWithLifecycle(false).value) {
ConversationContent(
uiState = conversationTestUiState,
uiState = uiState,
navigateToProfile = { },
onNavIconPressed = { },
)
}
}
}

@After
fun tearDown() {
resetFakeData()
}

@Test
fun app_launches() {
// Check that the conversation screen is visible on launch
Expand All @@ -71,27 +80,15 @@ class ConversationTest {
fun userScrollsUp_jumpToBottomAppears() {
// Check list is snapped to bottom and swipe up
findJumpToBottom().assertDoesNotExist()
composeTestRule.onNodeWithTag(ConversationTestTag).performTouchInput {
this.swipe(
start = this.center,
end = Offset(this.center.x, this.center.y + 500),
durationMillis = 200,
)
}
scrollAwayFromBottom()
// Check that the jump to bottom button is shown
findJumpToBottom().assertIsDisplayed()
}

@Test
fun jumpToBottom_snapsToBottomAndDisappears() {
// When the scroll is not snapped to the bottom
composeTestRule.onNodeWithTag(ConversationTestTag).performTouchInput {
this.swipe(
start = this.center,
end = Offset(this.center.x, this.center.y + 500),
durationMillis = 200,
)
}
scrollAwayFromBottom()
// Snap scroll to the bottom
findJumpToBottom().performClick()

Expand All @@ -102,16 +99,7 @@ class ConversationTest {
@Test
fun jumpToBottom_snapsToBottomAfterUserInteracted() {
// First swipe
composeTestRule.onNodeWithTag(
testTag = ConversationTestTag,
useUnmergedTree = true, // https://issuetracker.google.com/issues/184825850
).performTouchInput {
this.swipe(
start = this.center,
end = Offset(this.center.x, this.center.y + 500),
durationMillis = 200,
)
}
scrollAwayFromBottom()
// Second, snap to bottom
findJumpToBottom().performClick()

Expand All @@ -125,13 +113,7 @@ class ConversationTest {
@Test
fun changeTheme_scrollIsPersisted() {
// Swipe to show the jump to bottom button
composeTestRule.onNodeWithTag(ConversationTestTag).performTouchInput {
this.swipe(
start = this.center,
end = Offset(this.center.x, this.center.y + 500),
durationMillis = 200,
)
}
scrollAwayFromBottom()

// Check that the jump to bottom button is shown
findJumpToBottom().assertIsDisplayed()
Expand All @@ -143,6 +125,27 @@ class ConversationTest {
findJumpToBottom().assertIsDisplayed()
}

/**
* Scrolls the conversation far enough away from the bottom (more than 1.5x the viewport
* height) for the jump to bottom button to appear. Start from the center so the touch down
* does not land on the overlaid top app bar.
*/
private fun scrollAwayFromBottom() {
repeat(5) {
composeTestRule.onNodeWithTag(
testTag = ConversationTestTag,
useUnmergedTree = true, // https://issuetracker.google.com/issues/184825850
).performTouchInput {
this.swipe(
start = this.center,
end = Offset(this.center.x, this.bottom - 10f),
durationMillis = 200,
)
}
composeTestRule.waitForIdle()
}
}

private fun findJumpToBottom() = composeTestRule.onNodeWithText(
composeTestRule.activity.getString(R.string.jumpBottom),
useUnmergedTree = true,
Expand All @@ -159,8 +162,9 @@ class ConversationTest {
/**
* Make the list of messages longer so the test makes sense on tablets.
*/
private val conversationTestUiState = ConversationUiState(
initialMessages = (exampleUiState.messages.plus(exampleUiState.messages)),
private fun createConversationTestUiState() = ConversationUiState(
initialMessages = exampleUiState.messages +
exampleUiState.messages.map { it.copy(id = "${it.id}-copy") },
channelName = "#composers",
channelMembers = 42,
)
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ import androidx.compose.ui.test.performTouchInput
import androidx.compose.ui.test.swipeRight
import androidx.lifecycle.Lifecycle
import androidx.test.espresso.Espresso
import com.example.compose.jetchat.data.resetFakeData
import org.junit.After
import org.junit.Rule
import org.junit.Test

Expand All @@ -43,6 +45,13 @@ class NavigationTest {
@get:Rule
val composeTestRule = createAndroidComposeRule<NavActivity>()

@After
fun tearDown() {
// NavActivity launches inside composeTestRule before @Before runs, so clear cached channel
// state after each test so the next test's Activity starts fresh.
resetFakeData()
}

@Test
fun app_launches() {
// Check app launches at the correct destination
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,9 @@ import androidx.test.espresso.Espresso
import com.example.compose.jetchat.conversation.ConversationContent
import com.example.compose.jetchat.conversation.KeyboardShownKey
import com.example.compose.jetchat.data.exampleUiState
import com.example.compose.jetchat.data.resetFakeData
import com.example.compose.jetchat.theme.JetchatTheme
import org.junit.After
import org.junit.Before
import org.junit.Ignore
import org.junit.Rule
Expand All @@ -58,18 +60,25 @@ class UserInputTest {

@Before
fun setUp() {
resetFakeData()
// Launch the conversation screen
val uiState = exampleUiState
composeTestRule.setContent {
JetchatTheme {
ConversationContent(
uiState = exampleUiState,
uiState = uiState,
navigateToProfile = { },
onNavIconPressed = { },
)
}
}
}

@After
fun tearDown() {
resetFakeData()
}

@Test
@Ignore("Issue with keyboard sync https://issuetracker.google.com/169235317")
fun emojiSelector_isClosedWithBack() {
Expand Down
Loading
Loading