Skip to content

Commit

Permalink
ci: use detox for ui test, opt code
Browse files Browse the repository at this point in the history
  • Loading branch information
JimmyDaddy committed Dec 12, 2023
1 parent 9c673c2 commit 95b6648
Show file tree
Hide file tree
Showing 28 changed files with 1,762 additions and 1,042 deletions.
9 changes: 6 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Build and Test
name: CI
on:
pull_request:
types: [opened, synchronize, reopened]
Expand Down Expand Up @@ -74,7 +74,8 @@ jobs:
assets/**
package.json
!example/ios/**
example/e2e/**
- uses: actions/cache@v3
name: Cache node_modules
if: steps.verify-android-changed-files.outputs.files_changed == 'true'
Expand Down Expand Up @@ -143,7 +144,7 @@ jobs:
name: app-release-${{ github.sha }}.apk
path: ${{ github.workspace }}/example/android/app-release-${{ github.sha }}.apk

android-test:
android-api-level-test:
runs-on: macos-latest
needs: android-build
name: Android Test
Expand All @@ -165,6 +166,7 @@ jobs:
assets/**
package.json
!example/ios/**
example/e2e/**
- uses: actions/cache@v3
name: Cache node_modules
Expand Down Expand Up @@ -247,6 +249,7 @@ jobs:
assets/**
package.json
!example/android/**
example/e2e/**
- uses: actions/cache@v3
name: Cache node_modules
Expand Down
4 changes: 2 additions & 2 deletions README.MD
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
[![stars](https://img.shields.io/github/stars/jimmydaddy/react-native-image-marker?style=social)](https://github.com/JimmyDaddy/react-native-image-marker) [![forks](https://img.shields.io/github/forks/jimmydaddy/react-native-image-marker?style=social)](https://github.com/JimmyDaddy/react-native-image-marker/fork)
[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?logo=github)](https://github.com/JimmyDaddy/react-native-image-marker/pulls) ![license](https://img.shields.io/npm/l/react-native-image-marker)
[![github](https://img.shields.io/badge/github-repo-blue?logo=github)](https://github.com/JimmyDaddy/react-native-image-marker)
[![Native Build and Test](https://github.com/JimmyDaddy/react-native-image-marker/actions/workflows/native-ci.yml/badge.svg)](https://github.com/JimmyDaddy/react-native-image-marker/actions/workflows/native-ci.yml)
![platform-iOS](https://img.shields.io/badge/iOS-black?logo=Apple) ![platform-Android](https://img.shields.io/badge/Android-black?logo=Android)
[![CI](https://github.com/JimmyDaddy/react-native-image-marker/actions/workflows/ci.yml/badge.svg)](https://github.com/JimmyDaddy/react-native-image-marker/actions/workflows/ci.yml)
![platform-iOS](https://img.shields.io/badge/iOS-black?logo=Apple) ![platform-Android](https://img.shields.io/badge/Android-black?logo=Android)
<br/>

</div>
Expand Down
83 changes: 83 additions & 0 deletions example/.detoxrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/** @type {Detox.DetoxConfig} */
module.exports = {
testRunner: {
args: {
'$0': 'jest',
config: 'e2e/jest.config.js'
},
jest: {
setupTimeout: 120000
}
},
apps: {
'ios.debug': {
type: 'ios.app',
binaryPath: 'ios/build/Build/Products/Debug-iphonesimulator/ImageMarkerExample.app',
build: 'xcodebuild -workspace ios/ImageMarkerExample.xcworkspace -scheme ImageMarkerExample -configuration Debug -sdk iphonesimulator -derivedDataPath ios/build'
},
'ios.release': {
type: 'ios.app',
binaryPath: 'ios/build/Build/Products/Release-iphonesimulator/ImageMarkerExample.app',
build: 'xcodebuild -workspace ios/ImageMarkerExample.xcworkspace -scheme ImageMarkerExample -configuration Release -sdk iphonesimulator -derivedDataPath ios/build'
},
'android.debug': {
type: 'android.apk',
binaryPath: 'android/app/build/outputs/apk/debug/app-debug.apk',
build: 'cd android && ./gradlew assembleDebug assembleAndroidTest -DtestBuildType=debug',
reversePorts: [
8081
]
},
'android.release': {
type: 'android.apk',
binaryPath: 'android/app/build/outputs/apk/release/app-release.apk',
build: 'cd android && ./gradlew assembleRelease assembleAndroidTest -DtestBuildType=release'
}
},
devices: {
simulator: {
type: 'ios.simulator',
device: {
type: 'iPhone 15'
}
},
attached: {
type: 'android.attached',
device: {
adbName: '.*'
}
},
emulator: {
type: 'android.emulator',
device: {
avdName: 'Pixel_XL_API_34'
}
}
},
configurations: {
'ios.sim.debug': {
device: 'simulator',
app: 'ios.debug'
},
'ios.sim.release': {
device: 'simulator',
app: 'ios.release'
},
'android.att.debug': {
device: 'attached',
app: 'android.debug'
},
'android.att.release': {
device: 'attached',
app: 'android.release'
},
'android.emu.debug': {
device: 'emulator',
app: 'android.debug'
},
'android.emu.release': {
device: 'emulator',
app: 'android.release'
}
}
};
7 changes: 7 additions & 0 deletions example/android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@ android {
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 1
versionName "1.0"
testBuildType System.getProperty('testBuildType', 'debug')
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
}

splits {
Expand Down Expand Up @@ -134,6 +136,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 Down Expand Up @@ -174,6 +177,10 @@ dependencies {
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
androidTestImplementation('com.wix:detox:+')
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation project(':react-native-vector-icons')
}

apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)
apply from: file("../../node_modules/react-native-vector-icons/fonts.gradle")
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.imagemarkerexample;

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 // (2)
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);
}
}
2 changes: 2 additions & 0 deletions example/android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
android:icon="@mipmap/ic_launcher"
android:roundIcon="@mipmap/ic_launcher_round"
android:allowBackup="false"
android:networkSecurityConfig="@xml/network_security_config"
android:usesCleartextTraffic="true"
android:theme="@style/AppTheme">
<activity
android:name=".MainActivity"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import com.facebook.react.defaults.DefaultReactNativeHost;
import com.facebook.soloader.SoLoader;
import java.util.List;
import com.oblador.vectoricons.VectorIconsPackage;

public class MainApplication extends Application implements ReactApplication {

Expand All @@ -25,6 +26,7 @@ protected List<ReactPackage> getPackages() {
List<ReactPackage> packages = new PackageList(this).getPackages();
// Packages that cannot be autolinked yet can be added manually here, for example:
// packages.add(new MyReactNativePackage());
packages.add(new VectorIconsPackage());
return packages;
}

Expand Down
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>
24 changes: 23 additions & 1 deletion example/android/build.gradle
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.


buildscript {
ext {
def kotlin_version = project.properties["ImageMarkerExample_kotlinVersion"]
ext {
buildToolsVersion = "33.0.0"
minSdkVersion = 24
compileSdkVersion = 33
targetSdkVersion = 33

// We use NDK 23 which has both M1 support and is the side-by-side NDK version from AGP.
ndkVersion = "23.1.7779620"
kotlinVersion = "$kotlin_version"
}
repositories {
google()
Expand All @@ -18,9 +21,28 @@ buildscript {
maven { url "https://repository.jboss.org/maven2" }
maven { url 'https://maven.google.com' }
maven { url 'https://maven.fabric.io/public' }
maven {
url("$rootDir/../node_modules/detox/Detox-android")
}
}
dependencies {
classpath('com.android.tools.build:gradle:7.4.2')
classpath("com.facebook.react:react-native-gradle-plugin")
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion")
}
}

allprojects {
repositories {
google()
mavenCentral()
jcenter()
maven { url 'https://dl.google.com/dl/android/maven2' }
maven { url "https://repository.jboss.org/maven2" }
maven { url 'https://maven.google.com' }
maven { url 'https://maven.fabric.io/public' }
maven {
url("$rootDir/../node_modules/detox/Detox-android")
}
}
}
3 changes: 3 additions & 0 deletions example/android/gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,6 @@ newArchEnabled=false
# Use this property to enable or disable the Hermes JS engine.
# If set to false, you will be using JSC instead.
hermesEnabled=true

ImageMarkerExample_kotlinVersion=1.7.0

2 changes: 2 additions & 0 deletions example/android/settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@ rootProject.name = 'ImageMarkerExample'
apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings)
include ':app'
includeBuild('../node_modules/react-native-gradle-plugin')
include ':react-native-vector-icons'
project(':react-native-vector-icons').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-vector-icons/android')
5 changes: 5 additions & 0 deletions example/babel.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,9 @@ module.exports = {
},
],
],
env: {
production: {
plugins: ['react-native-paper/babel'],
},
},
};
90 changes: 90 additions & 0 deletions example/e2e/App.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import { device, element, by, waitFor } from 'detox';
import assert from 'power-assert';

describe('e2e/App.test.js', () => {
beforeAll(async () => {
await device.launchApp();
});

beforeEach(async () => {
await device.reloadReactNative();
});

it('should display correctly', async () => {
await expect(element(by.id('backgroundImageFormatLabel'))).toBeVisible();
await expect(element(by.id('backgroundImageFormatLabel'))).toHaveText(
'background image format:'
);

await expect(element(by.id('backgroundImageFormatBtn'))).toBeVisible();
await expect(element(by.id('backgroundImageFormatBtn'))).toHaveLabel(
'image'
);

await expect(element(by.id('watermarkTypeLabel'))).toBeVisible();
await expect(element(by.id('watermarkTypeLabel'))).toHaveText(
'watermark type:'
);

await expect(element(by.id('watermarkTypeBtn'))).toBeVisible();
await expect(element(by.id('watermarkTypeBtn'))).toHaveLabel('text');

await expect(element(by.id('exportResultFormatLabel'))).toBeVisible();
await expect(element(by.id('exportResultFormatLabel'))).toHaveText(
'export result format:'
);

await expect(element(by.id('exportResultFormatBtn'))).toBeVisible();
await expect(element(by.id('exportResultFormatBtn'))).toHaveLabel('png');

await expect(element(by.id('selectBgBtn'))).toBeVisible();
await expect(element(by.id('selectBgBtn'))).toHaveLabel('select bg');

// await expect(element(by.id('selectWatermarkBtn'))).toBeVisible();
// await expect(element(by.id('selectWatermarkBtn'))).toHaveLabel(
// 'select watermark'
// );

await expect(element(by.id('resultFileSizeLabel'))).toBeVisible();
await expect(element(by.id('resultFilePathLabel'))).toBeVisible();
if (device.getPlatform() === 'ios') {
const resultFileSizeLabel = await element(
by.id('resultFileSizeLabel')
).getAttributes('text');

assert.ok(
/^result file size:\d+(.\d+)?\s(KB|MB)$/.test(resultFileSizeLabel.text)
);
const resultFilePathLabel = await element(
by.id('resultFilePathLabel')
).getAttributes('text');
assert.ok(/^file path:.*\.png$/.test(resultFilePathLabel.text));
} else {
await expect(element(by.id('resultFileSizeLabel'))).toHaveLabel(
/^result file size:\d+(\.\d+)?\s(KB|MB)$/
);
await expect(element(by.id('resultFilePathLabel'))).toBeVisible();
await expect(element(by.id('resultFilePathLabel'))).toHaveText(
/^file path:.*\.png$/
);
}

await expect(element(by.id('resultImage'))).toBeVisible();
});

describe('when click backgroundImageFormatBtn', () => {
it('should display correctly', async () => {
await expect(element(by.id('backgroundImageFormatBtn'))).toHaveLabel(
'image'
);
await element(by.id('backgroundImageFormatBtn')).tap();
await waitFor(element(by.type('RCTModalHostView')))
.toBeVisible()
.withTimeout(2000);
await element(by.label('base64')).tap();
await expect(element(by.id('backgroundImageFormatBtn'))).toHaveLabel(
'base64'
);
});
});
});
Loading

0 comments on commit 95b6648

Please sign in to comment.