Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: android e2e tests #1360

Merged
merged 1 commit into from
Jun 17, 2024
Merged
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
13 changes: 10 additions & 3 deletions .detoxrc.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
// run iPhone 14 on local machine, iPhone 15 Pro on mac mini
const iOSDevice = process.env.MACMINI ? 'iPhone 15 Pro' : 'iPhone 14';

const reversePorts = [3003, 8080, 8081, 9735, 10009, 28334, 28335, 28336, 39388, 43782, 60001];

/** @type {Detox.DetoxConfig} */
module.exports = {
testRunner: {
$0: 'jest',
Expand All @@ -25,15 +28,19 @@ module.exports = {
},
'android.debug': {
type: 'android.apk',
binaryPath: 'android/app/build/outputs/apk/debug/app-debug.apk',
testBinaryPath: 'android/app/build/outputs/apk/androidTest/debug/app-debug-androidTest.apk',
binaryPath: 'android/app/build/outputs/apk/debug/app-universal-debug.apk',
build:
'cd android && ./gradlew assembleDebug assembleAndroidTest -DtestBuildType=debug && cd .. ',
reversePorts,
},
'android.release': {
type: 'android.apk',
binaryPath: 'android/app/build/outputs/apk/release/app-release.apk',
testBinaryPath: 'android/app/build/outputs/apk/androidTest/release/app-release-androidTest.apk',
binaryPath: 'android/app/build/outputs/apk/release/app-universal-release.apk',
build:
'cd android && ./gradlew assembleRelease assembleAndroidTest -DtestBuildType=release && cd ..',
reversePorts,
},
},
devices: {
Expand All @@ -46,7 +53,7 @@ module.exports = {
emulator: {
type: 'android.emulator',
device: {
avdName: 'Pixel_API_29_AOSP',
avdName: 'Pixel_API_31_AOSP',
},
},
},
Expand Down
2 changes: 1 addition & 1 deletion .env.test.template
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ BACKUPS_SERVER_PUBKEY=0319c4ff23820afec0c79ce3a42031d7fef1dff78b7bdd69b5560684f3
WEB_RELAY=https://webrelay.slashtags.to

# Blocktank
BLOCKTANK_HOST=https://api1.blocktank.to/api
BLOCKTANK_HOST=https://api.stag.blocktank.to

# Network
ELECTRUM_BITCOIN_HOST=35.187.18.233
Expand Down
192 changes: 192 additions & 0 deletions .github/workflows/e2e-android.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
name: e2e-android

on:
workflow_dispatch:
pull_request:

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

env:
E2E_TESTS: 1 # build without transform-remove-console babel plugin
DEBUG: 'lnurl* lnurl server'

jobs:
e2e:
runs-on: ubuntu-latest

steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 1

- 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: Free Disk Space
uses: jlumbroso/free-disk-space@main
with:
# this might remove tools that are actually needed,
# if set to "true" but frees about 6 GB
tool-cache: false
android: false
dotnet: true
haskell: true
large-packages: true
docker-images: true
swap-storage: true

- name: yarn and gradle caches in /mnt
run: |
rm -rf ~/.yarn
rm -rf ~/.gradle
sudo mkdir -p /mnt/.yarn
sudo mkdir -p /mnt/.gradle
sudo chown -R runner /mnt/.yarn
sudo chown -R runner /mnt/.gradle
ln -s /mnt/.yarn /home/runner/
ln -s /mnt/.gradle /home/runner/

- name: Create artifacts directory on /mnt
run: |
sudo mkdir -p /mnt/artifacts
sudo chown -R runner /mnt/artifacts

- name: Specify node version
uses: actions/setup-node@v4
with:
node-version: 20

- name: Use gradle caches
uses: actions/cache@v4
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
restore-keys: |
${{ runner.os }}-gradle-

- name: Use yarn caches
uses: actions/cache@v4
with:
path: ~/.yarn
key: ${{ runner.os }}-yarn-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-yarn-

- name: Activate enviroment variables
run: cp .env.test.template .env

- name: Yarn Install
run: yarn || yarn
env:
HUSKY: 0

- name: Activate Gradle variables
run: |
cp .github/workflows/gradle.properties ~/.gradle/gradle.properties
patch -p1 -i ./.github/workflows/react-native-quick-crypto.patch

- name: Use specific Java version for sdkmanager to work
uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: '17'

- name: Build
run: yarn e2e:build:android-release || yarn e2e:build:android-release

- name: Show build outputs
run: tree android/app/build/outputs/

- name: Kill java processes
run: pkill -9 -f java || true

- name: Run regtest setup
run: |
cd docker
mkdir lnd && chmod 777 lnd
docker-compose pull --quiet
docker compose up -d

- name: Wait for electrum server and LND
timeout-minutes: 10
run: |
while ! nc -z '127.0.0.1' 60001; do sleep 1; done
while ! nc -z '127.0.0.1' 10009; do sleep 1; done
sudo chmod -R 777 docker/lnd

- name: Test attempt 1
continue-on-error: true
id: test1
uses: reactivecircus/android-emulator-runner@v2
with:
profile: 5.4in FWVGA # devices list: avdmanager list device
api-level: 31
avd-name: Pixel_API_31_AOSP
force-avd-creation: false
emulator-options: -no-window -gpu swiftshader_indirect -no-snapshot -noaudio -no-boot-anim -camera-back none -camera-front none -partition-size 2047
arch: x86_64
script: yarn e2e:test:android-release --record-videos all --record-logs all --take-screenshots all --headless -d 200000 --artifacts-location /mnt/artifacts

- name: Test attempt 2
continue-on-error: true
id: test2
if: steps.test1.outcome != 'success'
uses: reactivecircus/android-emulator-runner@v2
with:
profile: 5.4in FWVGA # devices list: avdmanager list device
api-level: 31
avd-name: Pixel_API_31_AOSP
force-avd-creation: false
emulator-options: -no-window -gpu swiftshader_indirect -no-snapshot -noaudio -no-boot-anim -camera-back none -camera-front none -partition-size 2047
arch: x86_64
script: yarn e2e:test:android-release --record-videos all --record-logs all --take-screenshots all --headless -d 200000 --artifacts-location /mnt/artifacts

- name: Test attempt 3
continue-on-error: true
id: test3
if: steps.test1.outcome != 'success' && steps.test2.outcome != 'success'
uses: reactivecircus/android-emulator-runner@v2
with:
profile: 5.4in FWVGA # devices list: avdmanager list device
api-level: 31
avd-name: Pixel_API_31_AOSP
force-avd-creation: false
emulator-options: -no-window -gpu swiftshader_indirect -no-snapshot -noaudio -no-boot-anim -camera-back none -camera-front none -partition-size 2047
arch: x86_64
script: yarn e2e:test:android-release --record-videos all --record-logs all --take-screenshots all --headless -d 200000 --artifacts-location /mnt/artifacts

- name: Restart docker before last attempt
if: steps.test1.outcome != 'success' && steps.test2.outcome != 'success' && steps.test3.outcome != 'success'
run: |
cd docker && docker compose down -t 60 && docker compose up --quiet-pull -d && cd ..
while ! nc -z '127.0.0.1' 60001; do sleep 1; done

- name: Test attempt 4
if: steps.test1.outcome != 'success' && steps.test2.outcome != 'success' && steps.test3.outcome != 'success'
uses: reactivecircus/android-emulator-runner@v2
with:
profile: 5.4in FWVGA # devices list: avdmanager list device
api-level: 31
avd-name: Pixel_API_31_AOSP
force-avd-creation: false
emulator-options: -no-window -gpu swiftshader_indirect -no-snapshot -noaudio -no-boot-anim -camera-back none -camera-front none -partition-size 2047
arch: x86_64
script: yarn e2e:test:android-release --record-videos all --record-logs all --take-screenshots all --headless -d 200000 --artifacts-location /mnt/artifacts

- uses: actions/upload-artifact@v4
if: failure()
with:
name: e2e-test-videos
path: /mnt/artifacts/

- name: Dump docker logs on failure
if: failure()
uses: jwalton/gh-docker-logs@v2
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: e2e-ios-macmini
name: e2e-ios

on:
workflow_dispatch:
Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/gradle.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
BITKIT_UPLOAD_STORE_FILE=debug.keystore
BITKIT_UPLOAD_STORE_PASSWORD=android
BITKIT_UPLOAD_KEY_ALIAS=androiddebugkey
BITKIT_UPLOAD_KEY_PASSWORD=android
13 changes: 13 additions & 0 deletions .github/workflows/react-native-quick-crypto.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
diff --git a/node_modules/react-native-quick-crypto/android/build.gradle b/node_modules/react-native-quick-crypto/android/build.gradle
index 2ac6c0db..57afa566 100644
--- a/node_modules/react-native-quick-crypto/android/build.gradle
+++ b/node_modules/react-native-quick-crypto/android/build.gradle
@@ -94,6 +94,8 @@ android {
""
]
doNotStrip '**/*.so'
+ pickFirst 'META-INF/com.android.tools/proguard/coroutines.pro'
+ pickFirst 'META-INF/proguard/coroutines.pro'
}

buildTypes {
4 changes: 4 additions & 0 deletions android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ android {
versionName "1.0.1"
multiDexEnabled true
missingDimensionStrategy 'react-native-camera', 'general'
testBuildType System.getProperty('testBuildType', 'debug')
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
}

signingConfigs {
Expand Down Expand Up @@ -112,6 +114,7 @@ android {
signingConfig signingConfigs.release
minifyEnabled enableProguardInReleaseBuilds
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
proguardFile "${rootProject.projectDir}/../node_modules/detox/android/detox/proguard-rules-app.pro"
}
}
splits {
Expand Down Expand Up @@ -139,6 +142,7 @@ android {
}

dependencies {
androidTestImplementation('com.wix:detox:+')
// The version of react-native is set by the React Native Gradle Plugin
implementation("com.facebook.react:react-android")
implementation files("../../node_modules/@synonymdev/react-native-ldk/android/libs/LDK-release.aar")
Expand Down
29 changes: 29 additions & 0 deletions android/app/src/androidTest/java/com/bitkit/DetoxTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.bitkit;

import com.wix.detox.Detox;
import com.wix.detox.config.DetoxConfig;

import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;

import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.LargeTest;
import androidx.test.rule.ActivityTestRule;

@RunWith(AndroidJUnit4.class)
@LargeTest
public class DetoxTest {
@Rule
public ActivityTestRule<MainActivity> mActivityRule = new ActivityTestRule<>(MainActivity.class, false, false);

@Test
public void runDetoxTests() {
DetoxConfig detoxConfig = new DetoxConfig();
detoxConfig.idlePolicyConfig.masterTimeoutSec = 90;
detoxConfig.idlePolicyConfig.idleResourceTimeoutSec = 60;
detoxConfig.rnContextLoadTimeoutSec = (BuildConfig.DEBUG ? 180 : 60);

Detox.runTests(mActivityRule, detoxConfig);
}
}
3 changes: 2 additions & 1 deletion android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@
android:roundIcon="@mipmap/ic_launcher_orange_round"
android:allowBackup="false"
android:usesCleartextTraffic="true"
android:theme="@style/AppTheme">
android:theme="@style/AppTheme"
android:networkSecurityConfig="@xml/network_security_config">
<activity
android:name=".MainActivity"
android:label="@string/app_name"
Expand Down
8 changes: 8 additions & 0 deletions android/app/src/main/res/xml/network_security_config.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">10.0.2.2</domain>
<domain includeSubdomains="true">localhost</domain>
<domain includeSubdomains="true">127.0.0.1</domain>
</domain-config>
</network-security-config>
7 changes: 7 additions & 0 deletions android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ buildscript {
compileSdkVersion = 34
targetSdkVersion = 34
kotlin_version = "1.8.0"
kotlinVersion = "1.8.0"
ndkVersion = "25.2.9519653"
}
repositories {
Expand All @@ -21,3 +22,9 @@ buildscript {
}

apply plugin: "com.facebook.react.rootproject"

allprojects {
repositories {
maven { url("$rootDir/../node_modules/detox/Detox-android") }
}
}
Loading