Fix: Android build for Detox e2e (#8362)

This commit is contained in:
yasserfaraazkhan 2024-12-09 23:20:05 +05:30 committed by GitHub
parent 854d6207b0
commit 63889c03c6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 131 additions and 12 deletions

View file

@ -186,6 +186,7 @@ repositories {
maven {
url 'https://maven.google.com'
}
maven { url 'https://jitpack.io' }
}
dependencies {
@ -203,8 +204,11 @@ dependencies {
implementation 'com.google.android.material:material:1.12.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation "com.google.firebase:firebase-messaging:$firebaseVersion"
androidTestImplementation('com.wix:detox:+')
androidTestImplementation 'androidx.test:core:1.6.0'
androidTestImplementation 'androidx.test:runner:1.5.2'
androidTestImplementation 'com.wix:detox:20.26.2'
implementation project(':reactnativenotifications')
implementation project(':watermelondb-jsi')
@ -217,6 +221,7 @@ dependencies {
configurations.all {
resolutionStrategy {
force 'androidx.test:core:1.6.0'
eachDependency { DependencyResolveDetails details ->
if (details.requested.name == 'play-services-base') {
details.useTarget group: details.requested.group, name: details.requested.name, version: '18.2.0'

View file

@ -34,7 +34,7 @@ buildscript {
allprojects {
repositories {
maven {
url "$rootDir/../node_modules/detox/Detox-android"
url "$rootDir/../detox/node_modules/detox/Detox-android"
}
}
}

View file

@ -10,7 +10,7 @@
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
# Default value: -Xmx512m -XX:MaxMetaspaceSize=256m
org.gradle.jvmargs=-Xmx2048m -XX:MaxMetaspaceSize=512m
org.gradle.jvmargs=-Xmx4096m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit

35
detox/README.md Normal file
View file

@ -0,0 +1,35 @@
# How to Run Detox Tests
## Android
### Install Dependencies
From the root directory, run the following command to install the necessary dependencies:
```sh
npm install
```
### Inject Detox Settings
To inject the Detox settings into your project, navigate to the `detox` directory and run the following command:
```sh
npm run inject-detox-settings
```
### Update `minSdkVersion` for `react-native-image-picker`
On macOS machines, update the `minSdkVersion` of `react-native-image-picker` to 23 by running the following command from the root directory:
```sh
sed -i '' 's/minSdkVersion 21/minSdkVersion 23/' ./node_modules/react-native-image-picker/android/build.gradle
```
### Build detox android app
From the `detox` folder run:
```
npm run e2e:android-build
```

View file

@ -39,7 +39,7 @@ class LoginScreen {
signinButtonDisabled = element(by.id(this.testID.signinButtonDisabled));
toBeVisible = async () => {
await wait(timeouts.ONE_SEC);
await wait(timeouts.FOUR_SEC);
await waitFor(this.loginScreen).toExist().withTimeout(timeouts.TEN_SEC);
await waitFor(this.usernameInput).toBeVisible().withTimeout(timeouts.TEN_SEC);
@ -60,18 +60,25 @@ class LoginScreen {
login = async (user: any = {}) => {
await this.toBeVisible();
await this.usernameInput.typeText(`${user.newUser.email}\n`);
await this.passwordInput.typeText(`${user.newUser.password}\n`);
await this.usernameInput.tap({x: 150, y: 10});
await this.usernameInput.replaceText(user.newUser.email);
await this.passwordInput.tap();
await this.passwordInput.replaceText(user.newUser.password);
await this.signinButton.tap();
await wait(timeouts.FOUR_SEC);
};
loginAsAdmin = async (user: any = {}) => {
await this.toBeVisible();
await this.usernameInput.typeText(user.username);
await this.passwordInput.typeText(`${user.password}\n`);
await this.usernameInput.tap({x: 150, y: 10});
await wait(timeouts.ONE_SEC);
await this.usernameInput.replaceText(user.username);
await this.passwordInput.tap();
await this.passwordInput.replaceText(user.password);
await this.signinButton.tap();
await wait(timeouts.FOUR_SEC);
};
}

View file

@ -49,10 +49,9 @@ class ServerScreen {
connectToServer = async (serverUrl: string, serverDisplayName: string) => {
await this.toBeVisible();
await this.serverUrlInput.replaceText(serverUrl);
await this.serverUrlInput.tapReturnKey();
await this.serverDisplayNameInput.replaceText(serverDisplayName);
if (isAndroid()) {
await this.serverDisplayNameInput.tapReturnKey();
await this.tapConnectButton();
}
if (isIos()) {
await this.tapConnectButton();
@ -67,7 +66,7 @@ class ServerScreen {
}
}
}
await waitFor(this.usernameInput).toExist().withTimeout(timeouts.ONE_SEC);
await waitFor(this.usernameInput).toExist().withTimeout(timeouts.FOUR_SEC);
};
close = async () => {

View file

@ -0,0 +1,72 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
/* eslint-disable no-console */
const fs = require('fs');
const path = require('path');
// Paths to files
const androidManifestPath = path.resolve(
__dirname,
'../android/app/src/debug/AndroidManifest.xml',
);
const settingsGradlePath = path.resolve(__dirname, '../android/settings.gradle');
// Detox code to add to settings.gradle
const detoxSettings = `
include ':detox'
project(':detox').projectDir = new File(rootProject.projectDir, '../detox/node_modules/detox/android')
`;
// Updated AndroidManifest.xml content
const updatedManifest = `<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.mattermost.rnbeta">
<application
android:usesCleartextTraffic="true"
tools:targetApi="28"
tools:ignore="GoogleAppIndexingWarning">
<activity
android:name="androidx.test.core.app.InstrumentationActivityInvoker$BootstrapActivity"
android:exported="true"
tools:node="replace"/>
<activity
android:name="androidx.test.core.app.InstrumentationActivityInvoker$EmptyActivity"
android:exported="true"
tools:node="replace"/>
<activity
android:name="androidx.test.core.app.InstrumentationActivityInvoker$EmptyFloatingActivity"
android:exported="true"
tools:node="replace"/>
</application>
</manifest>`;
// Update AndroidManifest.xml
function updateAndroidManifest() {
try {
fs.writeFileSync(androidManifestPath, updatedManifest, 'utf-8');
console.log('AndroidManifest.xml updated successfully.');
} catch (err) {
console.error(`Failed to update AndroidManifest.xml: ${err.message}`);
}
}
// Update settings.gradle
function updateSettingsGradle() {
try {
const content = fs.readFileSync(settingsGradlePath, 'utf-8');
if (content.includes("include ':detox'")) {
console.log('Detox settings already present in settings.gradle.');
return;
}
fs.writeFileSync(settingsGradlePath, content + detoxSettings, 'utf-8');
console.log('settings.gradle updated successfully.');
} catch (err) {
console.error(`Failed to update settings.gradle: ${err.message}`);
}
}
// Run updates
updateAndroidManifest();
updateSettingsGradle();

View file

@ -42,6 +42,7 @@
"xml2js": "0.6.2"
},
"scripts": {
"e2e:android-inject-settings": "node inject-detox-settings.js",
"e2e:android-create-emulator": "./create_android_emulator.sh",
"e2e:android-build": "detox build -c android.emu.debug",
"e2e:android-test": "detox test -c android.emu.debug",