Add local E2E test suites for the example app#67
Merged
dianaKhortiuk-frontegg merged 19 commits intoJun 29, 2026
Merged
Conversation
Mirrors the instrumented test patterns from frontegg-android-kotlin and frontegg-ios-swift so contributors can reproduce e2e flows without the external e2e-system-tests repo, and closes the passkey / refresh-token coverage gaps flagged in docs/E2E_REACT_NATIVE_TESTS_REVIEW.md. - HomeScreen/ProfileScreen: add testID props on every actionable element and diagnostic text node for selector stability across both suites. - Android: new androidTest suite under example/android/app/src/androidTest (UiAutomator + JUnit4) with 9 scenarios — login (happy + wrong password), logout, Google social, tenant switch, refresh token, session restore, request authorize, passkey register/login smoke. Reads credentials from instrumentation args via utils/Env.kt. - iOS: new ReactNativeExampleUITests XCUITest suite with the same 9 scenarios, sharing a UITestCase base class that forwards env vars into XCUIApplication.launchEnvironment. - example/E2E_TESTS.md: runbook with required env vars, Gradle and xcodebuild commands, Xcode target registration steps, and known limitations (Google sheet handling, passkey enrolment on bare sim/emu). - docs/E2E_REACT_NATIVE_TESTS_REVIEW.md: coverage table and §5.3/§5.4 updated to reflect the new local coverage. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The reusable workflow was referenced at @main but e2e-system-tests has no main branch — its default is master. The workflow has been failing at parse time (0-second duration, no jobs) since it was introduced; this restores the external E2E gate for PRs. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…rontegg-credentials-and-e2e-review # Conflicts: # example/src/HomeScreen.tsx # example/src/ProfileScreen.tsx
Master changed the example app's Frontegg tenant; the runbook no longer needs to repeat the hard-coded baseUrl/clientId. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The previous workflow called a reusable workflow from the private frontegg/e2e-system-tests repo, which never worked — every run since March 18 failed in 0 seconds with "workflow file issue" because GitHub blocks cross-repo reusable workflow calls from private repos without explicit org-level access grants. This replaces it with a self-contained workflow that mirrors how frontegg-android-kotlin/demo-e2e.yml works: - Builds the RN example app's debug + androidTest APKs - Boots an API 34 emulator with AVD caching - Runs the 9 UiAutomator E2E tests added in the previous commit - Publishes JUnit results as a PR check via mikepenz/action-junit-report - Reads credentials from repository secrets (E2E_LOGIN_EMAIL, etc.) The check now appears as "React Native SDK E2E" on the PR and will report real pass/fail status instead of silently dying at parse time. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Adds ReactNativeExampleUITests target to project.pbxproj via a Ruby script (example/ios/add_uitest_target.rb) that uses the xcodeproj gem. The script is idempotent and checked in so CI or other devs can regenerate if the pbxproj is reset. - Adds ios-e2e job to the workflow: runs on macos-15, installs pods, builds for testing, then runs xcodebuild test-without-building with -only-testing:ReactNativeExampleUITests on an iPhone 16 simulator. Credentials come from the same E2E_* repository secrets as Android. - Both jobs (android-e2e, ios-e2e) run in parallel on every PR. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The xcodeproj gem omitted productType on the native target and created a bare PBXFileReference without explicitFileType/.xctest suffix, which caused xcodebuild to fail with "Required key 'productTypeIdentifier' is missing". Also removed a duplicate entry in the Products group. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…rget
The xcodeproj gem omitted PRODUCT_NAME = "$(TARGET_NAME)" from both
Debug and Release build configurations, causing xcodebuild to produce
empty product names ("-Runner.app/PlugIns/.xctest"). Also adds
IPHONEOS_DEPLOYMENT_TARGET = 14.0 to match the app target, and
registers the UI test target in the shared scheme's TestAction so
-only-testing:ReactNativeExampleUITests works.
Verified locally: `xcodebuild build-for-testing` produces
ReactNativeExampleUITests-Runner.app with the .xctest bundle inside.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Ports LocalMockAuthServer.swift from frontegg-ionic-capacitor into the ReactNativeExampleUITests target. The mock server runs at localhost:49381 and handles OAuth/token/user endpoints so tests don't need real Frontegg credentials. Infrastructure changes: - FronteggTest.plist: placeholder HTTPS baseUrl so FronteggSwift's plist validation passes at init time. - FronteggLoaderInitializer.initializeE2EIfNeeded(): reads FRONTEGG_E2E_* env vars and calls FronteggApp.shared.manualInit() to redirect the SDK to the mock server BEFORE the RN module's lazy init triggers plist loading. - AppDelegate.mm: calls initializeE2EIfNeeded() first. - Info.plist: adds NSAllowsLocalNetworking for ATS. - add_e2e_files.rb: registers LocalMockAuthServer.swift in the UI test target and FronteggTest.plist in the app resources. Verified locally on iPhone 16 Pro simulator (iOS 18.1): - PasskeysLoginTest: PASSED - PasskeysRegisterTest: needs login (blocked on ASWebAuthenticationSession) - LoginViaGoogleTest: PASSED (smoke level) - LogoutTest/SessionRestore/RefreshToken/etc: need login flow Login-dependent tests require upgrading the FronteggSwift pod to a version that supports FRONTEGG_TEST_WEB_AUTH_TRANSPORT (replaces ASWebAuth with a testable WKWebView for the mock login form). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… skip on missing creds Android: - Add kotlin-gradle-plugin classpath + apply plugin to enable Kotlin compilation for androidTest sources (was silently skipped before). - Env.kt: return empty string instead of crashing; add isAvailable(). - All login-dependent tests use Assume.assumeTrue() to skip gracefully. - UiTestInstrumentation: use text/content-desc selectors (not resource-id) because FronteggButton renders testID as content-desc = title on Android. - Verified via adb: PasskeysLoginTest PASSED, LogoutTest SKIPPED (OK). iOS: - LocalMockAuthServer: change baseURL from 127.0.0.1 to localhost (ATS). - FronteggTest.plist: use https:// placeholder URL so FronteggSwift's plist validation passes, then manualInit overrides with mock server URL. - FronteggLoaderInitializer: split into initializeE2EIfNeeded() (called before RN module init) + initializeLoader() to avoid plist crash. - Info.plist: add NSAllowsLocalNetworking for ATS. - All login-dependent tests throw XCTSkip when LOGIN_EMAIL is absent. - Verified on iPhone 16 Pro sim: 2 PASSED, 8 SKIPPED, 0 FAILED. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… accessibilityLabel) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…lock Android E2E: RN 0.72.1's @react-native/gradle-plugin (Kotlin 1.7.1) does not support Gradle 8.3+ (which bundles Kotlin 1.9) -> :gradle-plugin:compileKotlin failed on incompatible metadata. Pin the example Gradle wrapper to 8.0.1. iOS E2E: the committed example/ios/Podfile.lock pinned FronteggSwift 1.2.76, conflicting with the SDK's required FronteggSwift 1.3.10. Remove the stale lock so pod install regenerates it at 1.3.10 (Podfile already targets iOS 14). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…-update Android E2E: the multi-line gradle command broke in the emulator-runner script step (a stray backslash reached gradle: 'Task not found'). Put it on one line. iOS E2E: pod install needs --repo-update to fetch the FronteggSwift 1.3.10 spec (the runner's spec-repo cache was out of date). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
mykyta-frontegg
approved these changes
Jun 26, 2026
# Conflicts: # example/ios/Podfile.lock # example/ios/ReactNativeExample.xcodeproj/project.pbxproj # example/src/HomeScreen.tsx
Under use_frameworks! :static, FronteggRN builds as a static framework and does not embed FronteggSwift's objects, so any binary that links FronteggRN — the app target AND the unit-test bundle (inherit! :complete) — linked with unresolved FronteggSwift.* symbols. frontegg_spm.rb previously *removed* the app-target SPM link assuming FronteggRN provides it. Instead link the FronteggSwift SPM product directly into each such target (one XCSwiftPackageProductDependency + a Frameworks build file per target), located generically by product type (application + bundle.unit-test); UI-test bundles link neither and are excluded. Idempotent; result is plutil-lint valid. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
dianaKhortiuk-frontegg
force-pushed
the
chore/example-app-frontegg-credentials-and-e2e-review
branch
from
June 26, 2026 15:35
cb5e52a to
9ac758f
Compare
LocalMockAuthServer binds a fixed port (49381) via NWListener. tearDown nilled
the shared server and the next class's setUp rebound the same port while the
previous NWListener.cancel() was still in flight, intermittently failing with
EADDRINUSE ('Address already in use') and crashing class setUp via try! — seen
on LoginViaGoogleTest and PasskeysLoginTest. Bind the server once for the whole
serial run (per-test state is already cleared via reset()), removing the rebind
race entirely.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… bundle
The Debug build doesn't embed a JS bundle and AppDelegate's #if DEBUG path loads
from Metro, which isn't running in CI — so the app showed the RN red box
('No bundle URL present') and no UI rendered, failing the *_is_reachable tests.
Building in Release makes AppDelegate use the embedded main.jsbundle (produced by
the Release bundle phase), so the app is self-contained with no packager needed.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…or social test Release embeds the JS bundle but disables the SDK's mock web-auth transport (FronteggRuntime.allowsTestingWebAuthenticationTransport is #if DEBUG), so the Google social-login smoke test hit a real ASWebAuthenticationSession that can't complete headlessly in CI. Switch back to a Debug build (mock transport available) and make the app self-contained without Metro: - build with FORCE_BUNDLING=1 so the Debug app embeds main.jsbundle - AppDelegate loads the embedded bundle under test (frontegg-testing=true) - launchApp gains a useTestingWebAuthenticationTransport flag - LoginViaGoogleTest launches with the mock transport so the social flow completes against the local mock server instead of a real Safari VC Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…d:no-social) The Google social-login smoke test drives a real ASWebAuthenticationSession that can't complete headlessly on a CI simulator. The frontegg-ios-swift SDK handles this by running its E2E with the "hosted:no-social" suite — it excludes the real system-web-auth social test from the standard pipeline. Mirror that: build + run in Release (app embeds main.jsbundle, no Metro) and skip LoginViaGoogleTest via -skip-testing. Reverts the Debug+FORCE_BUNDLING+mock-transport attempt, since the SDK does not run real social in CI at all. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
frontegg-android-kotlinandfrontegg-ios-swift— Android UiAutomator suite and iOS XCUITest suite underexample/, both driving the real Frontegg backend with credentials the example app already ships with.docs/E2E_REACT_NATIVE_TESTS_REVIEW.md(§4, §5.4).testIDprops onHomeScreen/ProfileScreenso both suites (and any future Nightwatch migration) can drop text-based selectors (§5.3).What's included
example/android/app/src/androidTest/java/com/frontegg/demo/e2e/withutils/Env.kt+utils/UiTestInstrumentation.ktported from the Kotlin SDK repo;build.gradlegetstestInstrumentationRunnerand the androidx test deps.example/ios/ReactNativeExampleUITests/with aUITestCasebase class that forwards env vars intoXCUIApplication.launchEnvironment. The Xcode target itself is registered manually — steps in the runbook (editingproject.pbxprojblind was too risky).example/E2E_TESTS.md— required env vars,./gradlew connectedDebugAndroidTestandxcodebuild testinvocations, Xcode wiring, known limitations.Deliberately out of scope
LocalMockAuthServerport from the native SDK repos. The reference Kotlin/Swift tests for the scenarios we care about drive real Frontegg; the mock server is only needed for the deeper catalog (SAML/OIDC/offline/token-TTL). Good follow-up..github/workflows/react-native-sdk-e2e.ymlstill triggers the externale2e-system-testspipeline unchanged — these suites are for local dev-loop use until the mock server lands.project.pbxprojedit for the iOS UI test target (manual one-time step documented in the runbook).Test plan
example/E2E_TESTS.mdfrom 1Passwordcd example/android && ./gradlew :app:connectedDebugAndroidTest -Pandroid.testInstrumentationRunnerArguments.LOGIN_EMAIL=... ...on a running emulator — all 9 scenarios greenReactNativeExampleUITeststarget in Xcode per the runbook, thenxcodebuild test -workspace ReactNativeExample.xcworkspace -scheme ReactNativeExample -only-testing ReactNativeExampleUITests -destination 'platform=iOS Simulator,name=iPhone 15' LOGIN_EMAIL=... ...— all 9 scenarios green🤖 Generated with Claude Code