From f899bcbab2d866fa4cf001c099f2e6a2c2493949 Mon Sep 17 00:00:00 2001 From: "v.scharf" Date: Fri, 24 Apr 2026 13:35:48 +0200 Subject: [PATCH 1/6] run test in woolppecker ci --- .woodpecker/build.yaml | 14 +++++++ .woodpecker/test.yml | 38 +++++++++++++++++++ .../eu/opencloud/android/LoginScreenTest.kt | 24 ++++++------ 3 files changed, 64 insertions(+), 12 deletions(-) create mode 100644 .woodpecker/build.yaml create mode 100644 .woodpecker/test.yml diff --git a/.woodpecker/build.yaml b/.woodpecker/build.yaml new file mode 100644 index 000000000..098897676 --- /dev/null +++ b/.woodpecker/build.yaml @@ -0,0 +1,14 @@ +variables: + - &android_image 'docker.io/mingc/android-build-box:1.29.0' + +when: + - event: pull_request + - event: push + branch: + - ${CI_REPO_DEFAULT_BRANCH} + +steps: + - name: build + image: *android_image + commands: + - ./gradlew :opencloudApp:assembleOriginalDebugAndroidTest diff --git a/.woodpecker/test.yml b/.woodpecker/test.yml new file mode 100644 index 000000000..0d78af132 --- /dev/null +++ b/.woodpecker/test.yml @@ -0,0 +1,38 @@ +variables: + - &android_image 'docker.io/mingc/android-build-box:1.29.0' + - &emulator_image 'docker.io/shmayro/dockerify-android:09-02-26' + +depends_on: + - build + +when: + - event: pull_request + - event: push + branch: + - ${CI_REPO_DEFAULT_BRANCH} + +steps: + - name: emulator + image: *emulator_image + privileged: true + devices: + - /dev/kvm + detach: true + + - name: wait for emulator + image: *android_image + commands: + - adb connect emulator:5555 + - adb devices + + - name: start adb server + image: *android_image + commands: + - curl -L -o adbserver-desktop.jar https://github.com/KasperskyLab/Kaspresso/raw/master/artifacts/adbserver-desktop.jar + - java -jar adbserver-desktop.jar & + detach: true + + - name: run tests + image: *android_image + commands: + - ./gradlew :opencloudApp:connectedOriginalDebugAndroidTest -Pandroid.testInstrumentationRunnerArguments.class=eu.opencloud.android.LoginScreenTest#loginApp \ No newline at end of file diff --git a/opencloudApp/src/integrationTest/java/eu/opencloud/android/LoginScreenTest.kt b/opencloudApp/src/integrationTest/java/eu/opencloud/android/LoginScreenTest.kt index 17601fb47..590ee32fc 100644 --- a/opencloudApp/src/integrationTest/java/eu/opencloud/android/LoginScreenTest.kt +++ b/opencloudApp/src/integrationTest/java/eu/opencloud/android/LoginScreenTest.kt @@ -34,16 +34,16 @@ class LoginScreenTest : TestCase( @Test fun loginApp() { before { - adbServer.performCmd("adb", listOf("reverse", "tcp:9200", "tcp:9200")) +// adbServer.performCmd("adb", listOf("reverse", "tcp:9200", "tcp:9200")) }.after { adbServer.performCmd("adb", listOf("shell", "am", "force-stop", "com.android.chrome")) - adbServer.performCmd("adb", listOf("reverse", "--remove", "tcp:9200")) +// adbServer.performCmd("adb", listOf("reverse", "--remove", "tcp:9200")) }.run { step("set opencloud url") { StartScreen { hostUrlInput { isVisible() - typeText("https://localhost:9200") + typeText("https://cloud.rc.opencloud.rocks") } checkServerButton { isVisible() @@ -52,15 +52,15 @@ class LoginScreenTest : TestCase( } } } - step("trust certificate") { - TrustCertificate { - yesBtn { - isVisible() - isClickable() - click() - } - } - } +// step("trust certificate") { +// TrustCertificate { +// yesBtn { +// isVisible() +// isClickable() +// click() +// } +// } +// } step("login") { LoginScreen { username.isDisplayed() From 8b6e316a2b93982a744fdc98332ed972cd103f15 Mon Sep 17 00:00:00 2001 From: "v.scharf" Date: Fri, 24 Apr 2026 14:57:04 +0200 Subject: [PATCH 2/6] fix --- .woodpecker/test.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.woodpecker/test.yml b/.woodpecker/test.yml index 0d78af132..c8f3707c0 100644 --- a/.woodpecker/test.yml +++ b/.woodpecker/test.yml @@ -14,9 +14,6 @@ when: steps: - name: emulator image: *emulator_image - privileged: true - devices: - - /dev/kvm detach: true - name: wait for emulator From c8d1ab2b38653462fea9eaa20027ef3a6f1d7f4f Mon Sep 17 00:00:00 2001 From: "v.scharf" Date: Mon, 27 Apr 2026 13:47:11 +0200 Subject: [PATCH 3/6] rin in gh actions --- .github/workflows/integration.yml | 49 ++++++++++++++++++++++++ {.woodpecker => .wood-pecker}/build.yaml | 0 {.woodpecker => .wood-pecker}/test.yml | 0 3 files changed, 49 insertions(+) create mode 100644 .github/workflows/integration.yml rename {.woodpecker => .wood-pecker}/build.yaml (100%) rename {.woodpecker => .wood-pecker}/test.yml (100%) diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml new file mode 100644 index 000000000..6ddc37e9a --- /dev/null +++ b/.github/workflows/integration.yml @@ -0,0 +1,49 @@ +name: Integration Tests + +on: + pull_request: + branches: + - "*" + +jobs: + integration_tests: + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2 + + - name: Set up JDK 17 + uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 #v5.2.0 + with: + java-version: '17' + distribution: 'temurin' + + - name: Set up Gradle + uses: gradle/actions/setup-gradle@50e97c2cd7a37755bbfafc9c5b7cafaece252f6e #v6.1.0 + + - name: Enable KVM + run: | + echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules + sudo udevadm control --reload-rules + sudo udevadm trigger --name-match=kvm + + - name: Build test APK + run: ./gradlew :opencloudApp:assembleOriginalDebugAndroidTest + + - name: Run integration tests with emulator + uses: reactivecircus/android-emulator-runner@e89f39f1abbbd05b1113a29cf4db69e7540cae5a #v2.37.0 + with: + api-level: 35 + target: google_apis + arch: x86_64 + profile: pixel + avd-name: integration-tests-avd + force-avd-creation: true + disable-animations: true + emulator-options: -no-window -no-audio -no-boot-anim -accel auto -memory 2048 + script: | + curl -L -o adbserver-desktop.jar https://github.com/KasperskyLab/Kaspresso/raw/master/artifacts/adbserver-desktop.jar + java -jar adbserver-desktop.jar & + sleep 3 + ./gradlew :opencloudApp:connectedOriginalDebugAndroidTest -Pandroid.testInstrumentationRunnerArguments.class=eu.opencloud.android.LoginScreenTest#loginApp diff --git a/.woodpecker/build.yaml b/.wood-pecker/build.yaml similarity index 100% rename from .woodpecker/build.yaml rename to .wood-pecker/build.yaml diff --git a/.woodpecker/test.yml b/.wood-pecker/test.yml similarity index 100% rename from .woodpecker/test.yml rename to .wood-pecker/test.yml From 6ef31d35e711d5b102ce4a471937a0c2bbfb1d77 Mon Sep 17 00:00:00 2001 From: "v.scharf" Date: Mon, 27 Apr 2026 14:05:45 +0200 Subject: [PATCH 4/6] kill adb after failed test --- .github/workflows/integration.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index 6ddc37e9a..5e2c4ed74 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -45,5 +45,7 @@ jobs: script: | curl -L -o adbserver-desktop.jar https://github.com/KasperskyLab/Kaspresso/raw/master/artifacts/adbserver-desktop.jar java -jar adbserver-desktop.jar & + ADB_SERVER_PID=$! sleep 3 ./gradlew :opencloudApp:connectedOriginalDebugAndroidTest -Pandroid.testInstrumentationRunnerArguments.class=eu.opencloud.android.LoginScreenTest#loginApp + kill $ADB_SERVER_PID || true From 8f5e2a2c831504a2046439213f1119352d01b026 Mon Sep 17 00:00:00 2001 From: "v.scharf" Date: Mon, 27 Apr 2026 14:22:03 +0200 Subject: [PATCH 5/6] use keycloak credentials --- .github/workflows/integration.yml | 2 -- .../java/eu/opencloud/android/LoginScreenTest.kt | 3 +++ .../src/integrationTest/java/screens/LoginScreen.kt | 11 ++++++++--- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index 5e2c4ed74..6ddc37e9a 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -45,7 +45,5 @@ jobs: script: | curl -L -o adbserver-desktop.jar https://github.com/KasperskyLab/Kaspresso/raw/master/artifacts/adbserver-desktop.jar java -jar adbserver-desktop.jar & - ADB_SERVER_PID=$! sleep 3 ./gradlew :opencloudApp:connectedOriginalDebugAndroidTest -Pandroid.testInstrumentationRunnerArguments.class=eu.opencloud.android.LoginScreenTest#loginApp - kill $ADB_SERVER_PID || true diff --git a/opencloudApp/src/integrationTest/java/eu/opencloud/android/LoginScreenTest.kt b/opencloudApp/src/integrationTest/java/eu/opencloud/android/LoginScreenTest.kt index 590ee32fc..cafe0ac32 100644 --- a/opencloudApp/src/integrationTest/java/eu/opencloud/android/LoginScreenTest.kt +++ b/opencloudApp/src/integrationTest/java/eu/opencloud/android/LoginScreenTest.kt @@ -35,6 +35,9 @@ class LoginScreenTest : TestCase( fun loginApp() { before { // adbServer.performCmd("adb", listOf("reverse", "tcp:9200", "tcp:9200")) + adbServer.performCmd("adb", listOf("shell", "settings", "put", "global", "heads_up_notifications_enabled", "0")) + adbServer.performCmd("adb", listOf("shell", "wm", "dismiss-keyguard")) + adbServer.performCmd("adb", listOf("shell", "input", "keyevent", "82")) }.after { adbServer.performCmd("adb", listOf("shell", "am", "force-stop", "com.android.chrome")) // adbServer.performCmd("adb", listOf("reverse", "--remove", "tcp:9200")) diff --git a/opencloudApp/src/integrationTest/java/screens/LoginScreen.kt b/opencloudApp/src/integrationTest/java/screens/LoginScreen.kt index ce460d0f3..3e800b81a 100644 --- a/opencloudApp/src/integrationTest/java/screens/LoginScreen.kt +++ b/opencloudApp/src/integrationTest/java/screens/LoginScreen.kt @@ -8,9 +8,14 @@ object LoginScreen : UiScreen() { override val packageName: String = "com.android.chrome" // can't find it using withId("com.android.chrome", "username") so using withResourceName() - val username = UiEditText { withResourceName("oc-login-username") } - val password = UiEditText { withResourceName("oc-login-password") } - val loginButton = UiButton { withText("Log in") } +// val username = UiEditText { withResourceName("oc-login-username") } +// val password = UiEditText { withResourceName("oc-login-password") } +// val loginButton = UiButton { withText("Log in") } + + // keycloak login form + val username = UiEditText { withResourceName("username") } + val password = UiEditText { withResourceName("password") } + val loginButton = UiButton { withResourceName("kc-login") } val keepAccessForeverBtn = UiButton { withText("Allow") } } From 00ea6fb7cd50dfe17ee73d703839f792074f57f5 Mon Sep 17 00:00:00 2001 From: "v.scharf" Date: Mon, 27 Apr 2026 15:39:46 +0200 Subject: [PATCH 6/6] gh artifacts --- .github/workflows/integration.yml | 8 ++++++++ .../java/eu/opencloud/android/LoginScreenTest.kt | 5 +++++ 2 files changed, 13 insertions(+) diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index 6ddc37e9a..f61bf0f84 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -47,3 +47,11 @@ jobs: java -jar adbserver-desktop.jar & sleep 3 ./gradlew :opencloudApp:connectedOriginalDebugAndroidTest -Pandroid.testInstrumentationRunnerArguments.class=eu.opencloud.android.LoginScreenTest#loginApp + adb pull /sdcard/Documents/screenshots/ opencloudApp/build/screenshots/ || true + + - name: Upload test artifacts + if: always() + uses: actions/upload-artifact@v4 + with: + name: test-artifacts + path: opencloudApp/build/screenshots/ diff --git a/opencloudApp/src/integrationTest/java/eu/opencloud/android/LoginScreenTest.kt b/opencloudApp/src/integrationTest/java/eu/opencloud/android/LoginScreenTest.kt index cafe0ac32..d614c77de 100644 --- a/opencloudApp/src/integrationTest/java/eu/opencloud/android/LoginScreenTest.kt +++ b/opencloudApp/src/integrationTest/java/eu/opencloud/android/LoginScreenTest.kt @@ -30,6 +30,11 @@ class LoginScreenTest : TestCase( @get:Rule val activityRule = ActivityScenarioRule(SplashActivity::class.java) + @get:Rule + val permissionRule: GrantPermissionRule = GrantPermissionRule.grant( + android.Manifest.permission.READ_EXTERNAL_STORAGE, + android.Manifest.permission.WRITE_EXTERNAL_STORAGE + ) @Test fun loginApp() {