Skip to content

Skip test cases list in maestro tests using launch arguments#757

Merged
ajpallares merged 69 commits into
mainfrom
pallares/maestro-launch-args
Apr 27, 2026
Merged

Skip test cases list in maestro tests using launch arguments#757
ajpallares merged 69 commits into
mainfrom
pallares/maestro-launch-args

Conversation

@ajpallares

@ajpallares ajpallares commented Apr 8, 2026

Copy link
Copy Markdown
Member

Summary

  • Pass e2e_test_flow as a Maestro launchApp argument so the app navigates directly to the target test case screen, bypassing the Test Cases list
  • Adds a local LaunchArgsPlugin Capacitor plugin on both iOS (reads UserDefaults) and Android (reads intent extras) to bridge the argument to the web layer
  • Makes maestro tests faster by skipping the list navigation step
  • The Test Cases list is preserved for manual/local usage

Related PRs

Follows the same pattern as the iOS SDK's maestro app (purchases-ios/Examples/rc-maestro).

Made-with: Cursor
These steps were only used for debugging CI failures and add
unnecessary clutter to the CI report.

Made-with: Cursor
Fail fast with a clear error if RC_E2E_TEST_API_KEY_PRODUCTION_TEST_STORE
is not set, instead of silently replacing the placeholder with an empty
string and crashing at runtime.

Made-with: Cursor
Pass e2e_test_flow as a launchApp argument so the app navigates
directly to the target test case screen, making tests faster.
The Test Cases list is preserved for manual/local usage.

Made-with: Cursor
- Reorder imports to satisfy eslint import/order rule
- Add comment to empty catch block to fix no-empty rule
- Add LaunchArgsPlugin.swift to Xcode project so it gets compiled

Made-with: Cursor
Capacitor 6+ no longer auto-discovers local iOS plugins. Use a custom
CAPBridgeViewController subclass to explicitly register the plugin
instance via bridge.registerPluginInstance().

Made-with: Cursor
ajpallares added a commit to RevenueCat/react-native-purchases that referenced this pull request Apr 13, 2026
## Summary
- Pass `e2e_test_flow` as a Maestro `launchApp` argument so the app
navigates directly to the target test case screen, bypassing the Test
Cases list
- Reads the argument via `initialProps` on iOS (UserDefaults) and
Android (intent extras)
- Makes maestro tests faster by skipping the list navigation step
- The Test Cases list is preserved for manual/local usage

## Related PRs
- RevenueCat/purchases-kmp#796
- RevenueCat/purchases-flutter#1714
- RevenueCat/purchases-capacitor#757
- RevenueCat/cordova-plugin-purchases#919
- RevenueCat/purchases-unity#897

Follows the same pattern as the iOS SDK's maestro app
(`purchases-ios/Examples/rc-maestro`).

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Fail fast if the placeholder was not replaced, matching KMP.

Made-with: Cursor
ajpallares added a commit to RevenueCat/purchases-flutter that referenced this pull request Apr 15, 2026
## Summary
- Pass `e2e_test_flow` as a Maestro `launchApp` argument so the app
navigates directly to the target test case screen, bypassing the Test
Cases list
- Uses a `MethodChannel` to bridge the launch argument from native (iOS
UserDefaults / Android intent extras) to Dart
- Makes maestro tests faster by skipping the list navigation step
- The Test Cases list is preserved for manual/local usage

## Related PRs
- RevenueCat/react-native-purchases#1722
- RevenueCat/purchases-kmp#796
- RevenueCat/purchases-capacitor#757
- RevenueCat/cordova-plugin-purchases#919
- RevenueCat/purchases-unity#897

Follows the same pattern as the iOS SDK's maestro app
(`purchases-ios/Examples/rc-maestro`).

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Limited to the e2e Maestro test app and test YAML; main risk is
platform channel/launch-arg wiring causing the app to not route
correctly and slowing or breaking test runs.
> 
> **Overview**
> Maestro e2e tests can now pass an `e2e_test_flow` launch argument to
open a specific test case screen directly, skipping the Test Cases list
navigation.
> 
> This adds a native↔Flutter `MethodChannel`
(`com.revenuecat.maestro/launch_args`) on Android (intent extra) and iOS
(UserDefaults) and updates the Flutter app to resolve the requested
`flowKey` from `testCases` and use it as the initial home screen
(fallback remains `TestCasesScreen` for manual runs).
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
4d6fc7f. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
Use File.read + UI.user_error! instead of shell grep for cleaner error
handling and consistency with the rest of the Fastlane file.

Made-with: Cursor
ajpallares added a commit to RevenueCat/cordova-plugin-purchases that referenced this pull request Apr 20, 2026
## Summary

Passes `e2e_test_flow` as a Maestro `launchApp` argument so the app
navigates directly to the target test case screen, bypassing the Test
Cases list.

### Changes:
- Adds a local `cordova-plugin-launch-args` Cordova plugin with iOS
(reads UserDefaults) and Android (reads intent extras) implementations
to bridge the argument to the JS layer
- Updates `app.js` to use `LaunchArgs.getTestFlow()` with the
`TEST_CASES` registry for routing (same pattern as Flutter's `testCases`
list and KMP's `testFlowScreenMap`)
- When no `e2e_test_flow` is set, falls back to showing the Test Cases
list screen
- Makes maestro tests faster by skipping the list navigation step

## Related PRs
- RevenueCat/react-native-purchases#1722
- RevenueCat/purchases-kmp#796
- RevenueCat/purchases-flutter#1714
- RevenueCat/purchases-capacitor#757
- RevenueCat/purchases-unity#897

Follows the same pattern as the iOS SDK's maestro app
(`purchases-ios/Examples/rc-maestro`).

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Replace inline `maestro test` invocations in both the iOS and Android
lanes with the shared `run_maestro_e2e_tests` action from the
fastlane-plugin-revenuecat_internal plugin so Maestro runs use the
centralized retry logic.

Made-with: Cursor
- Render the purchase screen UI before calling getCustomerInfo so that
  any error surfaced via showError() is not wiped by the subsequent
  innerHTML replacement.
- Drop the redundant post-presentPaywall getCustomerInfo() call; the
  addCustomerInfoUpdateListener set up in init() already refreshes the
  entitlements label when a purchase completes, and the manual call had
  no try/catch so network hiccups caused uncaught rejections.
- Ignore e2e-tests/ in both .eslintignore and .prettierignore, matching
  the existing example/ pattern so the root lint job does not fail on
  Capacitor-generated boilerplate inside the test app.

Made-with: Cursor
The Test Store purchase confirmation dialog now renders identical
copy on iOS and Android, so the regex-based assertion and
case-insensitive tap are no longer needed. Match the exact strings
used by the already-merged flutter and cordova maestro flows.

Made-with: Cursor
ajpallares added a commit that referenced this pull request Apr 27, 2026
## Summary

Adds a Maestro E2E test app under `e2e-tests/MaestroTestApp/` — a
minimal Capacitor app used by automated Maestro flows to verify the
RevenueCat purchase integration.

- Two views: "Test Cases" list and "Purchase through paywall" (presents
a RevenueCat V2 paywall and displays entitlement status)
- App ID `com.revenuecat.automatedsdktests`
- API key placeholder (`MAESTRO_TESTS_REVENUECAT_API_KEY`) replaced at
CI time via `sed`
- Local SDK resolution via `file:` references (same mechanism as
`example/purchase-tester`)
- Errors from `getCustomerInfo` and `presentPaywall` are surfaced in the
UI for debugging test failures
- Includes a README and committed `package-lock.json`

Counterpart PRs:
[react-native-purchases#1635](RevenueCat/react-native-purchases#1635),
[purchases-flutter#1654](RevenueCat/purchases-flutter#1654),
[cordova-plugin-purchases#857](RevenueCat/cordova-plugin-purchases#857),
[purchases-unity#836](RevenueCat/purchases-unity#836),
[purchases-kmp#708](RevenueCat/purchases-kmp#708)

### Follow-up PRs (stacked)
- [#700](#700) —
Maestro test flows (YAML)
- [#701](#701) —
CircleCI jobs to run the tests
- [#757](#757) —
Launch-arg driven Maestro test flow routing
ajpallares and others added 13 commits April 27, 2026 10:17
- Bump the Android machine image from 2024.11.1 to 2025.10.1 to
  match the latest used elsewhere (e.g. cordova-plugin-purchases).
- iOS: split the simulator "boot" and "wait" steps so the simulator
  starts booting right after gem install and the wait happens just
  before running Maestro, letting the boot overlap with yarn install
  / build / cap sync.
- Android: drop the standalone "Build Maestro app" step and pass the
  Fastlane build lane as `post_emulator_launch_assemble_command` to
  the orb, so the app build runs in parallel with the emulator boot
  instead of after it.

Made-with: Cursor
Mirrors the build_purchase_tester / change_purchase_tester_api_key
pattern so the Maestro test app is fully buildable from a Fastlane lane
without requiring CI to pre-build the root and UI packages. The new
run_maestro_e2e_tests_* lanes call those helpers when the build artifact
is missing, so a clean local invocation works out of the box while CI
keeps building during the Android emulator boot.

Made-with: Cursor
Both jobs now explicitly call change_maestro_test_app_api_key and
build_maestro_test_app from CI; the run_maestro_e2e_tests_* lanes only
install the produced artifact and run the Maestro flows. Locally, the
exact same three-lane invocation works on either platform.

Made-with: Cursor
ajpallares added a commit that referenced this pull request Apr 27, 2026
## Summary

Adds CircleCI jobs that build the Maestro test app introduced in #699,
install it on a simulator/emulator, and run the Maestro flows from #700
against it on every PR.

- Two new jobs in the main `build-test-hold-deploy` workflow, both
pulling the API key from the `e2e-tests` CircleCI context
(`$RC_E2E_TEST_API_KEY_PRODUCTION_TEST_STORE`):
- `run-maestro-e2e-tests-ios` — macOS executor (Xcode 26.4.1), boots an
iPhone 17 simulator, builds the app via `xcodebuild`, installs it on the
booted simulator, runs the Maestro flows.
- `run-maestro-e2e-tests-android` — `android:2025.10.1` machine image
(xlarge), creates and boots an AVD, builds the debug APK via Gradle,
installs it via `adb`, runs the Maestro flows.
- Test artifacts and JUnit results are stored from
`fastlane/test_output`.

### Fastlane lanes

Mirrors the existing `change_purchase_tester_api_key` /
`build_purchase_tester` pattern so the test app is also runnable locally
without manually pre-building anything:

- `change_maestro_test_app_api_key` — replaces the
`MAESTRO_TESTS_REVENUECAT_API_KEY` placeholder in
`e2e-tests/MaestroTestApp/src/app.ts` with the value from the `api_key`
option or `RC_E2E_TEST_API_KEY_PRODUCTION_TEST_STORE`.
- `build_maestro_test_app(platform: ios|android)` — builds the root SDK,
the UI package, and the test app for the given platform (`xcodebuild` or
`./gradlew assembleDebug`).
- `run_maestro_e2e_tests_ios` / `run_maestro_e2e_tests_android` —
install the previously-built artifact on the simulator/emulator and run
the Maestro flows.

Both CI jobs invoke the three lanes explicitly (`change_*`, then
`build_*`, then `run_*`), so locally the exact same invocation works on
either platform.

### CI parallelism

- iOS: the simulator starts booting right after gem install; the wait
happens just before the Maestro run, so the boot overlaps with `yarn
install`, the API-key replacement and `build_maestro_test_app
platform:ios`.
- Android: the API key is replaced first (cheap), then the AVD is
created and `android/start_emulator` runs `bundle exec fastlane
build_maestro_test_app platform:android` as its
`post_emulator_launch_assemble_command`, so the (slow) APK build runs in
parallel with the (slow) emulator boot.

### Local usage

```bash
export RC_E2E_TEST_API_KEY_PRODUCTION_TEST_STORE=<key>

# iOS — requires a booted iPhone 17 simulator
bundle exec fastlane change_maestro_test_app_api_key
bundle exec fastlane build_maestro_test_app platform:ios
bundle exec fastlane run_maestro_e2e_tests_ios

# Android — requires a running emulator
bundle exec fastlane change_maestro_test_app_api_key
bundle exec fastlane build_maestro_test_app platform:android
bundle exec fastlane run_maestro_e2e_tests_android
```

### Stack

Predecessors (merged):
- #699 — Maestro test app
- #700 — Maestro test flows (YAML)

Follow-up (stacked on this PR):
- #757 — Launch-arg driven Maestro test flow routing
Base automatically changed from add-maestro-e2e-test-ci-job to main April 27, 2026 11:41
@ajpallares ajpallares merged commit 09f1236 into main Apr 27, 2026
13 checks passed
@ajpallares ajpallares deleted the pallares/maestro-launch-args branch April 27, 2026 11:50
RCGitBot added a commit that referenced this pull request May 6, 2026
**This is an automatic release.**

## RevenueCat SDK
### ✨ New Features
* Unified StoreReplacementMode API (#779) via Will Taylor
(@fire-at-will)
### 📦 Dependency Updates
* [AUTOMATIC BUMP] Updates purchases-hybrid-common to 18.4.0 (#782) via
RevenueCat Git Bot (@RCGitBot)
* [Android
10.3.1](https://github.com/RevenueCat/purchases-android/releases/tag/10.3.1)
* [Android
10.3.0](https://github.com/RevenueCat/purchases-android/releases/tag/10.3.0)
* [Android
10.2.1](https://github.com/RevenueCat/purchases-android/releases/tag/10.2.1)
* [iOS
5.70.0](https://github.com/RevenueCat/purchases-ios/releases/tag/5.70.0)
* [iOS
5.69.0](https://github.com/RevenueCat/purchases-ios/releases/tag/5.69.0)
* [AUTOMATIC BUMP] Updates purchases-hybrid-common to 18.3.0 (#778) via
RevenueCat Git Bot (@RCGitBot)
* [RENOVATE] Update build-dependencies (#776) via RevenueCat Git Bot
(@RCGitBot)
* [AUTOMATIC BUMP] Updates purchases-hybrid-common to 18.2.0 (#774) via
RevenueCat Git Bot (@RCGitBot)

### 🔄 Other Changes
* Bump fastlane-plugin-revenuecat_internal from `21e02ec` to `af7bb5c`
(#781) via dependabot[bot] (@dependabot[bot])
* Bump fastlane-plugin-revenuecat_internal from `2d11430` to `21e02ec`
(#780) via dependabot[bot] (@dependabot[bot])
* Bump fastlane-plugin-revenuecat_internal from `d24ab26` to `2d11430`
(#777) via dependabot[bot] (@dependabot[bot])
* Remove unused install-sdkman command (#773) via Rick (@rickvdl)
* Bump fastlane from 2.233.0 to 2.233.1 (#772) via dependabot[bot]
(@dependabot[bot])
* Skip test cases list in maestro tests using launch arguments (#757)
via Antonio Pallares (@ajpallares)
* Add CircleCI job for maestro E2E tests (#701) via Antonio Pallares
(@ajpallares)
* Add maestro E2E test for purchase through paywall (#700) via Antonio
Pallares (@ajpallares)
* Add maestro E2E test app (#699) via Antonio Pallares (@ajpallares)
* Bump fastlane-plugin-revenuecat_internal from `b822f01` to `d24ab26`
(#770) via dependabot[bot] (@dependabot[bot])
* Bump fastlane-plugin-revenuecat_internal from `e348913` to `b822f01`
(#769) via dependabot[bot] (@dependabot[bot])
* Bump fastlane from 2.232.2 to 2.233.0 (#767) via dependabot[bot]
(@dependabot[bot])
* Bump fastlane-plugin-revenuecat_internal from `a1eed48` to `e348913`
(#768) via dependabot[bot] (@dependabot[bot])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants