Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
51 changes: 51 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,57 @@ jobs:
path: /github/home/go/src/github.com/BitBoxSwiss/bitbox-wallet-app/frontends/android/BitBoxApp/app/build/outputs/apk/debug/app-debug.apk
name: BitBoxApp-android-${{github.sha}}.apk
if-no-files-found: error

e2e-android:
name: Android E2E Tests
needs: android
runs-on: ubuntu-latest
strategy:
matrix:
api-level: [30, 31, 32, 33, 34, 35]
steps:
- name: Checkout repo
uses: actions/checkout@v4

- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: '20.x'

- name: Download APK
uses: actions/download-artifact@v4
with:
name: BitBoxApp-android-${{ github.sha }}.apk
path: frontends/mobiletests/apk

- name: Install dependencies
working-directory: frontends/mobiletests
run: npm ci

- name: Enable KVM group perms
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: Install Appium & drivers
run: |
npm install -g [email protected]
appium driver install uiautomator2

- name: Start Android emulator and run tests
uses: reactivecircus/android-emulator-runner@v2
env:
PLATFORM: Android
ANDROID_EMULATOR_WAIT_TIME_BEFORE_KILL: 5
with:
api-level: ${{ matrix.api-level }}
arch: x86_64
force-avd-creation: true
emulator-boot-timeout: 600
working-directory: frontends/mobiletests
emulator-options: "-no-window -no-audio -no-boot-anim -no-snapshot-load -no-snapshot-save"
script: ./run.sh
qt-linux:
runs-on: ubuntu-22.04
needs: setup-env
Expand Down
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

SHELL := /bin/bash
WEBROOT := frontends/web
MOBILETESTROOT := frontends/mobiletests

catch:
@echo "Choose a make target."
Expand Down Expand Up @@ -57,6 +58,8 @@ webserve:
cd ${WEBROOT} && $(MAKE) serve
webe2etest:
cd ${WEBROOT} && $(MAKE) test-e2e
mobilee2etest:
cd ${MOBILETESTROOT} && ./run.sh
qt-linux: # run inside dockerdev
$(MAKE) buildweb
cd frontends/qt && $(MAKE) linux
Expand Down
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,12 @@ Playwright is used to perform automatic test on some use cases on the webdev ver
Tests are located under [`frontends/web/tests`](/frontends/web/tests) and can be run with
`make webe2etest`

Appium is used to perform automatic test on Android emulators.
The test runs automatically on PRs and push to master in the Github CI.

`make mobilee2etest` can be used to launch the tests; however, when ran locally, this requires an Android emulator
to be already running. In CI, the emulator is automatically spawned from a Github Action.

#### Run the HTTP API

Run `make servewallet` to compile the code and run `servewallet`. `servewallet` is a devtool which
Expand Down
1 change: 1 addition & 0 deletions frontends/mobiletests/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/node_modules/
13 changes: 13 additions & 0 deletions frontends/mobiletests/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Mobile e2e tests

This folder contains the necessary files to setup and run tests against Android (and in the future iOS) devices.

The tests are contained in the [e2e](./e2e) directory and use [Appium](https://github.com/appium/appium) to automate execution of actions on the app.

To run the test manually, one can either run `make mobilee2etest` from the [root repo](../..) or execute [run.sh](./run.sh) directly.
The script will start an Appium server, wait for it to be ready, and then call `npm run tests` which uses the testing framework [Mocha](https://mochajs.org/).

Note that, in order for the test to start, an Android emulator must be running. The script doesn't start one as steps to do so tend to be somewhat platform-dependant. When running in CI, an emulator is automatically started through a Github Action.

## Development
To create a new test, simply add a new file called `<test-name>.test.js` to the `e2e` folder.
58 changes: 58 additions & 0 deletions frontends/mobiletests/e2e/base.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/**
* Copyright 2025 Shift Crypto AG
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { remote } from 'webdriverio';
import { expect } from 'chai';

// --- Test ---
describe('BitBoxApp Base Test', function () {
this.timeout(180000);

let driver;
before(async () => {

const opts = {
path: '/',
port: 4723,
capabilities: {
platformName: 'Android',
'appium:deviceName': 'Android Emulator',
'appium:automationName': 'UiAutomator2',
'appium:app': './apk/app-debug.apk',
}
};

driver = await remote(opts);

// Switch to WebView if present
const contexts = await driver.getContexts();
console.log('Available contexts:', contexts);
const webview = contexts.find((c) => c.startsWith('WEBVIEW_'));
if (webview) await driver.switchContext(webview);

});

after(async () => {
if (driver) await driver.deleteSession();
});

it('App main page loads', async () => {
const body = await driver.$('body');
const bodyText = await body.getText();
expect(bodyText).to.include(
'Please connect your BitBox and tap the side to continue.'
);
});
});
Loading