Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
2a88af8
Feat integration-tests-1.3.0: Implement e2e instrumentation tests for…
HellBus1 Feb 19, 2026
2caec4e
Feat integration-tests-1.3.0: Implement e2e instrumentation tests for…
HellBus1 Feb 19, 2026
bd3a021
Feat integration-tests-1.3.0: Implement e2e instrumentation tests for…
HellBus1 Feb 19, 2026
dd32f0f
Feat integration-tests-1.3.0: Adjust warning implementations
HellBus1 Feb 19, 2026
dda16cc
Feat integration-tests-1.3.0: Add instrumentation tests for NoteCreat…
HellBus1 Feb 19, 2026
4a2ff39
Feat integration-tests-1.3.0: Remove unused imports
HellBus1 Feb 19, 2026
ecc72f5
Feat integration-tests-1.3.0: Add instrumentation tests in the GitHub…
HellBus1 Feb 19, 2026
0b13370
Feat integration-tests-1.3.0: Change emulator architecture
HellBus1 Feb 19, 2026
13c9cf3
Feat integration-tests-1.3.0: Force recreate avd every job run
HellBus1 Feb 19, 2026
15de2ee
Feat integration-tests-1.3.0: Remove instrumentation tests run in the…
HellBus1 Feb 19, 2026
048ee9e
Merge pull request #73 from HellBus1/integration-tests-1.3.0
HellBus1 Feb 19, 2026
0363d98
Feat richtext-editor-1.3.0: (WIP) implement fully functional bold, it…
HellBus1 Feb 20, 2026
fd771f1
Feat richtext-editor-1.3.0: Implement Markdown to Spannable conversio…
HellBus1 Feb 21, 2026
afeb818
Merge pull request #74 from HellBus1/richtext-editor-1.3.0
HellBus1 Feb 22, 2026
1b15229
Feat ui-redesign-1.3.0: Revamp the whole style to flat design
HellBus1 Feb 22, 2026
d5bcecf
Merge pull request #75 from HellBus1/ui-redesign-1.3.0
HellBus1 Feb 22, 2026
5d47975
Feat list-notes-ux-enhancement-1.3.0: Implement staggered grid view f…
HellBus1 Feb 22, 2026
28d7c47
Merge pull request #76 from HellBus1/list-notes-ux-enhancement-1.3.0
HellBus1 Feb 22, 2026
5d97410
Merge pull request #77 from HellBus1/1.3.0
HellBus1 Feb 23, 2026
ec852e2
Chore staging: Increase version code & change version name
HellBus1 Feb 23, 2026
d01e29c
Merge branch 'master' of github.com:HellBus1/VentNote into staging
HellBus1 Feb 23, 2026
bb4aeed
Chore staging: Increase version code
HellBus1 Feb 23, 2026
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
121 changes: 86 additions & 35 deletions .github/workflows/android_ci.yml
Original file line number Diff line number Diff line change
@@ -1,46 +1,97 @@
name: VentNote Build and Test CI
name: VentNote CI

on:
pull_request:
push:
branches: [ master ]
pull_request:
branches: [ master, staging ]

jobs:
test:
name: Run Unit Tests
lint-and-unit-test:
name: Lint and Unit Tests
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3
- name: Set up JDK 17
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'adopt'
cache: gradle

- name: Unit tests
run: ./gradlew test --stacktrace
- uses: actions/checkout@v4

- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
cache: gradle

- name: Run Lint
run: ./gradlew lintDebug --stacktrace

- name: Run Unit Tests
run: ./gradlew testDebugUnitTest --stacktrace

build:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write

steps:
- uses: actions/checkout@v3
- name: Set up JDK 17
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'adopt'
cache: gradle
- name: Upload Test Reports
if: always()
uses: actions/upload-artifact@v4
with:
name: lint-and-unit-test-reports
path: |
**/build/reports/lint-results-*.html
**/build/reports/tests/testDebugUnitTest/

- name: Clean project
run: ./gradlew clean --stacktrace
# instrumentation-test:
# name: Instrumentation Tests
# runs-on: macos-latest
# timeout-minutes: 60
# strategy:
# matrix:
# api-level: [34]
# steps:
# - uses: actions/checkout@v4
#
# - name: Set up JDK 17
# uses: actions/setup-java@v4
# with:
# java-version: '17'
# distribution: 'temurin'
# cache: gradle
#
# - name: Run Instrumentation Tests
# uses: reactivecircus/android-emulator-runner@v2
# with:
# api-level: ${{ matrix.api-level }}
# arch: arm64-v8a
# target: google_apis
# force-avd-creation: true
# emulator-options: -no-window -gpu swiftshader_indirect -no-snapshot -noaudio -no-boot-anim
# disable-animations: true
# # Increased RAM for better stability on ARM runners
# disk-size: 4096M
# heap-size: 512M
# script: ./gradlew connectedDebugAndroidTest --stacktrace
#
# - name: Upload Instrumentation Reports
# if: always()
# uses: actions/upload-artifact@v4
# with:
# name: instrumentation-test-reports
# path: app/build/reports/androidTests/connected/

- name: Lint Debug
run: ./gradlew lintDebug --stacktrace
build-check:
name: Build APK Check
runs-on: ubuntu-latest
needs: [lint-and-unit-test]
steps:
- uses: actions/checkout@v4

- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
cache: gradle

- name: Build debug APK
run: ./gradlew build --stacktrace
- name: Build Debug APK
run: ./gradlew assembleDebug --stacktrace

- name: Upload Debug APK
uses: actions/upload-artifact@v4
with:
name: debug-apk
path: app/build/outputs/apk/debug/*.apk
4 changes: 2 additions & 2 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ android {
applicationId "com.digiventure.ventnote"
minSdk 23
targetSdk = 36
versionCode 47
versionName "1.2.0"
versionCode 48
versionName "1.3.0"

testInstrumentationRunner "com.digiventure.utils.CustomTestRunner"
vectorDrawables {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
//package com.digiventure.utils
//
//import androidx.test.ext.junit.runners.AndroidJUnit4
//import org.junit.runner.RunWith
//
//@RunWith(AndroidJUnit4::class)
//abstract class BaseAcceptanceTest {
//// @get:Rule(order = 0)
//// val composeTestRule = createComposeRule()
//}
package com.digiventure.utils

import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.runner.RunWith

@RunWith(AndroidJUnit4::class)
abstract class BaseAcceptanceTest
138 changes: 138 additions & 0 deletions app/src/androidTest/java/com/digiventure/ventnote/NavDrawerFeature.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
package com.digiventure.ventnote

import android.content.Intent
import androidx.compose.ui.test.*
import androidx.compose.ui.test.junit4.createAndroidComposeRule
import androidx.test.espresso.intent.Intents
import androidx.test.espresso.intent.Intents.intended
import androidx.test.espresso.intent.matcher.IntentMatchers.hasAction
import androidx.test.espresso.intent.matcher.IntentMatchers.hasData
import com.digiventure.utils.BaseAcceptanceTest
import com.digiventure.ventnote.commons.TestTags
import dagger.hilt.android.testing.HiltAndroidRule
import dagger.hilt.android.testing.HiltAndroidTest
import org.hamcrest.Matchers.allOf
import org.junit.After
import org.junit.Before
import org.junit.Rule
import org.junit.Test

@HiltAndroidTest
class NavDrawerFeature : BaseAcceptanceTest() {

@get:Rule(order = 0)
val hiltRule = HiltAndroidRule(this)

@get:Rule(order = 1)
val composeTestRule = createAndroidComposeRule<MainActivity>()

@Before
fun setUp() {
hiltRule.inject()
Intents.init()

// Open the drawer
composeTestRule.onNodeWithTag(TestTags.NOTES_PAGE).assertIsDisplayed()
composeTestRule.onNodeWithTag(TestTags.MENU_ICON_BUTTON).performClick()
composeTestRule.waitForIdle()
composeTestRule.onNodeWithTag(TestTags.NAV_DRAWER, useUnmergedTree = true).assertIsDisplayed()
}

@After
fun tearDown() {
Intents.release()
}

@Test
fun initialState_showsMenuItems() {
composeTestRule.onNodeWithTag(TestTags.RATE_APP_TILE).assertIsDisplayed()
composeTestRule.onNodeWithTag(TestTags.MORE_APPS_TILE).assertIsDisplayed()
composeTestRule.onNodeWithTag(TestTags.APP_VERSION_TILE).assertIsDisplayed()
composeTestRule.onNodeWithTag(TestTags.THEME_TILE).assertIsDisplayed()
composeTestRule.onNodeWithTag(TestTags.COLOR_MODE_TILE).assertIsDisplayed()
composeTestRule.onNodeWithTag(TestTags.BACKUP_TILE).assertIsDisplayed()
}

@Test
fun rateApp_launchesPlayStore() {
composeTestRule.onNodeWithTag(TestTags.RATE_APP_TILE).performClick()

intended(allOf(
hasAction(Intent.ACTION_VIEW),
hasData("https://play.google.com/store/apps/details?id=com.digiventure.ventnote")
))
}

@Test
fun moreApps_launchesDeveloperPage() {
composeTestRule.onNodeWithTag(TestTags.MORE_APPS_TILE).performClick()

intended(allOf(
hasAction(Intent.ACTION_VIEW),
hasData("https://play.google.com/store/apps/developer?id=Mattrmost")
))
}

@Test
fun backupNavigation_navigatesToBackupPage() {
composeTestRule.onNodeWithTag(TestTags.BACKUP_TILE).performClick()
composeTestRule.waitForIdle()

// Use text or tag to verify backup page (usually has "Backup" title in header)
composeTestRule.onNodeWithText("Backup Notes").assertIsDisplayed()
}

@Test
fun themeColorChange_updatesTheme() {
// Verify we can click all theme colors
composeTestRule.onNodeWithTag(TestTags.THEME_COLOR_PURPLE).performClick()
composeTestRule.onNodeWithTag(TestTags.THEME_COLOR_CRIMSON).performClick()
composeTestRule.onNodeWithTag(TestTags.THEME_COLOR_CADMIUM_GREEN).performClick()
composeTestRule.onNodeWithTag(TestTags.THEME_COLOR_COBALT_BLUE).performClick()

// Clicks should not crash and should update internal state (hard to verify without custom matchers)
composeTestRule.onNodeWithTag(TestTags.THEME_TILE).assertIsDisplayed()
}

@Test
fun colorModeToggle_updatesMode() {
// Find the current mode by checking the subtitle text
val lightModeText = "switch to light mode"
val darkModeText = "switch to dark mode"

// Initial click to toggle (assuming default is light mode or whatever)
// We look for either text to be sure
val initialNode = composeTestRule.onNode(
hasText(lightModeText, ignoreCase = true) or hasText(darkModeText, ignoreCase = true)
)

initialNode.assertIsDisplayed()
val isInitiallyLight = try {
composeTestRule.onNodeWithText(darkModeText, ignoreCase = true).assertIsDisplayed()
true // It says "switch to dark", so it is currently light
} catch (_: Throwable) {
false
}

// Toggle
composeTestRule.onNodeWithTag(TestTags.COLOR_MODE_TILE).performClick()
composeTestRule.waitForIdle()

// Verify text swapped
if (isInitiallyLight) {
composeTestRule.onNodeWithText(lightModeText, ignoreCase = true).assertIsDisplayed()
} else {
composeTestRule.onNodeWithText(darkModeText, ignoreCase = true).assertIsDisplayed()
}
}

@Test
fun drawer_canBeClosed() {
// Click outside or use a specific close mechanism if available,
// but here we can just swipe or click the content area if accessible.
// Easiest is to just verify it closes on back press
androidx.test.platform.app.InstrumentationRegistry.getInstrumentation().sendKeyDownUpSync(android.view.KeyEvent.KEYCODE_BACK)
composeTestRule.waitForIdle()
composeTestRule.onNodeWithTag(TestTags.NAV_DRAWER).assertDoesNotExist()
}
}
Loading