Skip to content

Fix iOS 26 bottom tab test IDs#8254

Open
yedidyak wants to merge 5 commits intomasterfrom
bugfix/ios-26-tab-testid
Open

Fix iOS 26 bottom tab test IDs#8254
yedidyak wants to merge 5 commits intomasterfrom
bugfix/ios-26-tab-testid

Conversation

@yedidyak
Copy link
Contributor

Summary

  • sync each bottom tab item testID onto the underlying tab view so Detox can still find tabs when iOS 26/Xcode 26 no longer exposes the UITabBarItem identifier directly
  • re-apply the sync after tab creation, child option merges, and layout, with a short retry for delayed tab view creation
  • keep the existing UITabBarItem accessibilityIdentifier behavior intact while propagating the same identifier to the actual tab button view

Context

The engine already passes tab test IDs through bottomTab.testID (for example in packages/wix-one-app-engine/src/services/Navigator.ts), but RNN only assigned that identifier to UITabBarItem. This appears to be insufficient on newer iOS/Xcode 26 tab hierarchies, similar to the recent back-button testID regression.

Verification

  • git diff --check
  • attempted xcodebuild -project ios/ReactNativeNavigation.xcodeproj -scheme ReactNativeNavigation -sdk iphonesimulator -configuration Debug build CODE_SIGNING_ALLOWED=NO under Xcode 26.2; the build is currently blocked by the existing missing header ios/ReactNativeVersionExtracted.h, but the changed files got through the Objective-C compile phase before that unrelated failure

Reference

@yedidyak yedidyak requested a review from Copilot March 19, 2026 16:35
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR addresses an iOS 26/Xcode 26 Detox regression where bottom tab testIDs are no longer discoverable via UITabBarItem alone, by propagating each tab item’s accessibilityIdentifier onto the underlying tab button view and re-applying it across lifecycle events.

Changes:

  • Add logic in UITabBarController (RNNOptions) to copy UITabBarItem.accessibilityIdentifier onto the corresponding tab bar item view (with a delayed retry).
  • Expose a new syncTabBarItemTestIDs API on the UITabBarController (RNNOptions) category.
  • Invoke syncTabBarItemTestIDs after tab item creation, option merges, and layout in RNNBottomTabsController.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
ios/UITabBarController+RNNOptions.mm Implements syncing tab item testIDs to tab button views and schedules a retry when views aren’t available yet.
ios/UITabBarController+RNNOptions.h Exposes syncTabBarItemTestIDs for callers to trigger re-syncs.
ios/RNNBottomTabsController.mm Calls syncTabBarItemTestIDs after tab creation, child option merges, and during layout.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates the iOS bottom tabs implementation to keep Detox testIDs discoverable on iOS 26/Xcode 26 by propagating each tab’s UITabBarItem.accessibilityIdentifier onto the underlying tab button view, and re-syncing during key lifecycle/option-merge points.

Changes:

  • Add logic on UITabBarController to sync per-tab testIDs from UITabBarItem to the underlying tab view, with a short delayed retry when tab views aren’t created yet.
  • Invoke the sync after tab bar item creation, after child option merges, and after layout in RNNBottomTabsController.
  • Expose syncTabBarItemTestIDs via the UITabBarController (RNNOptions) header for internal use.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
ios/UITabBarController+RNNOptions.mm Implements tab button view testID propagation + retry scheduling via associated objects.
ios/UITabBarController+RNNOptions.h Exposes syncTabBarItemTestIDs for callers.
ios/RNNBottomTabsController.mm Calls syncTabBarItemTestIDs during creation, option merging, and layout.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR addresses an iOS 26 / Xcode 26 regression where bottom tab testIDs are no longer discoverable via UITabBarItem alone by syncing the same identifier onto the underlying tab bar button views so Detox can reliably locate tabs.

Changes:

  • Add logic on UITabBarController to propagate each UITabBarItem.accessibilityIdentifier to the corresponding tab bar item view, with a short delayed retry.
  • Expose a syncTabBarItemTestIDs API in the UITabBarController (RNNOptions) category.
  • Call the sync method after tab creation, child option merges, and in viewDidLayoutSubviews within RNNBottomTabsController.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
ios/UITabBarController+RNNOptions.mm Implements syncing UITabBarItem testIDs onto underlying tab views with associated-object retry state.
ios/UITabBarController+RNNOptions.h Exposes syncTabBarItemTestIDs on the options category.
ios/RNNBottomTabsController.mm Triggers testID sync after tab item creation, option merges, and layout.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the iOS bottom tabs implementation to keep Detox-accessible test IDs working on newer iOS/Xcode 26 tab bar hierarchies by syncing each UITabBarItem.accessibilityIdentifier onto the underlying tab button view (UITabBarButton) and retrying briefly if the view is not created yet.

Changes:

  • Add a syncTabBarItemTestIDs utility on UITabBarController that copies each tab item’s accessibilityIdentifier onto the corresponding tab button view, preserving/restoring any pre-existing view identifier.
  • Add a short, bounded retry loop to handle delayed tab button view creation.
  • Invoke the sync after tab item creation, child option merges, and during layout in RNNBottomTabsController.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.

File Description
ios/UITabBarController+RNNOptions.mm Implements syncing tab item testIDs to tab button views with associated-object state and retry.
ios/UITabBarController+RNNOptions.h Exposes syncTabBarItemTestIDs on the UITabBarController (RNNOptions) category.
ios/RNNBottomTabsController.mm Calls the sync hook after tab creation, option merges, and layout to keep identifiers applied.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants