Skip to content

Commit 126bca2

Browse files
committed
tests: enable automatic tests on Android.
1 parent 7d540b4 commit 126bca2

File tree

8 files changed

+20364
-0
lines changed

8 files changed

+20364
-0
lines changed

.github/workflows/ci.yml

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,68 @@ jobs:
7070
path: /github/home/go/src/github.com/BitBoxSwiss/bitbox-wallet-app/frontends/android/BitBoxApp/app/build/outputs/apk/debug/app-debug.apk
7171
name: BitBoxApp-android-${{github.sha}}.apk
7272
if-no-files-found: error
73+
74+
e2e-android:
75+
name: Android E2E Tests
76+
needs: android
77+
runs-on: ubuntu-latest
78+
strategy:
79+
matrix:
80+
# APIs to test are chosen as follows:
81+
# - 24 is the minimum we support (keep in sync with "minSdkVersion" in build.gradle)
82+
# - 35 is the target version (keep in sync with "targetSdkVersion" in build.gradle)
83+
# The others are only API levels that match a new Android release.
84+
# - 26: Android 8
85+
# - 28: Android 9
86+
# - 29: Android 10
87+
# - 30: Android 11
88+
# - 31: Android 12
89+
# - 33: Android 13
90+
# - 34: Android 14
91+
api-level: [24, 26, 28, 29, 30, 31, 33, 34, 35]
92+
steps:
93+
- name: Checkout repo
94+
uses: actions/checkout@v4
95+
96+
- name: Set up Node.js
97+
uses: actions/setup-node@v4
98+
with:
99+
node-version: '20'
100+
101+
- name: Download APK
102+
uses: actions/download-artifact@v4
103+
with:
104+
name: BitBoxApp-android-${{ github.sha }}.apk
105+
path: frontends/tests/apk
106+
107+
- name: Install dependencies
108+
working-directory: frontends/tests
109+
run: npm ci
110+
111+
- name: Enable KVM group perms
112+
run: |
113+
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
114+
sudo udevadm control --reload-rules
115+
sudo udevadm trigger --name-match=kvm
116+
117+
- name: Install Appium & drivers
118+
run: |
119+
npm install -g appium
120+
appium driver install uiautomator2
121+
122+
- name: Start Android emulator and run tests
123+
uses: reactivecircus/android-emulator-runner@v2
124+
env:
125+
PLATFORM: Android
126+
ANDROID_EMULATOR_WAIT_TIME_BEFORE_KILL: 5
127+
with:
128+
api-level: ${{ matrix.api-level }}
129+
arch: x86_64
130+
force-avd-creation: true
131+
emulator-boot-timeout: 600
132+
working-directory: frontends/tests
133+
emulator-options: "-no-window -no-audio -no-boot-anim -no-snapshot-load -no-snapshot-save"
134+
script: ./run.sh
73135
qt-linux:
74136
runs-on: ubuntu-22.04
75137
needs: setup-env

Makefile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
SHELL := /bin/bash
1616
WEBROOT := frontends/web
17+
MOBILETESTROOT := frontends/tests
1718

1819
catch:
1920
@echo "Choose a make target."
@@ -57,6 +58,8 @@ webserve:
5758
cd ${WEBROOT} && $(MAKE) serve
5859
webe2etest:
5960
cd ${WEBROOT} && $(MAKE) test-e2e
61+
mobilee2etest:
62+
cd ${MOBILETESTROOT} && ./run.sh
6063
qt-linux: # run inside dockerdev
6164
$(MAKE) buildweb
6265
cd frontends/qt && $(MAKE) linux

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,9 @@ Playwright is used to perform automatic test on some use cases on the webdev ver
103103
Tests are located under [`frontends/web/tests`](/frontends/web/tests) and can be run with
104104
`make webe2etest`
105105

106+
Appium is used to perform automatic test on Android emulators.
107+
The test runs automatically on PRs and push to master in the Github CI.
108+
106109
#### Run the HTTP API
107110

108111
Run `make servewallet` to compile the code and run `servewallet`. `servewallet` is a devtool which

frontends/tests/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/node_modules/

frontends/tests/e2e/base.test.js

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/**
2+
* Copyright 2025 Shift Crypto AG
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
import { remote } from 'webdriverio';
17+
import { expect } from 'chai';
18+
19+
// --- Test ---
20+
describe('BitBoxApp Base Test', function () {
21+
this.timeout(180000);
22+
23+
let driver;
24+
before(async () => {
25+
26+
const opts = {
27+
path: '/',
28+
port: 4723,
29+
capabilities: {
30+
platformName: 'Android',
31+
'appium:deviceName': 'Android Emulator',
32+
'appium:automationName': 'UiAutomator2',
33+
'appium:app': './apk/app-debug.apk',
34+
'appium:noReset': true,
35+
}
36+
};
37+
38+
driver = await remote(opts);
39+
40+
// Switch to WebView if present
41+
const contexts = await driver.getContexts();
42+
console.log('Available contexts:', contexts);
43+
const webview = contexts.find((c) => c.startsWith('WEBVIEW_'));
44+
if (webview) await driver.switchContext(webview);
45+
46+
});
47+
48+
after(async () => {
49+
if (driver) await driver.deleteSession();
50+
});
51+
52+
it('App main page loads', async () => {
53+
const body = await driver.$('body');
54+
const bodyText = await body.getText();
55+
expect(bodyText).to.include(
56+
'Please connect your BitBox and tap the side to continue.'
57+
);
58+
});
59+
});

0 commit comments

Comments
 (0)