Skip to content

ci: run StoreKit tests on Mac Catalyst with Xcode 26#6897

Draft
ajpallares wants to merge 14 commits into
mainfrom
pallares/mac-catalyst-tests
Draft

ci: run StoreKit tests on Mac Catalyst with Xcode 26#6897
ajpallares wants to merge 14 commits into
mainfrom
pallares/mac-catalyst-tests

Conversation

@ajpallares

Copy link
Copy Markdown
Member

Checklist

  • If applicable, unit tests
  • If applicable, create follow-up issues for purchases-android and hybrids

Motivation

StoreKit unit tests can't fetch products on iOS simulators with Xcode 26.4+ due to a StoreKit bug. This adds a Mac Catalyst test job on Xcode 26.5 to keep StoreKit coverage on a current Apple platform, where the bug doesn't reproduce.

Description

  • New run-test-mac-catalyst-xcode-26 job wired into the test/snapshot workflows and merge gates, with a mac-catalyst-26 snapshot bucket.
  • The host app is ad-hoc signed so SKTestSession gets an app container; unsigned, its config writes fail with SKInternalErrorDomain Code=3, which breaks dialog suppression and purchases.
  • setSimulatedError-based tests are compiled out on Catalyst (no macabi slice in the StoreKitTest overlay — Apple bug FB22922982).

Made with Cursor

ajpallares and others added 8 commits June 3, 2026 10:27
Adds a Mac Catalyst test job that runs the full iOS test plan (including
StoreKit tests) on the Mac Catalyst variant with Xcode 26.5, to check
whether the StoreKit product-fetching bug that breaks iOS simulator tests
on Xcode 26.4+ also reproduces on Mac Catalyst.

Wires the job into the run-all-tests and release workflows and adds it to
the all-tasks-passed / all-tests-succeeded merge gates.

Co-authored-by: Cursor <cursoragent@cursor.com>
The StoreKitTest framework's Swift overlay (setSimulatedError(_:forAPI:)
and FailableStoreKitAPI) ships no Mac Catalyst (macabi) slice in Xcode
26.5, so tests using it fail to compile for Catalyst. Guard those tests
out / skip them on Catalyst. testPurchaseFailureClearsPresentedPaywall is
kept defined (skipped at runtime) to satisfy PurchasesOrchestratorTests.

Also fix MockPurchases.presentCodeRedemptionSheet(), which implemented a
requirement marked @available(macCatalyst, unavailable): guard it with
!targetEnvironment(macCatalyst) to match StoreKit1Wrapper.

Regenerates fastlane/README.md for the new test_catalyst lane.

Co-authored-by: Cursor <cursoragent@cursor.com>
SKTestSession purchases come back as userCancelled on Mac Catalyst (the
purchase dialog can't be suppressed in this headless environment), so the
three SK2 tests that require a real completed purchase fail there. Skip
them on Catalyst for now via XCTSkip; they keep running on all other
platforms. Product fetching itself works fine on Catalyst.

Co-authored-by: Cursor <cursoragent@cursor.com>
Route Mac Catalyst snapshots into their own `mac-catalyst-26` bucket,
teach the `test_catalyst` lane to record snapshots via the CI-Snapshots
test plan, and wire `run-test-mac-catalyst` into the snapshot generation
workflow + snapshot PR step.

Co-authored-by: Cursor <cursoragent@cursor.com>
Document the filed feedback (FB22922982) for the missing StoreKitTest
macabi slice in the comments and XCTSkip message.

Co-authored-by: Cursor <cursoragent@cursor.com>
A fully unsigned Mac Catalyst app has no application container, so
SKTestSession cannot persist its configuration (disabling dialogs,
clearing transactions, storefront overrides) and every write fails with
SKInternalErrorDomain Code=3. That made purchase dialogs reappear and SK2
purchase tests come back userCancelled on Catalyst.

Ad-hoc signing the host app (CODE_SIGN_IDENTITY=-, the equivalent of
Xcode's "Sign to Run Locally") gives it a stable container, so the config
writes succeed. With dialogs now suppressed, the three SK2 purchase tests
that previously had to be skipped on Catalyst pass again.

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
@RevenueCat-Danger-Bot

RevenueCat-Danger-Bot commented Jun 3, 2026

Copy link
Copy Markdown
1 Warning
⚠️ This PR increases the size of the repo by more than 100.00 KB (increased by 242.72 KB).

Generated by 🚫 Danger

Co-authored-by: Cursor <cursoragent@cursor.com>
@ajpallares

Copy link
Copy Markdown
Member Author

@RCGitBot please test run-test-mac-catalyst-xcode-26

@github-actions

github-actions Bot commented Jun 3, 2026

Copy link
Copy Markdown

🚀 Triggered run-test-mac-catalyst-xcode-26Pipeline #38754

@RevenueCat-Danger-Bot

RevenueCat-Danger-Bot commented Jun 3, 2026

Copy link
Copy Markdown

❌ CI Job Failed — run-test-mac-catalyst-xcode-26

View Build

Failed Tests

  • InstallmentsInfoFactoryTests/testBuildInstallmentsInfoForMonthlyBillingPlanAndEverySixMonthsCommitment()
  • InstallmentsInfoFactoryTests/testBuildInstallmentsInfoForMonthlyBillingPlanAndEveryThreeMonthsCommitment()
  • InstallmentsInfoFactoryTests/testBuildInstallmentsInfoForMonthlyBillingPlanAndEveryTwoMonthsCommitment()
  • InstallmentsInfoFactoryTests/testBuildInstallmentsInfoForMonthlyBillingPlanAndMonthlyCommitment()
  • InstallmentsInfoFactoryTests/testBuildInstallmentsInfoForMonthlyBillingPlanAndYearlyCommitment()
  • InstallmentsInfoFactoryTests/testBuildInstallmentsInfoReturnsNilForUnknownBillingPlan()
  • InstallmentsInfoFactoryTests/testBuildInstallmentsInfoReturnsNilForUnsupportedCommitmentPeriod()
  • InstallmentsInfoFactoryTests/testBuildInstallmentsInfoReturnsNilForUpFrontBillingPlan()
  • PurchasesLogInTests/testCompletionBlockLogInWithStaticStringLogsMessage()

ajpallares and others added 4 commits June 3, 2026 20:02
These tests ran for the first time on Mac Catalyst and asserted iOS- or
macOS-native behavior that doesn't hold there:

- PurchasesDiagnosticsTrackingTests: exclude Catalyst, where
  presentCodeRedemptionSheet() is unavailable (would crash with an
  unrecognized selector).
- SandboxEnvironmentDetectorTests: route Catalyst to the macOS branch,
  since it detects sandbox via the receipt environment, not the URL path.
- LocalReceiptParserStoreKitTests: treat Catalyst like macOS for the
  receipt applicationVersion.
- HTTPClientTests: group Catalyst with iOS for identifierForVendor, which
  uses UIDevice (always present) there rather than the macOS sandbox gate.

Co-authored-by: Cursor <cursoragent@cursor.com>
…urchases-ios into pallares/mac-catalyst-tests
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.

3 participants