Skip to content

Commit

Permalink
ci: Enable Detox E2E in Release mode (#11710)
Browse files Browse the repository at this point in the history
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**

This PR enhances our end-to-end testing setup by enabling Detox to run
on release builds. This change ensures that our tests are running in a
production-like environment, which will help uncover issues that may not
be visible in debug builds.
There is a noticeable performance difference while building the app in
release mode. The apps in release mode take ~12 minutes to build
compared to debug mode, where it takes ~17 minutes to build.


See release mode build times
<img width="998" alt="Screenshot 2024-10-10 at 5 20 27 PM"
src="https://github.com/user-attachments/assets/7476fe30-a573-4342-8be4-330437621ac7">



See debug mode build times:
<img width="1026" alt="Screenshot 2024-10-10 at 5 07 08 PM"
src="https://github.com/user-attachments/assets/11c72cb9-e27a-40a4-97c4-84ffcf9f1ee6">




Key Changes:
- Updated build scripts to differentiate between release scripts and
debug scripts
- Updated the Detox configuration to build the app in release mode while
running on CI.
-  Updated NFT tests to remove redundant steps
- The Importing NFTs e2e tests were crashing only in release mode on
iOS. The assets team will investigate and address in a follow up PR


## **Related issues**

Fixes:

## **Manual testing steps**

1. Go to this page...
2.
3.

## **Screenshots/Recordings**

<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->

### **Before**

<!-- [screenshots/recordings] -->

### **After**

Smoke runs:
-
https://app.bitrise.io/app/be69d4368ee7e86d/pipelines/af0893da-2466-4a32-b6f4-4d0056f7be81
-
https://app.bitrise.io/app/be69d4368ee7e86d/pipelines/f3ef024d-c0fe-4b58-a601-bd66c0023de0

Regression runs:

-
https://app.bitrise.io/app/be69d4368ee7e86d/pipelines/c1214e8a-86a2-4e20-972b-6247af5bac8a
-
https://app.bitrise.io/app/be69d4368ee7e86d/pipelines/53db98a1-bcfe-4dc4-91b3-20491d1171fd

## **Pre-merge author checklist**

- [ ] I’ve followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [ ] I've completed the PR template to the best of my ability
- [ ] I’ve included tests if applicable
- [ ] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] I’ve applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.

---------

Co-authored-by: Cal-L <[email protected]>
  • Loading branch information
cortisiko and Cal-L authored Oct 14, 2024
1 parent 4f8f66c commit d5c3dc0
Show file tree
Hide file tree
Showing 11 changed files with 73 additions and 103 deletions.
1 change: 0 additions & 1 deletion .depcheckrc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
ignores:
- '@metamask/oss-attribution-generator'
- 'webpack-cli'
- '@react-native-community/datetimepicker'
- '@react-native-community/slider'
- 'patch-package'
- '@lavamoat/allow-scripts'
Expand Down
28 changes: 8 additions & 20 deletions .detoxrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ module.exports = {
configurations: {
'ios.sim.apiSpecs': {
device: 'ios.simulator',
app: 'ios.debug',
app: 'ios.qa',
testRunner: {
args: {
"$0": "node e2e/api-specs/run-api-spec-tests.js",
Expand All @@ -41,10 +41,9 @@ module.exports = {
device: 'ios.simulator',
app: 'ios.release',
},
// because e2e run on debug mode in bitrise
'android.emu.bitrise.debug': {
device: 'android.bitrise.emulator',
app: 'android.bitrise.debug',
'ios.sim.qa': {
device: 'ios.simulator',
app: 'ios.qa',
},

'android.emu.debug': {
Expand Down Expand Up @@ -86,32 +85,21 @@ module.exports = {
binaryPath: 'ios/build/Build/Products/Debug-iphonesimulator/MetaMask.app',
build: 'yarn start:ios:e2e',
},
'ios.release': {
'ios.qa': {
type: 'ios.app',
binaryPath:
'ios/build/Build/Products/Release-iphonesimulator/MetaMask.app',
build: "METAMASK_BUILD_TYPE='main' METAMASK_ENVIRONMENT='production' yarn build:ios:release:e2e",
},
'android.bitrise.debug': {
type: 'android.apk',
binaryPath: 'android/app/build/outputs/apk/prod/debug/app-prod-debug.apk',
build: 'yarn start:android:e2e',
'ios/build/Build/Products/Release-iphonesimulator/MetaMask-QA.app',
build: "METAMASK_BUILD_TYPE='main' METAMASK_ENVIRONMENT='qa' yarn build:ios:qa",
},
'android.debug': {
type: 'android.apk',
binaryPath: 'android/app/build/outputs/apk/prod/debug/app-prod-debug.apk',
build: 'yarn start:android:e2e',
},
'android.release': {
type: 'android.apk',
binaryPath:
'android/app/build/outputs/apk/prod/release/app-prod-release.apk',
build: "METAMASK_BUILD_TYPE='main' METAMASK_ENVIRONMENT='production' yarn build:android:release:e2e",
},
'android.qa': {
type: 'android.apk',
binaryPath: 'android/app/build/outputs/apk/qa/release/app-qa-release.apk',
build: "METAMASK_BUILD_TYPE='main' METAMASK_ENVIRONMENT='qa' yarn build:android:qa:e2e",
build: "METAMASK_BUILD_TYPE='main' METAMASK_ENVIRONMENT='qa' yarn build:android:qa",
},
},
};
2 changes: 1 addition & 1 deletion android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ android {
release {
manifestPlaceholders.isDebug = false
minifyEnabled enableProguardInReleaseBuilds
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro", "${rootProject.projectDir}/../node_modules/detox/android/detox/proguard-rules-app.pro", "${rootProject.projectDir}/../node_modules/detox/android/detox/proguard-rules.pro"
}
}

Expand Down
53 changes: 39 additions & 14 deletions bitrise.yml
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ stages:
- run_ios_api_specs: {}
- run_tag_smoke_accounts_ios: {}
- run_tag_smoke_accounts_android: {}
- run_tag_smoke_assets_ios: {}
# - run_tag_smoke_assets_ios: {}
- run_tag_smoke_assets_android: {}
- run_tag_smoke_confirmations_ios: {}
- run_tag_smoke_confirmations_android: {}
Expand All @@ -145,8 +145,8 @@ stages:
- run_tag_smoke_core_android: {}
build_regression_e2e_ios_android_stage:
workflows:
- ios_build_regression_tests: {}
- android_build_regression_tests: {}
- ios_e2e_build: {}
- android_e2e_build: {}
run_regression_e2e_ios_android_stage:
workflows:
- ios_run_regression_tests: {}
Expand Down Expand Up @@ -267,8 +267,29 @@ workflows:
source "${HOME}/.nvm/nvm.sh"
echo 'source "${HOME}/.nvm/nvm.sh"' | tee -a ${HOME}/.{bashrc,profile}
nvm install ${NODE_VERSION}
# Retry logic for Node installation
MAX_ATTEMPTS=3
ATTEMPT=1
until [ $ATTEMPT -gt $MAX_ATTEMPTS ]
do
echo "Attempt $ATTEMPT to install Node.js"
nvm install ${NODE_VERSION}
INSTALL_STATUS=$? # Capture the exit status of the nvm install command
if [ $INSTALL_STATUS -eq 0 ]; then
echo "Node.js installation successful!"
break
else
echo "Node.js installation failed with exit code $INSTALL_STATUS"
ATTEMPT=$((ATTEMPT+1))
echo "Node.js installation failed, retrying in 5 seconds..."
sleep 5
fi
done
if [ $ATTEMPT -gt $MAX_ATTEMPTS ]; then
echo "Node.js installation failed after $MAX_ATTEMPTS attempts."
exit 1
fi
envman add --key PATH --value $PATH
node --version
Expand Down Expand Up @@ -586,6 +607,10 @@ workflows:
inputs:
- ndk_version: $NDK_VERSION
- gradlew_path: $PROJECT_LOCATION/gradlew
- file-downloader@1:
inputs:
- source: $BITRISEIO_ANDROID_QA_KEYSTORE_URL
- destination: android/keystores/internalRelease.keystore
- script@1:
title: Install CCache & symlink
inputs:
Expand Down Expand Up @@ -620,7 +645,7 @@ workflows:
node -v
export METAMASK_ENVIRONMENT='local'
export METAMASK_BUILD_TYPE='main'
IGNORE_BOXLOGS_DEVELOPMENT="true" FORCE_BUNDLING=true yarn test:e2e:android:bitrise:build
IGNORE_BOXLOGS_DEVELOPMENT="true" yarn test:e2e:android:build:qa-release
- save-gradle-cache@1: {}
- save-cache@1:
title: Save CCache
Expand Down Expand Up @@ -700,7 +725,7 @@ workflows:
fi
export METAMASK_ENVIRONMENT='local'
export METAMASK_BUILD_TYPE='main'
IGNORE_BOXLOGS_DEVELOPMENT="true" FORCE_BUNDLING=true yarn test:e2e:android:bitrise:run "$TEST_SUITE_FOLDER" --testNamePattern="$TEST_SUITE"
IGNORE_BOXLOGS_DEVELOPMENT="true" yarn test:e2e:android:run:qa-release "$TEST_SUITE_FOLDER" --testNamePattern="$TEST_SUITE"
- custom-test-results-export@1:
title: Export test results
is_always_run: true
Expand Down Expand Up @@ -802,6 +827,8 @@ workflows:
- deploy_path: $BITRISE_HTML_REPORT_DIR
title: Deploy test report files
ios_e2e_build:
envs:
- NO_FLIPPER: '1'
before_run:
- install_applesimutils
- code_setup
Expand Down Expand Up @@ -833,7 +860,7 @@ workflows:
inputs:
- content: |-
#!/usr/bin/env bash
HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1 brew install ccache
brew install ccache with HOMEBREW_NO_DEPENDENTS_CHECK=1
ln -s $(which ccache) /usr/local/bin/gcc
ln -s $(which ccache) /usr/local/bin/g++
ln -s $(which ccache) /usr/local/bin/cc
Expand Down Expand Up @@ -867,7 +894,7 @@ workflows:
node -v
export METAMASK_ENVIRONMENT='local'
export METAMASK_BUILD_TYPE='main'
IGNORE_BOXLOGS_DEVELOPMENT="true" FORCE_BUNDLING=true yarn test:e2e:ios:debug:build
IGNORE_BOXLOGS_DEVELOPMENT="true" yarn test:e2e:ios:build:qa-release
- save-cocoapods-cache@1: {}
- save-cache@1:
title: Save CCache
Expand All @@ -888,6 +915,8 @@ workflows:
- key: node_modules-{{ .OS }}-{{ .Arch }}-{{ getenv "BRANCH_COMMIT_HASH" }}
- paths: node_modules
ios_e2e_test:
envs:
- NO_FLIPPER: '1'
before_run:
- setup
- install_applesimutils
Expand Down Expand Up @@ -923,7 +952,7 @@ workflows:
- set-xcode-build-number@1:
inputs:
- build_short_version_string: $VERSION_NAME
- plist_path: $PROJECT_LOCATION_IOS/MetaMask/Info.plist
- plist_path: $PROJECT_LOCATION_IOS/MetaMask/MetaMask-QA-Info.plist
- script:
inputs:
- content: |-
Expand Down Expand Up @@ -954,7 +983,7 @@ workflows:
node -v
export METAMASK_ENVIRONMENT='local'
export METAMASK_BUILD_TYPE='main'
IGNORE_BOXLOGS_DEVELOPMENT="true" FORCE_BUNDLING=true yarn test:e2e:ios:debug:run "$TEST_SUITE_FOLDER" --testNamePattern="$TEST_SUITE"
IGNORE_BOXLOGS_DEVELOPMENT="true" yarn test:e2e:ios:run:qa-release "$TEST_SUITE_FOLDER" --testNamePattern="$TEST_SUITE"
- custom-test-results-export@1:
is_always_run: true
is_skippable: false
Expand Down Expand Up @@ -1234,8 +1263,6 @@ workflows:
inputs:
- ipa_path: $BITRISE_APP_STORE_IPA_PATH
build_ios_release:
envs:
- NO_FLIPPER: '1'
before_run:
- code_setup
after_run:
Expand Down Expand Up @@ -1275,8 +1302,6 @@ workflows:
- deploy_path: sourcemaps/ios/index.js.map
title: Deploy Source Map
build_ios_qa:
envs:
- NO_FLIPPER: '1'
before_run:
- code_setup
after_run:
Expand Down
17 changes: 1 addition & 16 deletions e2e/specs/assets/nft-detection-modal.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,10 @@ import TestHelpers from '../../helpers';
import Assertions from '../../utils/Assertions';
import NftDetectionModal from '../../pages/modals/NftDetectionModal';
import { SmokeAssets } from '../../tags';
import NetworkListModal from '../../pages/modals/NetworkListModal';
import NetworkEducationModal from '../../pages/modals/NetworkEducationModal';

import { NftDetectionModalSelectorsText } from '../../selectors/Modals/NftDetectionModal.selectors';

describe(SmokeAssets('NFT Detection Modal'), () => {
const ETHEREUM = 'Ethereum Main Network';
beforeAll(async () => {
jest.setTimeout(170000);
await TestHelpers.reverseServerPort();
Expand All @@ -25,7 +23,6 @@ describe(SmokeAssets('NFT Detection Modal'), () => {
await withFixtures(
{
fixture: new FixtureBuilder()
.withGanacheNetwork()
.withPreferencesController({
useNftDetection: false,
})
Expand All @@ -35,12 +32,6 @@ describe(SmokeAssets('NFT Detection Modal'), () => {
},
async () => {
await loginToApp();

// Switch to Mainnet
await WalletView.tapNetworksButtonOnNavBar();
await NetworkListModal.changeNetworkTo(ETHEREUM);
await NetworkEducationModal.tapGotItButton();

await Assertions.checkIfVisible(NftDetectionModal.container);

// fix flaky test: toast should desapear to get access to cancel button
Expand All @@ -65,7 +56,6 @@ describe(SmokeAssets('NFT Detection Modal'), () => {
await withFixtures(
{
fixture: new FixtureBuilder()
.withGanacheNetwork()
.withPreferencesController({
useNftDetection: false,
})
Expand All @@ -76,11 +66,6 @@ describe(SmokeAssets('NFT Detection Modal'), () => {
async () => {
await loginToApp();

// Switch to Mainnet
await WalletView.tapNetworksButtonOnNavBar();
await NetworkListModal.changeNetworkTo(ETHEREUM);
await NetworkEducationModal.tapGotItButton();

await Assertions.checkIfVisible(NftDetectionModal.container);
await NftDetectionModal.tapAllowButton();
// Check that we are on the wallet screen
Expand Down
2 changes: 1 addition & 1 deletion ios/Podfile
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ def common_target_logic
pod 'GzipSwift'

# Pod for fixing react-native-quick-crypto issue: https://github.com/margelo/react-native-quick-crypto/issues/244
pod "OpenSSL-Universal", "= 1.1.1100"
pod 'OpenSSL-Universal', :modular_headers => true, :configurations => ['Release']
end

target 'MetaMask' do
Expand Down
9 changes: 2 additions & 7 deletions ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -702,8 +702,6 @@ PODS:
- React-Core
- RNCPicker (2.2.1):
- React-Core
- RNDateTimePicker (7.7.0):
- React-Core
- RNDefaultPreference (1.4.3):
- React
- RNDeviceInfo (9.0.2):
Expand Down Expand Up @@ -825,6 +823,7 @@ DEPENDENCIES:
- GzipSwift
- lottie-ios (from `../node_modules/lottie-ios`)
- lottie-react-native (from `../node_modules/lottie-react-native`)
- OpenSSL-Universal
- OpenSSL-Universal (= 1.1.1100)
- Permission-BluetoothPeripheral (from `../node_modules/react-native-permissions/ios/BluetoothPeripheral`)
- RCT-Folly (from `../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec`)
Expand Down Expand Up @@ -897,7 +896,6 @@ DEPENDENCIES:
- "RNCClipboard (from `../node_modules/@react-native-clipboard/clipboard`)"
- "RNCMaskedView (from `../node_modules/@react-native-masked-view/masked-view`)"
- "RNCPicker (from `../node_modules/@react-native-picker/picker`)"
- "RNDateTimePicker (from `../node_modules/@react-native-community/datetimepicker`)"
- RNDefaultPreference (from `../node_modules/react-native-default-preference`)
- RNDeviceInfo (from `../node_modules/react-native-device-info`)
- "RNFBApp (from `../node_modules/@react-native-firebase/app`)"
Expand Down Expand Up @@ -1115,8 +1113,6 @@ EXTERNAL SOURCES:
:path: "../node_modules/@react-native-masked-view/masked-view"
RNCPicker:
:path: "../node_modules/@react-native-picker/picker"
RNDateTimePicker:
:path: "../node_modules/@react-native-community/datetimepicker"
RNDefaultPreference:
:path: "../node_modules/react-native-default-preference"
RNDeviceInfo:
Expand Down Expand Up @@ -1274,7 +1270,6 @@ SPEC CHECKSUMS:
RNCClipboard: ddd4d291537f1667209c9c405aaa4307297e252e
RNCMaskedView: 090213d32d8b3bb83a4dcb7d12c18f0152591906
RNCPicker: cb57c823d5ce8d2d0b5dfb45ad97b737260dc59e
RNDateTimePicker: 4f3c4dbd4f908be32ec8c93f086e8924bd4a2e07
RNDefaultPreference: 2f8d6d54230edbd78708ada8d63bb275e5a8415b
RNDeviceInfo: 1e3f62b9ec32f7754fac60bd06b8f8a27124e7f0
RNFBApp: 5f87753a8d8b37d229adf85cd0ff37709ffdf008
Expand Down Expand Up @@ -1302,6 +1297,6 @@ SPEC CHECKSUMS:
Yoga: 6f5ab94cd8b1ecd04b6e973d0bc583ede2a598cc
YogaKit: f782866e155069a2cca2517aafea43200b01fd5a

PODFILE CHECKSUM: 876298d4a106643492005466f7a314cd08711f4d
PODFILE CHECKSUM: e0bcc4eb12d48746028cd4f4161a292fa9ddc627

COCOAPODS: 1.15.2
19 changes: 7 additions & 12 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,6 @@
"start:android:flask": "export METAMASK_BUILD_TYPE='flask' && ./scripts/build.sh android flaskDebug",
"build:announce": "node ./scripts/metamask-bot-build-announce-bitrise.js",
"build:android:release": "./scripts/build.sh android release",
"build:android:release:e2e": "./scripts/build.sh android releaseE2E",
"build:android:qa:e2e": "./scripts/build.sh android QAE2E",
"build:android:checksum": "./scripts/checksum.sh",
"build:android:checksum:qa": "./scripts/checksum.sh QA",
"build:android:checksum:flask": "export METAMASK_BUILD_TYPE='flask' && ./scripts/checksum.sh flask",
Expand All @@ -44,28 +42,26 @@
"build:android:pre-release:bundle:flask": "export METAMASK_BUILD_TYPE='flask' && GENERATE_BUNDLE=true ./scripts/build.sh android flask --pre",
"build:ios:release": "./scripts/build.sh ios release",
"build:ios:pre-flask": "export METAMASK_BUILD_TYPE='flask' && ./scripts/build.sh ios flask --pre",
"build:ios:release:e2e": "./scripts/build.sh ios releaseE2E",
"build:ios:pre-release": "./scripts/build.sh ios release --pre",
"build:ios:qa": "./scripts/build.sh ios QA",
"build:ios:pre-qa": "./scripts/build.sh ios QA --pre",
"build:android:qa": "NO_FLIPPER='1' ./scripts/build.sh android QA",
"build:ios:qa": "NO_FLIPPER='1' ./scripts/build.sh ios QA",
"build:attribution": "./scripts/generate-attributions.sh",
"release:android": "./scripts/build.sh android release && open android/app/build/outputs/apk/release/",
"release:ios": "./scripts/build.sh ios release",
"release:android:qa": "./scripts/build.sh android QA && open android/app/build/outputs/apk/release/",
"test": "yarn test:unit && yarn test:e2e",
"test": "yarn test:unit",
"test:unit": "jest ./app/ ./locales/",
"test:unit:update": "time jest -u ./app/",
"test:api-specs": "detox reset-lock-file && detox test -c ios.sim.apiSpecs",
"test:e2e": "yarn test:e2e:ios && yarn test:e2e:android",
"test:e2e:ios": "detox build -c ios.sim.release && detox test -c ios.sim.release",
"test:e2e:ios:build:qa-release": "IS_TEST='true' detox build -c ios.sim.qa",
"test:e2e:ios:run:qa-release": "IS_TEST='true' detox test -c ios.sim.qa",
"test:e2e:android:build:qa-release": "NO_FLIPPER='1' IS_TEST='true' detox build -c android.emu.release.qa",
"test:e2e:android:run:qa-release": "NO_FLIPPER='1' IS_TEST='true' detox test -c android.emu.release.qa --headless --record-logs all",
"test:e2e:ios:debug:build": "IS_TEST='true' detox build -c ios.sim.debug",
"test:e2e:ios:debug:run": "IS_TEST='true' detox reset-lock-file && detox test -c ios.sim.debug",
"test:e2e:android:debug:build": "IS_TEST='true' detox build -c android.emu.debug",
"test:e2e:android:bitrise:build": "IS_TEST='true' detox build -c android.emu.bitrise.debug",
"test:e2e:android:debug:run": "IS_TEST='true' detox test -c android.emu.debug",
"test:e2e:android:bitrise:run": "IS_TEST='true' detox reset-lock-file && detox test -c android.emu.bitrise.debug --headless",
"test:e2e:android": "detox build -c android.emu.release && detox test -c android.emu.release --record-videos failing",
"test:e2e:android:qa": "detox build -c android.emu.release.qa && detox test -c android.emu.release.qa --record-videos failing",
"test:wdio:ios": "yarn wdio ./wdio/config/ios.config.debug.js",
"test:wdio:ios:browserstack:local": "yarn wdio ./wdio/config/ios.config.browserstack.local.js",
"test:wdio:android": "yarn wdio ./wdio/config/android.config.debug.js",
Expand Down Expand Up @@ -197,7 +193,6 @@
"@react-native-clipboard/clipboard": "1.8.4",
"@react-native-community/blur": "^4.4.0",
"@react-native-community/checkbox": "^0.5.17",
"@react-native-community/datetimepicker": "^7.5.0",
"@react-native-community/netinfo": "^9.5.0",
"@react-native-community/slider": "^4.4.3",
"@react-native-cookies/cookies": "^6.2.1",
Expand Down
Loading

0 comments on commit d5c3dc0

Please sign in to comment.