Skip to content

Commit 7168285

Browse files
committed
Add E2E test on Android LeapChat to have two turns of chat
1 parent 98650e3 commit 7168285

File tree

3 files changed

+72
-6
lines changed

3 files changed

+72
-6
lines changed
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package ai.liquid.leapchat
2+
3+
import androidx.compose.ui.test.ExperimentalTestApi
4+
import androidx.compose.ui.test.assertIsDisplayed
5+
import androidx.compose.ui.test.assertTextContains
6+
import androidx.compose.ui.test.hasTestTag
7+
import androidx.compose.ui.test.hasText
8+
import androidx.compose.ui.test.junit4.createAndroidComposeRule
9+
import androidx.compose.ui.test.onAllNodesWithTag
10+
import androidx.compose.ui.test.performClick
11+
import androidx.compose.ui.test.performTextInput
12+
import androidx.test.ext.junit.runners.AndroidJUnit4
13+
import org.junit.Rule
14+
import org.junit.Test
15+
import org.junit.runner.RunWith
16+
17+
@RunWith(AndroidJUnit4::class)
18+
class MainActivityE2EAssetTests {
19+
20+
@get:Rule
21+
val composeTestRule = createAndroidComposeRule<MainActivity>()
22+
23+
24+
@OptIn(ExperimentalTestApi::class)
25+
@Test
26+
fun testEndToEndChat() {
27+
val modelLoadingIndicatorMatcher = hasTestTag("ModelLoadingIndicator")
28+
val inputBoxMatcher = hasTestTag("InputBox")
29+
val sendButtonMatcher = hasText("Send")
30+
31+
// Wait for the model to be downloaded and loaded
32+
composeTestRule.onNode(modelLoadingIndicatorMatcher).assertIsDisplayed()
33+
composeTestRule.waitUntilDoesNotExist(
34+
modelLoadingIndicatorMatcher,
35+
timeoutMillis = MODEL_LOADING_TIMEOUT
36+
)
37+
composeTestRule.waitUntilAtLeastOneExists(sendButtonMatcher, timeoutMillis = 5000L)
38+
39+
// Send an input to the model
40+
composeTestRule.onNode(inputBoxMatcher)
41+
.performTextInput("How many 'r' are there in the word 'strawberry'?")
42+
composeTestRule.onNode(sendButtonMatcher).performClick()
43+
composeTestRule.waitUntilAtLeastOneExists(
44+
hasTestTag("AssistantMessageView"),
45+
timeoutMillis = 5000L
46+
)
47+
composeTestRule.onNode(hasTestTag("AssistantMessageViewText"))
48+
.assertTextContains("strawberry", substring = true)
49+
50+
// Continue the chat with a second prompt
51+
composeTestRule.onNode(inputBoxMatcher).performTextInput("What about letter 'a'?")
52+
composeTestRule.onNode(sendButtonMatcher).performClick()
53+
composeTestRule.waitUntil(timeoutMillis = 5000L) {
54+
composeTestRule.onAllNodesWithTag("AssistantMessageView")
55+
.fetchSemanticsNodes().size == 2
56+
}
57+
}
58+
59+
companion object {
60+
const val MODEL_LOADING_TIMEOUT = 5L * 60L * 1000L
61+
}
62+
}

Android/LeapChat/app/src/main/java/ai/liquid/leapchat/MainActivity.kt

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ import androidx.compose.ui.Modifier
5252
import androidx.compose.ui.focus.FocusRequester
5353
import androidx.compose.ui.focus.focusRequester
5454
import androidx.compose.ui.platform.LocalContext
55+
import androidx.compose.ui.platform.testTag
5556
import androidx.compose.ui.unit.dp
5657
import androidx.lifecycle.MutableLiveData
5758
import androidx.lifecycle.lifecycleScope
@@ -152,7 +153,7 @@ class MainActivity : ComponentActivity() {
152153
onValueChange = { userInputFieldText = it },
153154
modifier = Modifier
154155
.padding(4.dp)
155-
.fillMaxWidth(1.0f),
156+
.fillMaxWidth(1.0f).testTag("InputBox"),
156157
enabled = !isInGeneration.value
157158
)
158159
Row(
@@ -469,8 +470,8 @@ class MainActivity : ComponentActivity() {
469470
}
470471

471472
companion object {
472-
const val MODEL_SLUG = "lfm2-1.2b"
473-
const val QUANTIZATION_SLUG = "lfm2-1.2b-20250710-8da4w"
473+
const val MODEL_SLUG = "lfm2-350m"
474+
const val QUANTIZATION_SLUG = "lfm2-350m-20250710-8da4w"
474475
}
475476
}
476477

@@ -497,7 +498,9 @@ fun ModelLoadingIndicator(
497498
Box(
498499
Modifier
499500
.padding(4.dp)
500-
.fillMaxSize(1.0f), contentAlignment = Alignment.Center
501+
.fillMaxSize(1.0f)
502+
.testTag("ModelLoadingIndicator"),
503+
contentAlignment = Alignment.Center
501504
) {
502505
Text(modelLoadingStatusText, style = MaterialTheme.typography.titleSmall)
503506
}

Android/LeapChat/app/src/main/java/ai/liquid/leapchat/views/AssistantMessage.kt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import androidx.compose.material3.Text
1717
import androidx.compose.runtime.Composable
1818
import androidx.compose.ui.Alignment
1919
import androidx.compose.ui.Modifier
20+
import androidx.compose.ui.platform.testTag
2021
import androidx.compose.ui.res.painterResource
2122
import androidx.compose.ui.tooling.preview.Preview
2223
import androidx.compose.ui.unit.dp
@@ -27,7 +28,7 @@ fun AssistantMessage(
2728
reasoningText: String?,
2829
) {
2930
val reasoningText = reasoningText?.trim()
30-
Row(modifier = Modifier.padding(all = 8.dp).fillMaxWidth(1.0f), horizontalArrangement = Arrangement.Absolute.Left) {
31+
Row(modifier = Modifier.padding(all = 8.dp).fillMaxWidth(1.0f).testTag("AssistantMessageView"), horizontalArrangement = Arrangement.Absolute.Left) {
3132
Image(
3233
painter = painterResource(R.drawable.smart_toy_outline),
3334
contentDescription = "Assistant icon",
@@ -43,7 +44,7 @@ fun AssistantMessage(
4344
Text(text = reasoningText, style = MaterialTheme.typography.bodySmall, color = MaterialTheme.colorScheme.secondary)
4445
}
4546
Spacer(modifier = Modifier.height(4.dp))
46-
Text(text = text, style = MaterialTheme.typography.bodyMedium)
47+
Text(text = text, style = MaterialTheme.typography.bodyMedium, modifier = Modifier.testTag("AssistantMessageViewText"))
4748
}
4849
}
4950
}

0 commit comments

Comments
 (0)