Skip to content

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

Merged
ajpallares merged 83 commits into
mainfrom
pallares/maestro-launch-args
Apr 13, 2026
Merged

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

Conversation

@ajpallares
Copy link
Copy Markdown
Member

@ajpallares ajpallares commented Apr 8, 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

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

ajpallares and others added 30 commits April 8, 2026 10:12
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Generated iOS project boilerplate from React Native 0.76.0 template with
bundle ID set to com.revenuecat.maestro.e2e. Includes xcodeproj, app delegate,
launch screen, privacy manifest, asset catalog, and test target.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The RN repo uses Yarn workspaces, so a standalone yarn.lock is needed
to prevent Yarn from treating MaestroTestApp as part of the workspace.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
react-native-screens 4.24+ requires RN 0.77+ codegen.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Align with purchaseTesterTypescript patterns: ignore .yarn cache,
.xcode.env.local, Xcode artifacts, and stop over-ignoring xcworkspace.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace Objective-C AppDelegate (AppDelegate.h, AppDelegate.mm, main.m)
with a Swift AppDelegate using @main annotation. Also adds required
devDependencies for pod install to work correctly.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Made-with: Cursor
The StoreKitConfiguration.storekit file was on disk but not registered
as a PBXFileReference in project.pbxproj, so Xcode couldn't find it
at runtime. Also fix the scheme identifier path.

Made-with: Cursor
The identifier is relative to the .xcodeproj directory, so it needs
the ../ prefix to reach the sibling StoreKitConfiguration.storekit.

Made-with: Cursor
- Use portal: references for react-native-purchases and
  react-native-purchases-ui so E2E tests exercise the local branch
  code instead of whatever is published on npm
- Commit ios/Podfile.lock for reproducible CI builds (force-added
  since root .gitignore has **/Podfile.lock)
- Add try/catch to presentPaywall for diagnosable test failures
- Type the navigation prop with RootStackParamList
- Add README with build/run instructions and API key setup

Made-with: Cursor
… add testID

- Add e2e-tests/MaestroTestApp to root workspaces (matching
  purchaseTesterTypescript pattern)
- Replace portal: deps with babel module-resolver aliases to SDK source
- Configure Metro watchFolders + exclusionList for out-of-root resolution
- Surface presentPaywall errors in a visible <Text testID="error-message">
  instead of only console.error, so Maestro can capture failures
- Switch from accessibilityLabel to testID for reliable Maestro targeting
- Update README to describe the workspace + module-resolver mechanism

Made-with: Cursor
…ile.lock

- Add .catch() to getCustomerInfo() to surface errors in the UI instead
  of producing an unhandled promise rejection
- Replace deprecated blacklistRE with blockList in metro.config.js
- Regenerate Podfile.lock under current workspace setup (was generated
  under the old portal: setup)

Made-with: Cursor
Without this file, CocoaPods' use_native_modules! doesn't know where
to find react-native-purchases and react-native-purchases-ui, since
they aren't explicit npm dependencies of the test app.
Mirrors the purchaseTesterTypescript example.

Made-with: Cursor
Include react-native-purchases and react-native-purchases-ui as Gradle
projects so the Android autolinker can resolve them. Mirrors the
purchaseTesterTypescript example.

Made-with: Cursor
RN 0.76.x is incompatible with react-native-purchases-ui's AGP 8.13.2
(NativeDeviceEventManagerSpec unresolved supertype during Kotlin compilation).

- React Native 0.76.9 → 0.78.0 (+ React 19, safe-area-context 5, screens 4.5)
- Gradle wrapper 8.10.2 → 8.14.4
- Kotlin 1.9.25 → 2.0.21, NDK 26 → 27, targetSdk 34 → 35
- Add allprojects repositories block and explicit Gradle project includes
- Regenerate Podfile.lock and yarn.lock

Made-with: Cursor
react-native-screens 4.24.0 has a codegen incompatibility with
RN 0.78 ("Unknown prop type for accessibilityContainerViewIsModal").
Pin to ~4.11.0 (matching purchaseTesterTypescript) and regenerate
both yarn.lock and Podfile.lock.

Made-with: Cursor
The CLI is a devDependency of react-native (not production), so it's
not installed transitively. Both pod install (use_native_modules!) and
Gradle autolinking (RNGP) require it to discover native modules.

Made-with: Cursor
- Add ReactAppDependencyProvider for RN 0.78+ native component registration
- Always use pre-bundled JS instead of Metro dev server (CI has no Metro)
- Force JS bundling in Android debug builds by setting debuggableVariants = []

Made-with: Cursor
- Replace force-unwrap in bundleURL() with guard + fatalError for a
  more debuggable crash when main.jsbundle is missing
- Add comment in babel.config.js explaining how SDK packages are
  resolved from repo source without being in package.json dependencies

Made-with: Cursor
The committed Podfile.lock goes stale when yarn resolves a different
react-native patch (hermes-engine version changes). Since this is a
CI-only test app rebuilt from scratch every run, not committing the
lockfile avoids the staleness problem.

Made-with: Cursor
Reverting the previous decision to gitignore Podfile.lock. Instead,
we'll enforce immutable yarn installs on CI (no YARN_ENABLE_IMMUTABLE_INSTALLS=false)
so versions don't drift, and the committed Podfile.lock stays consistent
with yarn.lock.

Made-with: Cursor
MaestroTestApp is a workspace of the root package.json, so the root
yarn.lock is the source of truth. The local yarn.lock was an artifact
from project initialization and was pinning react-native@0.78.3 while
the root lockfile pins 0.78.0, causing immutable install failures on CI.

Made-with: Cursor
@ajpallares ajpallares marked this pull request as ready for review April 9, 2026 11:42
@ajpallares ajpallares requested a review from a team as a code owner April 9, 2026 11:42
@ajpallares ajpallares requested a review from a team as a code owner April 13, 2026 11:21
Base automatically changed from add-maestro-e2e-test-ci-job to main April 13, 2026 14:53
@ajpallares ajpallares merged commit 5da9114 into main Apr 13, 2026
10 checks passed
@ajpallares ajpallares deleted the pallares/maestro-launch-args branch April 13, 2026 14:53
@tonidero tonidero mentioned this pull request Apr 15, 2026
RCGitBot pushed a commit that referenced this pull request Apr 15, 2026
## RevenueCat SDK
> [!WARNING]  
> If you don't have any login system in your app, please make sure your
one-time purchase products have been correctly configured in the
RevenueCat dashboard as either consumable or non-consumable. If they're
incorrect as consumables, RevenueCat will consume these purchases. This
means that customers won't be able to restore them from version 10.0.0
onward.
> Non-consumables are products that are meant to be bought only once,
for example, lifetime subscriptions. Please see more information in our
[docs](https://www.revenuecat.com/docs/known-store-issues/play-billing-library/restore-consumable-purchases-bc8)

### 💥 Breaking Changes
This release updates to Billing Library 8.3.0 with min SDK supported of
Android 6 (API 23), previously min was 21. It also removes a previous
workaround used to be able to restore consumed one time products which
is not available anymore.

* [AUTOMATIC BUMP] Updates purchases-hybrid-common to 18.0.0 (#1729) via
RevenueCat Git Bot (@RCGitBot)
* [Android
10.1.2](https://github.com/RevenueCat/purchases-android/releases/tag/10.1.2)
* [Android
10.1.1](https://github.com/RevenueCat/purchases-android/releases/tag/10.1.1)
* [Android
10.1.0](https://github.com/RevenueCat/purchases-android/releases/tag/10.1.0)
* [Android
10.0.2](https://github.com/RevenueCat/purchases-android/releases/tag/10.0.2)
* [Android
10.0.1](https://github.com/RevenueCat/purchases-android/releases/tag/10.0.1)
* [Android
9.29.1](https://github.com/RevenueCat/purchases-android/releases/tag/9.29.1)
* [Android
10.0.0](https://github.com/RevenueCat/purchases-android/releases/tag/10.0.0)
* [iOS
5.67.2](https://github.com/RevenueCat/purchases-ios/releases/tag/5.67.2)

### 🔄 Other Changes
* Skip test cases list in maestro tests using launch arguments (#1722)
via Antonio Pallares (@ajpallares)
* Add CircleCI job for maestro E2E tests (#1637) via Antonio Pallares
(@ajpallares)
* Bump fastlane-plugin-revenuecat_internal from `894bb1b` to `20911d1`
(#1728) via dependabot[bot] (@dependabot[bot])
* Bump fastlane-plugin-revenuecat_internal from `ceecf91` to `894bb1b`
(#1726) via dependabot[bot] (@dependabot[bot])
* Update CODEOWNERS default owner to @RevenueCat/sdk (#1725) via Antonio
Pallares (@ajpallares)
* Add maestro E2E test for purchase through paywall (#1636) via Antonio
Pallares (@ajpallares)
* Add maestro E2E test app (#1635) via Antonio Pallares (@ajpallares)
* Bump addressable from 2.8.9 to 2.9.0 (#1723) via dependabot[bot]
(@dependabot[bot])
* Bump addressable from 2.8.7 to 2.9.0 in
/examples/purchaseTesterTypescript (#1721) via dependabot[bot]
(@dependabot[bot])
* Bump addressable from 2.8.7 to 2.9.0 in /examples/MagicWeather (#1720)
via dependabot[bot] (@dependabot[bot])
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 -->
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>
ajpallares added a commit to RevenueCat/purchases-capacitor that referenced this pull request Apr 27, 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
- 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
- RevenueCat/react-native-purchases#1722
- RevenueCat/purchases-kmp#796
- RevenueCat/purchases-flutter#1714
- 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`).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pr:other A code change that improves performance

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants