Skip to content

Commit

Permalink
feat: android e2e tests
Browse files Browse the repository at this point in the history
  • Loading branch information
limpbrains committed Nov 2, 2023
1 parent 4957634 commit f8f75de
Show file tree
Hide file tree
Showing 19 changed files with 377 additions and 98 deletions.
2 changes: 1 addition & 1 deletion .detoxrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ module.exports = {
emulator: {
type: 'android.emulator',
device: {
avdName: 'Pixel_API_29_AOSP',
avdName: 'Pixel_API_31_AOSP',
},
},
},
Expand Down
183 changes: 183 additions & 0 deletions .github/workflows/e2e-android.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
name: e2e-android

on: pull_request

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

jobs:
e2e:
runs-on: macos-12

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

- name: Setup Docker Colima 1
uses: douglascamata/setup-docker-macos-action@v1-alpha
id: docker1
continue-on-error: true

- name: Setup Docker Colima 2
if: steps.docker1.outcome != 'success'
uses: douglascamata/setup-docker-macos-action@v1-alpha
id: docker2
continue-on-error: true

- name: Setup Docker Default
if: steps.docker1.outcome != 'success' && steps.docker2.outcome != 'success'
uses: docker-practice/actions-setup-docker@1.0.12
timeout-minutes: 30

# - name: Install AppleSimulatorUtils
# run: HOMEBREW_NO_AUTO_UPDATE=1 brew tap wix/brew && brew install applesimutils

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

- name: Wait for bitcoind
timeout-minutes: 2
run: while ! nc -z '127.0.0.1' 43782; do sleep 1; done

- name: Wait for electrum server
timeout-minutes: 2
run: while ! nc -z '127.0.0.1' 60001; do sleep 1; done

- name: Setup Node
uses: actions/setup-node@v3
with:
node-version: 18.17
cache: 'yarn' # cache packages, but not node_modules

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

- name: Activate react-native-skia-stub
run: patch -p1 < .github/workflows/react-native-skia-stub.patch

- name: Activate Gradle variables
run: cp .github/workflows/gradle.properties ~/.gradle/gradle.properties

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

- name: Yarn Install
run: yarn --no-audit --prefer-offline || yarn --no-audit --prefer-offline
env:
HUSKY: 0

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

- name: Test attempt 1
uses: reactivecircus/android-emulator-runner@v2
continue-on-error: true
id: test1
with:
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: |
adb root
adb reverse tcp:80 tcp:80
adb reverse tcp:8080 tcp:8080
adb reverse tcp:9735 tcp:9735
adb reverse tcp:10009 tcp:10009
adb reverse tcp:28334 tcp:28334
adb reverse tcp:28335 tcp:28335
adb reverse tcp:28336 tcp:28336
adb reverse tcp:39388 tcp:39388
adb reverse tcp:43782 tcp:43782
adb reverse tcp:60001 tcp:60001
yarn e2e:test:android-release --record-videos all --take-screenshots all --record-logs all
- name: Test attempt 2
uses: reactivecircus/android-emulator-runner@v2
continue-on-error: true
id: test2
if: steps.test1.outcome != 'success'
with:
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: |
adb root
adb reverse tcp:80 tcp:80
adb reverse tcp:8080 tcp:8080
adb reverse tcp:9735 tcp:9735
adb reverse tcp:10009 tcp:10009
adb reverse tcp:28334 tcp:28334
adb reverse tcp:28335 tcp:28335
adb reverse tcp:28336 tcp:28336
adb reverse tcp:39388 tcp:39388
adb reverse tcp:43782 tcp:43782
adb reverse tcp:60001 tcp:60001
yarn e2e:test:android-release --record-videos all --take-screenshots all --record-logs all
- name: Test attempt 3
uses: reactivecircus/android-emulator-runner@v2
continue-on-error: true
id: test3
if: steps.test1.outcome != 'success' && steps.test2.outcome != 'success'
with:
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: |
adb root
adb reverse tcp:80 tcp:80
adb reverse tcp:8080 tcp:8080
adb reverse tcp:9735 tcp:9735
adb reverse tcp:10009 tcp:10009
adb reverse tcp:28334 tcp:28334
adb reverse tcp:28335 tcp:28335
adb reverse tcp:28336 tcp:28336
adb reverse tcp:39388 tcp:39388
adb reverse tcp:43782 tcp:43782
adb reverse tcp:60001 tcp:60001
yarn e2e:test:android-release --record-videos all --take-screenshots all --record-logs all
- name: Test attempt 4
uses: reactivecircus/android-emulator-runner@v2
if: steps.test1.outcome != 'success' && steps.test2.outcome != 'success' && steps.test3.outcome != 'success'
with:
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: |
adb root
adb reverse tcp:80 tcp:80
adb reverse tcp:8080 tcp:8080
adb reverse tcp:9735 tcp:9735
adb reverse tcp:10009 tcp:10009
adb reverse tcp:28334 tcp:28334
adb reverse tcp:28335 tcp:28335
adb reverse tcp:28336 tcp:28336
adb reverse tcp:39388 tcp:39388
adb reverse tcp:43782 tcp:43782
adb reverse tcp:60001 tcp:60001
yarn e2e:test:android-release --record-videos all --take-screenshots all --record-logs all
- uses: actions/upload-artifact@v3
if: failure()
with:
name: e2e-test-videos
path: ./artifacts/

- name: Dump docker logs on failure
if: failure()
uses: jwalton/gh-docker-logs@v2
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
14 changes: 14 additions & 0 deletions android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ android {
versionName "1.0"
multiDexEnabled true
missingDimensionStrategy 'react-native-camera', 'general'
testBuildType System.getProperty('testBuildType', 'debug')
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
}

splits {
Expand Down Expand Up @@ -138,6 +140,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"
}
}

Expand All @@ -159,6 +162,9 @@ android {
}

dependencies {
androidTestImplementation('com.wix:detox:+')
implementation 'com.google.android.material:material:1.3.0' // FIXME https://github.com/wix/Detox/issues/2846
implementation 'androidx.appcompat:appcompat:1.1.0'
// 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 All @@ -180,3 +186,11 @@ dependencies {
}

apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)

// DETOX workaround
// https://github.com/wix/Detox/issues/3867#issuecomment-1540477784
configurations.all {
resolutionStrategy {
force 'androidx.test:core:1.5.0'
}
}
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 @@ -27,7 +27,8 @@
android:roundIcon="@mipmap/ic_launcher_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
7 changes: 7 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,7 @@
<?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-config>
</network-security-config>
8 changes: 7 additions & 1 deletion android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ buildscript {
minSdkVersion = 24
compileSdkVersion = 33
targetSdkVersion = 33
kotlin_version = '1.8.0'
kotlin_version = "1.8.21"
ndkVersion = "25.1.8937393"
}
repositories {
Expand All @@ -20,3 +20,9 @@ buildscript {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}

allprojects {
repositories {
maven { url("$rootDir/../node_modules/detox/Detox-android") }
}
}
11 changes: 8 additions & 3 deletions e2e/channels.e2e.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import BitcoinJsonRpc from 'bitcoin-json-rpc';
import jestExpect from 'expect';
import { device } from 'detox';

import initWaitForElectrumToSync from '../__tests__/utils/wait-for-electrum';
import {
Expand Down Expand Up @@ -126,7 +127,7 @@ d('LN Channel Onboarding', () => {
await expect(element(by.text('200 000'))).toBeVisible();

// Swipe to confirm (set x offset to avoid navigating back)
await element(by.id('GRAB')).swipe('right', 'slow', NaN, 0.8);
await element(by.id('GRAB')).swipe('right', 'slow', 0.9);
await waitFor(element(by.id('LightningSettingUp')))
.toBeVisible()
.withTimeout(10000);
Expand Down Expand Up @@ -156,7 +157,11 @@ d('LN Channel Onboarding', () => {
jestExpect(buttonEnabled2).toBe(false);

// go back and change to 2nd card
await element(by.id('NavigationBack')).atIndex(1).tap();
if (device.getPlatform() === 'ios') {
await element(by.id('NavigationBack')).atIndex(1).tap(); // ios
} else {
await element(by.id('NavigationBack')).atIndex(0).tap(); // android
}
await element(by.id('Barrel-medium')).tap();
await element(by.id('CustomSetupContinue')).tap();
await element(by.id('Barrel-medium')).tap();
Expand All @@ -178,7 +183,7 @@ d('LN Channel Onboarding', () => {
// await expect(element(by.text('1 week'))).toBeVisible();

// Swipe to confirm (set x offset to avoid navigating back)
await element(by.id('GRAB')).swipe('right', 'slow', NaN, 0.8);
await element(by.id('GRAB')).swipe('right', 'slow', 0.9);
await waitFor(element(by.id('LightningSettingUp')))
.toBeVisible()
.withTimeout(10000);
Expand Down
Loading

0 comments on commit f8f75de

Please sign in to comment.