Move rc-maestro to Projects and rename it AutomatedSDKTestsApp (#8190)

* other: move PurchaseTester to Projects

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* other(ci): add a PurchaseTester smoke build with Tuist

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* other: move rc-maestro to Projects

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* other: rename rc-maestro to AutomatedSDKTestsApp

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Facundo MenzellaandClaude Opus 5.5 authored and GitHub committed 2026-11-03 15:21:45 +00:00
1 parent 735b5e5d6b
commit afd06bf825
80 files changed
+51 -64

No files matched your search

+2 -2
View File
@@ -1605,7 +1605,7 @@ jobs:
- install-dependencies
- revenuecat/install-maestro
- tuist-generate-workspace:
query: "Maestro"
query: "AutomatedSDKTestsApp"
# Create directory to track test failures
- run:
name: Initialize test tracking
@@ -1731,7 +1731,7 @@ jobs:
- install-dependencies
- revenuecat/install-maestro
- tuist-generate-workspace:
query: "Maestro"
query: "AutomatedSDKTestsApp"
- run:
name: Set API key for workflow e2e tests (test_store)
command: |
+3 -3
View File
@@ -29,8 +29,8 @@
/Sources/**/*Workflow* @RevenueCat/workflows
/RevenueCatUI/**/*Workflow* @RevenueCat/workflows
/Tests/**/*Workflow* @RevenueCat/workflows
/Examples/rc-maestro/maestro/workflows/ @RevenueCat/workflows
/Examples/rc-maestro/rc-maestro/Sources/rc-maestro/e2e-test-flows/*workflow* @RevenueCat/workflows
/Projects/AutomatedSDKTestsApp/maestro/workflows/ @RevenueCat/workflows
/Projects/AutomatedSDKTestsApp/AutomatedSDKTestsApp/Sources/AutomatedSDKTestsApp/e2e-test-flows/*workflow* @RevenueCat/workflows
# Checkpoints (after Workflows, so checkpoint files with Workflow in the name stay here)
/Sources/Checkpoints/ @RevenueCat/coresdk
@@ -53,7 +53,7 @@
/Tests/UnitTests/Networking/**/*CustomerCenter* @RevenueCat/customer-center
/RevenueCatUI/CustomerCenter/ @RevenueCat/customer-center
/Tests/RevenueCatUITests/CustomerCenter/ @RevenueCat/customer-center
/Examples/rc-maestro/maestro/customer_center/ @RevenueCat/customer-center
/Projects/AutomatedSDKTestsApp/maestro/customer_center/ @RevenueCat/customer-center
# Public API surface: changes here should stay visible to the whole SDK team
/api/ @RevenueCat/sdk
+1
View File
@@ -1,6 +1,7 @@
excluded:
- Carthage
- Examples
- Projects/AutomatedSDKTestsApp
- Tests/InstallationTests
- Tests/TestingApps
- Tests/APITesters
+1 -1
View File
@@ -90,7 +90,7 @@ Key top-level directories: `Sources/`, `RevenueCatUI/`, `Tests/`, `Examples/`, `
### Example apps
- `Examples/SampleCat/` is the reference for app integration code (offerings, paywalls, checkpoints, Customer Center). The dashboard download writes over its `Constants.swift`, so keep other values out of that file.
- PaywallsTester, rc-maestro, and `Tests/` are test tools with debug seams. Do not copy them into app code.
- PaywallsTester, AutomatedSDKTestsApp, and `Tests/` are test tools with debug seams. Do not copy them into app code.
### Key Architectural Patterns
+1 -1
View File
@@ -2,6 +2,6 @@
- **Unit tests**: Logic, state changes, and serialization. Use `Tests/UnitTests/` for the core SDK, `Tests/StoreKitUnitTests/` for StoreKit, and `Tests/RevenueCatUITests/` for RevenueCatUI logic.
- **PaywallFixtures**: Paywall UI behavior with fixed data and no backend dependency. Examples include carousel pages across tabs, package selection, gestures, and accessibility. Add fixtures in `Tests/TestingApps/PaywallFixtures/` and XCUITests in `Tests/TestingApps/PaywallFixturesUITests/`.
- **Maestro**: Complete app flows, such as purchases, entitlement updates, and workflow navigation. Use the app and YAML flows in `Examples/rc-maestro/`.
- **Maestro**: Complete app flows, such as purchases, entitlement updates, and workflow navigation. Use the app and YAML flows in `Projects/AutomatedSDKTestsApp/`.
- **Snapshot tests**: Visual appearance, such as layout, colors, and text styles. Use the snapshot tests in `Tests/RevenueCatUITests/`.
- **Manual checks**: Behavior that the automated tests cannot verify, such as actual VoiceOver speech and focus order.
Whitespace-only changes.
@@ -1,14 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "group:Maestro.xcodeproj">
</FileRef>
<Group
location = "container:"
name = "Dependencies">
<FileRef
location = "group:Tuist/.build/tuist-derived/RevenueCat/RevenueCat.xcodeproj">
</FileRef>
</Group>
</Workspace>
@@ -3,13 +3,13 @@ import ProjectDescriptionHelpers
import Foundation
let project = Project(
name: "Maestro",
name: "AutomatedSDKTestsApp",
organizationName: .revenueCatOrgName,
packages: .projectPackages,
settings: .appProject,
targets: [
.target(
name: "Maestro",
name: "AutomatedSDKTestsApp",
destinations: .iOS,
product: .app,
bundleId: "com.revenuecat.maestro.ios",
@@ -27,10 +27,10 @@ let project = Project(
"REVENUECAT_API_HOST": "$(REVENUECAT_API_HOST)"
]
),
sources: ["rc-maestro/Sources/**/*.swift"],
sources: ["AutomatedSDKTestsApp/Sources/**/*.swift"],
resources: [
"rc-maestro/Resources/**/*.xcassets",
"rc-maestro/Resources/StoreKit/app787ddb07e6.storekit",
"AutomatedSDKTestsApp/Resources/**/*.xcassets",
"AutomatedSDKTestsApp/Resources/StoreKit/app787ddb07e6.storekit",
],
dependencies: [
.revenueCat,
@@ -44,15 +44,15 @@ let project = Project(
],
schemes: [
.scheme(
name: "Maestro",
name: "AutomatedSDKTestsApp",
shared: true,
hidden: false,
buildAction: .buildAction(targets: ["Maestro"], findImplicitDependencies: true),
buildAction: .buildAction(targets: ["AutomatedSDKTestsApp"], findImplicitDependencies: true),
runAction: .runAction(
configuration: "Debug",
executable: "Maestro",
executable: "AutomatedSDKTestsApp",
options: .options(
storeKitConfigurationPath: "rc-maestro/Resources/StoreKit/StoreKitConfiguration.storekit"
storeKitConfigurationPath: "AutomatedSDKTestsApp/Resources/StoreKit/StoreKitConfiguration.storekit"
)
)
)
File renamed without changes.
@@ -3,7 +3,7 @@
#
# Fixtures live in the Automated SDK Tests project (6627e5bc). Do not edit them.
# Run locally against the test store:
# maestro test -e MAESTRO_STORE=test_store Examples/rc-maestro/maestro/workflows/checkpoint_attribute.yaml
# maestro test -e MAESTRO_STORE=test_store Projects/AutomatedSDKTestsApp/maestro/workflows/checkpoint_attribute.yaml
appId: com.revenuecat.maestro.ios
name: A checkpoint rule on a subscriber attribute
@@ -2,7 +2,7 @@
#
# Fixtures live in the Automated SDK Tests project (6627e5bc). Do not edit them.
# Run locally against the test store:
# maestro test -e MAESTRO_STORE=test_store Examples/rc-maestro/maestro/workflows/checkpoint_everyone.yaml
# maestro test -e MAESTRO_STORE=test_store Projects/AutomatedSDKTestsApp/maestro/workflows/checkpoint_everyone.yaml
appId: com.revenuecat.maestro.ios
name: A checkpoint for everyone presents its offering
@@ -3,7 +3,7 @@
#
# Fixtures live in the Automated SDK Tests project (6627e5bc). Do not edit them.
# Run locally against the test store:
# maestro test -e MAESTRO_STORE=test_store Examples/rc-maestro/maestro/workflows/checkpoint_no_match.yaml
# maestro test -e MAESTRO_STORE=test_store Projects/AutomatedSDKTestsApp/maestro/workflows/checkpoint_no_match.yaml
appId: com.revenuecat.maestro.ios
name: A checkpoint without a matching rule presents nothing
@@ -3,7 +3,7 @@
#
# Fixtures live in the Automated SDK Tests project (6627e5bc). Do not edit them.
# Run locally against the test store:
# maestro test -e MAESTRO_STORE=test_store Examples/rc-maestro/maestro/workflows/checkpoint_priority.yaml
# maestro test -e MAESTRO_STORE=test_store Projects/AutomatedSDKTestsApp/maestro/workflows/checkpoint_priority.yaml
appId: com.revenuecat.maestro.ios
name: The first matching checkpoint rule wins
@@ -4,7 +4,7 @@
#
# Fixtures live in the Automated SDK Tests project (6627e5bc). Do not edit them.
# Run locally against the test store:
# maestro test -e MAESTRO_STORE=test_store Examples/rc-maestro/maestro/workflows/checkpoint_purchase_error_during_flow.yaml
# maestro test -e MAESTRO_STORE=test_store Projects/AutomatedSDKTestsApp/maestro/workflows/checkpoint_purchase_error_during_flow.yaml
appId: com.revenuecat.maestro.ios
name: A failed purchase in a checkpoint flow shows the SDK error and keeps the flow
@@ -3,7 +3,7 @@
#
# Fixtures live in the Automated SDK Tests project (6627e5bc). Do not edit them.
# Run locally against the test store:
# maestro test -e MAESTRO_STORE=test_store Examples/rc-maestro/maestro/workflows/checkpoint_purchase_obtains_entitlement_and_product.yaml
# maestro test -e MAESTRO_STORE=test_store Projects/AutomatedSDKTestsApp/maestro/workflows/checkpoint_purchase_obtains_entitlement_and_product.yaml
appId: com.revenuecat.maestro.ios
name: A purchase in a checkpoint flow reports the obtained entitlement and product
@@ -2,7 +2,7 @@
# app can continue.
#
# Run locally against the test store:
# maestro test -e MAESTRO_STORE=test_store Examples/rc-maestro/maestro/workflows/checkpoint_unknown_id_presents_nothing.yaml
# maestro test -e MAESTRO_STORE=test_store Projects/AutomatedSDKTestsApp/maestro/workflows/checkpoint_unknown_id_presents_nothing.yaml
appId: com.revenuecat.maestro.ios
name: An unknown checkpoint presents nothing
@@ -20,7 +20,7 @@
#
# Run locally against the test store:
# maestro test -e MAESTRO_STORE=test_store \
# Examples/rc-maestro/maestro/workflows/default_package_hidden_by_visibility_rule.yaml
# Projects/AutomatedSDKTestsApp/maestro/workflows/default_package_hidden_by_visibility_rule.yaml
appId: com.revenuecat.maestro.ios
name: Default-selected package hidden by a visibility rule falls back to a visible package
@@ -7,7 +7,7 @@
#
# Run locally against the test store:
# maestro test -e MAESTRO_STORE=test_store \
# Examples/rc-maestro/maestro/workflows/default_package_visible_stays_selected.yaml
# Projects/AutomatedSDKTestsApp/maestro/workflows/default_package_visible_stays_selected.yaml
appId: com.revenuecat.maestro.ios
name: Visible default-selected package stays selected
@@ -13,7 +13,7 @@
#
# Run locally against the test store:
# maestro test -e MAESTRO_STORE=test_store \
# Examples/rc-maestro/maestro/workflows/developer_provided_offering_filters_packages.yaml
# Projects/AutomatedSDKTestsApp/maestro/workflows/developer_provided_offering_filters_packages.yaml
appId: com.revenuecat.maestro.ios
name: Developer-provided offering renders only its own packages
@@ -2,7 +2,7 @@
# taps the back button, and asserts screen 1 is shown again.
#
# Run locally against the test store:
# maestro test -e MAESTRO_STORE=test_store Examples/rc-maestro/maestro/workflows/navigate_workflow_back.yaml
# maestro test -e MAESTRO_STORE=test_store Projects/AutomatedSDKTestsApp/maestro/workflows/navigate_workflow_back.yaml
appId: com.revenuecat.maestro.ios
name: Navigate a workflow paywall back to the first screen
@@ -6,7 +6,7 @@
# `navigate_back` action asserted below.
#
# Run locally against the test store:
# maestro test -e MAESTRO_STORE=test_store Examples/rc-maestro/maestro/workflows/navigate_workflow_sheet_back.yaml
# maestro test -e MAESTRO_STORE=test_store Projects/AutomatedSDKTestsApp/maestro/workflows/navigate_workflow_sheet_back.yaml
appId: com.revenuecat.maestro.ios
name: Navigate back from a workflow bottom sheet
@@ -3,7 +3,7 @@
# not surface an error.
#
# Run locally against the test store:
# maestro test -e MAESTRO_STORE=test_store Examples/rc-maestro/maestro/workflows/no_workflow_default_paywall.yaml
# maestro test -e MAESTRO_STORE=test_store Projects/AutomatedSDKTestsApp/maestro/workflows/no_workflow_default_paywall.yaml
appId: com.revenuecat.maestro.ios
name: Offering with no paywall or workflow renders the default paywall
@@ -3,7 +3,7 @@
# Local-only for now (not under e2e_tests/, so the CI lane does not run it).
#
# Run locally against the test store:
# maestro test -e MAESTRO_STORE=test_store Examples/rc-maestro/maestro/workflows/open_workflow.yaml
# maestro test -e MAESTRO_STORE=test_store Projects/AutomatedSDKTestsApp/maestro/workflows/open_workflow.yaml
appId: com.revenuecat.maestro.ios
name: Navigate a workflow paywall to purchase
@@ -3,7 +3,7 @@
# rendered literally.
#
# Run locally against the test store:
# maestro test -e MAESTRO_STORE=test_store Examples/rc-maestro/maestro/workflows/workflow_custom_variable_default.yaml
# maestro test -e MAESTRO_STORE=test_store Projects/AutomatedSDKTestsApp/maestro/workflows/workflow_custom_variable_default.yaml
appId: com.revenuecat.maestro.ios
name: Workflow paywall renders the custom variable default value
@@ -3,7 +3,7 @@
# argument) and asserts the overridden value (12345) renders instead of the dashboard default (50000).
#
# Run locally against the test store:
# maestro test -e MAESTRO_STORE=test_store Examples/rc-maestro/maestro/workflows/workflow_custom_variable_override.yaml
# maestro test -e MAESTRO_STORE=test_store Projects/AutomatedSDKTestsApp/maestro/workflows/workflow_custom_variable_override.yaml
appId: com.revenuecat.maestro.ios
name: Workflow paywall renders an overridden custom variable value
@@ -17,7 +17,7 @@
# the SDK regressed.
#
# Run locally against the test store:
# maestro test -e MAESTRO_STORE=test_store Examples/rc-maestro/maestro/workflows/workflow_exit_offer_closes_uikit.yaml
# maestro test -e MAESTRO_STORE=test_store Projects/AutomatedSDKTestsApp/maestro/workflows/workflow_exit_offer_closes_uikit.yaml
appId: com.revenuecat.maestro.ios
name: Workflow exit offer closes when presented from UIKit
@@ -4,7 +4,7 @@
# (top-center on the first page).
#
# Run locally against the test store:
# maestro test -e MAESTRO_STORE=test_store Examples/rc-maestro/maestro/workflows/workflow_exit_offer_not_on_first_page.yaml
# maestro test -e MAESTRO_STORE=test_store Projects/AutomatedSDKTestsApp/maestro/workflows/workflow_exit_offer_not_on_first_page.yaml
appId: com.revenuecat.maestro.ios
name: Workflow exit offer is not shown when closing the first page
@@ -4,7 +4,7 @@
# own close control is an unlabeled icon that flows can only tap by coordinate.
#
# Run locally against the test store:
# maestro test -e MAESTRO_STORE=test_store Examples/rc-maestro/maestro/workflows/workflow_exit_offer_on_last_page.yaml
# maestro test -e MAESTRO_STORE=test_store Projects/AutomatedSDKTestsApp/maestro/workflows/workflow_exit_offer_on_last_page.yaml
appId: com.revenuecat.maestro.ios
name: Workflow exit offer is shown when closing the last page
@@ -12,7 +12,7 @@
# never reaches the app, which then silently opens the default workflow.
#
# Run locally against the test store:
# maestro test -e MAESTRO_STORE=test_store Examples/rc-maestro/maestro/workflows/workflow_experiment_assigns_variant.yaml
# maestro test -e MAESTRO_STORE=test_store Projects/AutomatedSDKTestsApp/maestro/workflows/workflow_experiment_assigns_variant.yaml
appId: com.revenuecat.maestro.ios
name: A started experiment assigns each user their variant paywall
@@ -3,7 +3,7 @@
# maestro-experiment-user-1 resolves to variant A and maestro-experiment-user-2 to variant B.
#
# Run locally against the test store:
# maestro test -e MAESTRO_STORE=test_store Examples/rc-maestro/maestro/workflows/workflow_experiment_log_in_shows_user_variant.yaml
# maestro test -e MAESTRO_STORE=test_store Projects/AutomatedSDKTestsApp/maestro/workflows/workflow_experiment_log_in_shows_user_variant.yaml
appId: com.revenuecat.maestro.ios
name: Logging in shows the logged in user's experiment variant
@@ -3,7 +3,7 @@
# experiment step to its fallback and everyone follows variant A.
#
# Run locally against the test store:
# maestro test -e MAESTRO_STORE=test_store Examples/rc-maestro/maestro/workflows/workflow_experiment_not_started_serves_holdout.yaml
# maestro test -e MAESTRO_STORE=test_store Projects/AutomatedSDKTestsApp/maestro/workflows/workflow_experiment_not_started_serves_holdout.yaml
appId: com.revenuecat.maestro.ios
name: An experiment that was never started serves the holdout
@@ -12,7 +12,7 @@
# maestro-branch-1`, which iOS resolves from `customerInfo.originalAppUserId`.
#
# Run locally against the test store:
# maestro test -e MAESTRO_STORE=test_store Examples/rc-maestro/maestro/workflows/workflow_initial_branch_routes_audience.yaml
# maestro test -e MAESTRO_STORE=test_store Projects/AutomatedSDKTestsApp/maestro/workflows/workflow_initial_branch_routes_audience.yaml
appId: com.revenuecat.maestro.ios
name: An initial audience branch routes to a variant paywall
@@ -3,7 +3,7 @@
# including the CTA. Launch arguments set the app's locale for this run (no simulator reboot needed).
#
# Run locally against the test store:
# maestro test -e MAESTRO_STORE=test_store Examples/rc-maestro/maestro/workflows/workflow_localized_spanish.yaml
# maestro test -e MAESTRO_STORE=test_store Projects/AutomatedSDKTestsApp/maestro/workflows/workflow_localized_spanish.yaml
appId: com.revenuecat.maestro.ios
name: Workflow paywall renders Spanish localizations
@@ -8,7 +8,7 @@
# survives and the workflow renders from it.
#
# Run locally against the test store:
# maestro test -e MAESTRO_STORE=test_store Examples/rc-maestro/maestro/workflows/workflow_offline_cached.yaml
# maestro test -e MAESTRO_STORE=test_store Projects/AutomatedSDKTestsApp/maestro/workflows/workflow_offline_cached.yaml
appId: com.revenuecat.maestro.ios
name: Workflow offering renders from cache when reopened offline after a prior load
@@ -11,7 +11,7 @@
# presentable. The force_server_error_strategy launch argument is read by Constants.
#
# Run locally against the test store:
# maestro test -e MAESTRO_STORE=test_store Examples/rc-maestro/maestro/workflows/workflow_offline_fallback.yaml
# maestro test -e MAESTRO_STORE=test_store Projects/AutomatedSDKTestsApp/maestro/workflows/workflow_offline_fallback.yaml
appId: com.revenuecat.maestro.ios
name: Workflow offering renders the default paywall when config is offline with nothing cached
@@ -3,7 +3,7 @@
# and its icon-only button in the middle advances to screen 2.
#
# Run locally against the test store:
# maestro test -e MAESTRO_STORE=test_store Examples/rc-maestro/maestro/workflows/workflow_screen_without_text.yaml
# maestro test -e MAESTRO_STORE=test_store Projects/AutomatedSDKTestsApp/maestro/workflows/workflow_screen_without_text.yaml
appId: com.revenuecat.maestro.ios
name: Workflow screen without text renders and navigates
@@ -11,7 +11,7 @@ import SwiftUI
struct PurchaseView: View {
// An offering also used by rc-maestro's E2E tests, which only require it to have no paywall attached.
// An offering also used by AutomatedSDKTestsApp's E2E tests, which only require it to have no paywall attached.
private static let offeringIdentifier = "no_paywall"
@State private var activeEntitlements: String = "Loading..."
+1 -1
View File
@@ -3,12 +3,12 @@ import ProjectDescription
import ProjectDescriptionHelpers
var projects: [Path] = [
"./Examples/rc-maestro/",
"./Examples/MagicWeather/",
"./Examples/MagicWeatherSwiftUI/",
"./Examples/testCustomEntitlementsComputation/",
"./Examples/SampleCat/",
"./Projects/PurchaseTester",
"./Projects/AutomatedSDKTestsApp",
"./Projects/PaywallsTester",
"./Projects/APITesters",
"./Projects/PaywallValidationTester",
+5 -5
View File
@@ -1301,7 +1301,7 @@ platform :ios do
backend_environment = options[:backend_environment] || "production"
store = options[:store] || "app_store"
output_dir = options[:output_dir] || "test_output/maestro"
# Which subdirectory of Examples/rc-maestro/maestro to run flows from (e.g. "e2e_tests", "workflows").
# Which subdirectory of Projects/AutomatedSDKTestsApp/maestro to run flows from (e.g. "e2e_tests", "workflows").
flow_subdir = options[:flow_subdir] || "e2e_tests"
skip_slack_notification = options.fetch(:skip_slack_notification, true)
base_path = "#{Dir.pwd}/.."
@@ -1368,7 +1368,7 @@ platform :ios do
xcodebuild(
workspace: xcworkspace,
scheme: "Maestro",
scheme: "AutomatedSDKTestsApp",
sdk: "iphonesimulator",
configuration: "Debug",
derivedDataPath: "./build"
@@ -1376,11 +1376,11 @@ platform :ios do
# Install app to simulator
UI.message("Installing app to simulator...")
sh("xcrun", "simctl", "install", "booted", "#{base_path}/build/Build/Products/Debug-iphonesimulator/Maestro.app")
sh("xcrun", "simctl", "install", "booted", "#{base_path}/build/Build/Products/Debug-iphonesimulator/AutomatedSDKTestsApp.app")
if store == "app_store"
bundle_id = "com.revenuecat.maestro.ios"
storekit_config_path = "#{base_path}/Examples/rc-maestro/rc-maestro/Resources/StoreKit/app787ddb07e6.storekit"
storekit_config_path = "#{base_path}/Projects/AutomatedSDKTestsApp/AutomatedSDKTestsApp/Resources/StoreKit/app787ddb07e6.storekit"
# Start file watcher in background
UI.message("Starting StoreKit config file watcher...")
@@ -1397,7 +1397,7 @@ platform :ios do
success = false
begin
flow_dir = "#{base_path}/Examples/rc-maestro/maestro/#{flow_subdir}"
flow_dir = "#{base_path}/Projects/AutomatedSDKTestsApp/maestro/#{flow_subdir}"
previous_test_environment = {}
if store == "app_store"