Skip to content

Commit 6525e03

Browse files
committed
feat: add UI tests and CI workflow for example app
Introduce Compose-based UI tests for MainScreen and ColorVotingScreen. Add GitHub Actions workflow to run tests on pull requests and pushes to `main`.
1 parent 072893e commit 6525e03

3 files changed

Lines changed: 114 additions & 0 deletions

File tree

.github/workflows/example-app.yml

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
name: Example App
2+
3+
on:
4+
pull_request:
5+
push:
6+
branches:
7+
- main
8+
9+
jobs:
10+
check:
11+
runs-on: ubuntu-latest
12+
strategy:
13+
fail-fast: false
14+
matrix:
15+
android-api-level: [ 34 ]
16+
17+
steps:
18+
- name: checkout
19+
uses: actions/checkout@v4
20+
21+
- name: Set up the JDK
22+
uses: actions/setup-java@v3
23+
with:
24+
java-version: '17'
25+
distribution: 'temurin'
26+
27+
- name: Set up Gradle
28+
uses: gradle/actions/setup-gradle@v3
29+
30+
- name: Enable KVM
31+
run: |
32+
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
33+
sudo udevadm control --reload-rules
34+
sudo udevadm trigger --name-match=kvm
35+
36+
- uses: reactivecircus/android-emulator-runner@v2
37+
with:
38+
api-level: ${{ matrix.android-api-level }}
39+
emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
40+
disable-animations: true
41+
# Print emulator logs if tests fail
42+
script: ./gradlew :examples:connectedAndroidTest || (adb logcat -d System.out:I && exit 1)
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package com.ably.example
2+
3+
import androidx.compose.ui.semantics.SemanticsProperties
4+
import androidx.compose.ui.test.assertIsDisplayed
5+
import androidx.compose.ui.test.junit4.createAndroidComposeRule
6+
import androidx.compose.ui.test.onAllNodesWithText
7+
import androidx.compose.ui.test.onNodeWithText
8+
import androidx.compose.ui.test.performClick
9+
import androidx.test.ext.junit.runners.AndroidJUnit4
10+
import org.junit.Rule
11+
import org.junit.Test
12+
import org.junit.runner.RunWith
13+
14+
@RunWith(AndroidJUnit4::class)
15+
class ColorVotingScreenTest {
16+
17+
@get:Rule
18+
val composeTestRule = createAndroidComposeRule<MainActivity>()
19+
20+
@Test
21+
fun incrementRedColor() {
22+
// Navigate to Color Voting tab
23+
composeTestRule.onNodeWithText("Color Voting").performClick()
24+
25+
// Wait for the screen to load
26+
composeTestRule.waitForIdle()
27+
28+
// Get initial red count (should be 0 initially or some value)
29+
composeTestRule.onNodeWithText("Red")
30+
31+
// Find and click the Vote button for Red color
32+
// The Vote button should be near the Red text
33+
// Use the first Vote button which corresponds to Red (first ColorVoteCard)
34+
val redVoteButton = composeTestRule.onAllNodesWithText("Vote")[0]
35+
36+
composeTestRule.waitUntil(timeoutMillis = 10_000) {
37+
SemanticsProperties.Disabled !in redVoteButton.fetchSemanticsNode().config
38+
}
39+
40+
redVoteButton.performClick()
41+
42+
// Wait for the counter to update with 1 second timeout
43+
composeTestRule.waitUntil(timeoutMillis = 1_000) {
44+
composeTestRule.onAllNodesWithText("1").fetchSemanticsNodes().isNotEmpty()
45+
}
46+
47+
composeTestRule.onNodeWithText("1").assertIsDisplayed()
48+
}
49+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package com.ably.example
2+
3+
import androidx.compose.ui.test.assertIsDisplayed
4+
import androidx.compose.ui.test.junit4.createAndroidComposeRule
5+
import androidx.compose.ui.test.onNodeWithText
6+
import androidx.test.ext.junit.runners.AndroidJUnit4
7+
import org.junit.Rule
8+
import org.junit.Test
9+
import org.junit.runner.RunWith
10+
11+
@RunWith(AndroidJUnit4::class)
12+
class MainScreenTest {
13+
14+
@get:Rule
15+
val composeTestRule = createAndroidComposeRule<MainActivity>()
16+
17+
@Test
18+
fun tabsAreDisplayed() {
19+
// Verify both tabs are displayed
20+
composeTestRule.onNodeWithText("Color Voting").assertIsDisplayed()
21+
composeTestRule.onNodeWithText("Task Management").assertIsDisplayed()
22+
}
23+
}

0 commit comments

Comments
 (0)