From 0fee6660ce167ba5a0d24d11c9411b0359db6816 Mon Sep 17 00:00:00 2001 From: Wes Risenmay Date: Thu, 18 Dec 2025 10:15:28 -0700 Subject: [PATCH 1/4] added an e2e tests for the connect widget --- E2E_TESTING.md | 23 +++++++++++++++++++++++ README.md | 2 ++ example/app.json | 6 ++++-- example/maestro/connectWidget.yaml | 7 +++++++ example/package.json | 7 +++++-- 5 files changed, 41 insertions(+), 4 deletions(-) create mode 100644 E2E_TESTING.md create mode 100644 example/maestro/connectWidget.yaml diff --git a/E2E_TESTING.md b/E2E_TESTING.md new file mode 100644 index 0000000..9658811 --- /dev/null +++ b/E2E_TESTING.md @@ -0,0 +1,23 @@ +# E2E Testing + +We use Maestro for E2E testing. + +## Local setup + +### 1. [Install maestro](https://docs.maestro.dev/getting-started/installing-maestro) + +### 2. Run an E2E friendly version of the app + +``` + # Run from the example folder + npm run android:e2e + # Or + npm run ios:e2e +``` + +### 3. Run the E2E tests + +``` + # Run from the example folder + npm run e2e +``` diff --git a/README.md b/README.md index dfb7b8e..4bdd321 100644 --- a/README.md +++ b/README.md @@ -10,3 +10,5 @@ documentation][sdk_docs] to get started. [Contributiong](./CONTRIBUTING.md) [Development](./DEVELOPMENT.md) + +[E2E Testing](./E2E_TESTING.md) diff --git a/example/app.json b/example/app.json index f8c6642..521138a 100644 --- a/example/app.json +++ b/example/app.json @@ -9,7 +9,8 @@ "userInterfaceStyle": "automatic", "newArchEnabled": true, "ios": { - "supportsTablet": true + "supportsTablet": true, + "bundleIdentifier": "com.anonymous.example" }, "android": { "adaptiveIcon": { @@ -19,7 +20,8 @@ "monochromeImage": "./assets/images/android-icon-monochrome.png" }, "edgeToEdgeEnabled": true, - "predictiveBackGestureEnabled": false + "predictiveBackGestureEnabled": false, + "package": "com.anonymous.example" }, "web": { "output": "static", diff --git a/example/maestro/connectWidget.yaml b/example/maestro/connectWidget.yaml new file mode 100644 index 0000000..c89a80d --- /dev/null +++ b/example/maestro/connectWidget.yaml @@ -0,0 +1,7 @@ +appId: com.anonymous.example +--- +- launchApp +- tapOn: "Connect" +- assertVisible: "Select your institution" +- tapOn: ".*MX Bank.*" +- assertVisible: "Enter your credentials" diff --git a/example/package.json b/example/package.json index 3f84c73..574f289 100644 --- a/example/package.json +++ b/example/package.json @@ -4,8 +4,11 @@ "version": "1.0.0", "scripts": { "start": "expo start", - "android": "expo start --android", - "ios": "expo start --ios", + "android": "expo start:android", + "android:e2e": "expo run:android", + "e2e": "maestro test ./maestro/", + "ios": "expo start:ios", + "ios:e2e": "expo run:ios", "lint": "expo lint" }, "dependencies": { From bac1a025d7d6701194ea2f082ed148f2e72f229c Mon Sep 17 00:00:00 2001 From: Wes Risenmay Date: Thu, 18 Dec 2025 10:31:57 -0700 Subject: [PATCH 2/4] add an e2e test workflow --- .github/workflows/maestro-tests.yml | 160 ++++++++++++++++++++++++++++ 1 file changed, 160 insertions(+) create mode 100644 .github/workflows/maestro-tests.yml diff --git a/.github/workflows/maestro-tests.yml b/.github/workflows/maestro-tests.yml new file mode 100644 index 0000000..a58de41 --- /dev/null +++ b/.github/workflows/maestro-tests.yml @@ -0,0 +1,160 @@ +name: Maestro E2E Tests + +on: + pull_request: + +jobs: + test-android: + runs-on: ubuntu-latest + timeout-minutes: 30 + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: "20" + cache: "npm" + + - name: Install root dependencies + run: npm ci + + - name: Build SDK + run: npm run build + + - name: Install example app dependencies + working-directory: example + run: npm ci + + - name: Set up JDK 17 + uses: actions/setup-java@v4 + with: + java-version: "17" + distribution: "temurin" + cache: "gradle" + + - name: Setup Android SDK + uses: android-actions/setup-android@v3 + + - name: Enable Gradle Wrapper + working-directory: example/android + run: chmod +x ./gradlew + + - name: Accept Android licenses + run: yes | $ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager --licenses || true + + - name: Install Maestro CLI + run: | + curl -Ls "https://get.maestro.mobile.dev" | bash + echo "$HOME/.maestro/bin" >> $GITHUB_PATH + + - name: Set up Android Emulator and run tests + uses: reactivecircus/android-emulator-runner@v2 + with: + api-level: 33 + target: google_apis + arch: x86_64 + profile: pixel_6 + force-avd-creation: false + emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none + disable-animations: true + script: | + cd example + npm run android:e2e & + APP_PID=$! + + echo "Waiting for app to build and install..." + timeout 300 bash -c 'until adb shell pm list packages | grep -q "com.anonymous.example"; do sleep 5; done' || exit 1 + + echo "Running Maestro tests..." + ~/.maestro/bin/maestro test ./maestro/ + + kill $APP_PID || true + + - name: Upload Maestro test results + if: always() + uses: actions/upload-artifact@v4 + with: + name: maestro-results + path: | + example/maestro/**/*.mp4 + example/maestro/**/*.log + retention-days: 7 + + test-ios: + runs-on: macos-14 + timeout-minutes: 45 + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: "20" + cache: "npm" + + - name: Install root dependencies + run: npm ci + + - name: Build SDK + run: npm run build + + - name: Install example app dependencies + working-directory: example + run: npm ci + + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: "3.2" + bundler-cache: true + + - name: Install CocoaPods dependencies + working-directory: example/ios + run: pod install + + - name: Install Maestro CLI + run: | + curl -Ls "https://get.maestro.mobile.dev" | bash + echo "$HOME/.maestro/bin" >> $GITHUB_PATH + + - name: Boot iOS Simulator + run: | + SIMULATOR_ID=$(xcrun simctl create "iPhone 15 Pro" "iPhone 15 Pro") + xcrun simctl boot "$SIMULATOR_ID" + echo "SIMULATOR_ID=$SIMULATOR_ID" >> $GITHUB_ENV + + - name: Build and run iOS app + working-directory: example + run: | + npm run ios:e2e & + APP_PID=$! + echo "APP_PID=$APP_PID" >> $GITHUB_ENV + + echo "Waiting for app to build and install..." + sleep 120 + + - name: Run Maestro tests + working-directory: example + run: ~/.maestro/bin/maestro test ./maestro/ + + - name: Cleanup + if: always() + run: | + kill $APP_PID || true + xcrun simctl shutdown $SIMULATOR_ID || true + xcrun simctl delete $SIMULATOR_ID || true + + - name: Upload Maestro test results + if: always() + uses: actions/upload-artifact@v4 + with: + name: maestro-results-ios + path: | + example/maestro/**/*.mp4 + example/maestro/**/*.log + retention-days: 7 From 0ba78aa779c41f34d10f24897ccdc9971d11d48e Mon Sep 17 00:00:00 2001 From: Wes Risenmay Date: Thu, 18 Dec 2025 10:45:35 -0700 Subject: [PATCH 3/4] remove maestro github action --- .github/workflows/maestro-tests.yml | 160 ---------------------------- 1 file changed, 160 deletions(-) delete mode 100644 .github/workflows/maestro-tests.yml diff --git a/.github/workflows/maestro-tests.yml b/.github/workflows/maestro-tests.yml deleted file mode 100644 index a58de41..0000000 --- a/.github/workflows/maestro-tests.yml +++ /dev/null @@ -1,160 +0,0 @@ -name: Maestro E2E Tests - -on: - pull_request: - -jobs: - test-android: - runs-on: ubuntu-latest - timeout-minutes: 30 - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Set up Node.js - uses: actions/setup-node@v4 - with: - node-version: "20" - cache: "npm" - - - name: Install root dependencies - run: npm ci - - - name: Build SDK - run: npm run build - - - name: Install example app dependencies - working-directory: example - run: npm ci - - - name: Set up JDK 17 - uses: actions/setup-java@v4 - with: - java-version: "17" - distribution: "temurin" - cache: "gradle" - - - name: Setup Android SDK - uses: android-actions/setup-android@v3 - - - name: Enable Gradle Wrapper - working-directory: example/android - run: chmod +x ./gradlew - - - name: Accept Android licenses - run: yes | $ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager --licenses || true - - - name: Install Maestro CLI - run: | - curl -Ls "https://get.maestro.mobile.dev" | bash - echo "$HOME/.maestro/bin" >> $GITHUB_PATH - - - name: Set up Android Emulator and run tests - uses: reactivecircus/android-emulator-runner@v2 - with: - api-level: 33 - target: google_apis - arch: x86_64 - profile: pixel_6 - force-avd-creation: false - emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none - disable-animations: true - script: | - cd example - npm run android:e2e & - APP_PID=$! - - echo "Waiting for app to build and install..." - timeout 300 bash -c 'until adb shell pm list packages | grep -q "com.anonymous.example"; do sleep 5; done' || exit 1 - - echo "Running Maestro tests..." - ~/.maestro/bin/maestro test ./maestro/ - - kill $APP_PID || true - - - name: Upload Maestro test results - if: always() - uses: actions/upload-artifact@v4 - with: - name: maestro-results - path: | - example/maestro/**/*.mp4 - example/maestro/**/*.log - retention-days: 7 - - test-ios: - runs-on: macos-14 - timeout-minutes: 45 - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Set up Node.js - uses: actions/setup-node@v4 - with: - node-version: "20" - cache: "npm" - - - name: Install root dependencies - run: npm ci - - - name: Build SDK - run: npm run build - - - name: Install example app dependencies - working-directory: example - run: npm ci - - - name: Set up Ruby - uses: ruby/setup-ruby@v1 - with: - ruby-version: "3.2" - bundler-cache: true - - - name: Install CocoaPods dependencies - working-directory: example/ios - run: pod install - - - name: Install Maestro CLI - run: | - curl -Ls "https://get.maestro.mobile.dev" | bash - echo "$HOME/.maestro/bin" >> $GITHUB_PATH - - - name: Boot iOS Simulator - run: | - SIMULATOR_ID=$(xcrun simctl create "iPhone 15 Pro" "iPhone 15 Pro") - xcrun simctl boot "$SIMULATOR_ID" - echo "SIMULATOR_ID=$SIMULATOR_ID" >> $GITHUB_ENV - - - name: Build and run iOS app - working-directory: example - run: | - npm run ios:e2e & - APP_PID=$! - echo "APP_PID=$APP_PID" >> $GITHUB_ENV - - echo "Waiting for app to build and install..." - sleep 120 - - - name: Run Maestro tests - working-directory: example - run: ~/.maestro/bin/maestro test ./maestro/ - - - name: Cleanup - if: always() - run: | - kill $APP_PID || true - xcrun simctl shutdown $SIMULATOR_ID || true - xcrun simctl delete $SIMULATOR_ID || true - - - name: Upload Maestro test results - if: always() - uses: actions/upload-artifact@v4 - with: - name: maestro-results-ios - path: | - example/maestro/**/*.mp4 - example/maestro/**/*.log - retention-days: 7 From 28f1e22c0e5f8cac30b25e2c0e94755ff9918435 Mon Sep 17 00:00:00 2001 From: Wes Risenmay Date: Thu, 18 Dec 2025 10:52:47 -0700 Subject: [PATCH 4/4] tick version and update changelog --- CHANGELOG.md | 6 ++++++ package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f73bd26..88b1d79 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed +## [2.0.1] + +### Added + +- Local E2E testing via maestro + ## [2.0.0] ### Changed diff --git a/package-lock.json b/package-lock.json index 59929a8..83eeee6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@mxenabled/react-native-widget-sdk", - "version": "2.0.0", + "version": "2.0.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@mxenabled/react-native-widget-sdk", - "version": "2.0.0", + "version": "2.0.1", "license": "MIT", "dependencies": { "@mxenabled/widget-post-message-definitions": "^1.4.0", diff --git a/package.json b/package.json index c2e503c..862b9e2 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@mxenabled/react-native-widget-sdk", "description": "MX React Native Widget SDK", - "version": "2.0.0", + "version": "2.0.1", "main": "dist/index.js", "module": "dist/index.mjs", "types": "dist/index.d.ts",