Title: Runtime snapshot does not expose SwiftUI TabView tab items as actionable refs · Issue #439 · getsentry/XcodeBuildMCP · GitHub
Open Graph Title: Runtime snapshot does not expose SwiftUI TabView tab items as actionable refs · Issue #439 · getsentry/XcodeBuildMCP
X Title: Runtime snapshot does not expose SwiftUI TabView tab items as actionable refs · Issue #439 · getsentry/XcodeBuildMCP
Description: Summary With XcodeBuildMCP 2.6.0 runtime UI automation, SwiftUI TabView tab bar items can collapse into a single non-actionable Tab Bar element in snapshot-ui. The individual tabs are not exposed as targetable elementRefs, so agents stil...
Open Graph Description: Summary With XcodeBuildMCP 2.6.0 runtime UI automation, SwiftUI TabView tab bar items can collapse into a single non-actionable Tab Bar element in snapshot-ui. The individual tabs are not exposed a...
X Description: Summary With XcodeBuildMCP 2.6.0 runtime UI automation, SwiftUI TabView tab bar items can collapse into a single non-actionable Tab Bar element in snapshot-ui. The individual tabs are not exposed a...
Opengraph URL: https://github.com/getsentry/XcodeBuildMCP/issues/439
X: @github
Domain: github.com
{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"Runtime snapshot does not expose SwiftUI TabView tab items as actionable refs","articleBody":"### Summary\n\nWith XcodeBuildMCP 2.6.0 runtime UI automation, SwiftUI `TabView` tab bar items can collapse into a single non-actionable `Tab Bar` element in `snapshot-ui`. The individual tabs are not exposed as targetable `elementRef`s, so agents still have to rely on an app-side UIKit accessibility/automation bridge or coordinates to switch tabs.\n\nThis may be an AXe capture limitation rather than a bug in the JS runtime-snapshot normalizer, but it shows up as an XcodeBuildMCP UI automation gap because `wait-for-ui` and `tap --element-ref` can only act on elements present in the runtime snapshot.\n\n### Environment\n\n- XcodeBuildMCP: 2.6.0 (Homebrew)\n- Xcode: 26.5 / build 17F42\n- Simulator profile: clean disposable iOS simulator\n- App under test: generic SwiftUI iOS app using `TabView(selection:)` with `.tabItem { Label(...) }`, `.tag(...)`, and `.accessibilityIdentifier(\"tab_reports\")` on the tab content view\n\n`xcodebuildmcp doctor doctor --output json --style minimal` reported:\n\n- `serverVersion`: `2.6.0`\n- `axe`: `Available: Yes; UI automation: Yes; Video capture: Yes`\n- `manifest-tools`: `Total tools: 82; Workflows: 15`\n\n### Reproduction\n\n1. Build and launch a SwiftUI app with a standard tab view:\n\n```swift\nTabView(selection: $selectedTab) {\n NavigationStack { HomeView() }\n .accessibilityIdentifier(\"screen_home\")\n .tabItem { Label(\"Home\", systemImage: \"house\") }\n .tag(Tab.home)\n .accessibilityIdentifier(\"tab_home\")\n\n NavigationStack { ReportsView() }\n .accessibilityIdentifier(\"screen_reports\")\n .tabItem { Label(\"Reports\", systemImage: \"chart.bar\") }\n .tag(Tab.reports)\n .accessibilityIdentifier(\"tab_reports\")\n}\n```\n\n2. Capture a verbose runtime snapshot:\n\n```bash\nxcodebuildmcp ui-automation snapshot-ui \\\n --simulator-id \u003cUDID\u003e \\\n --output json \\\n --style minimal \\\n --verbose\n```\n\n3. Try waiting for the tab identifier or a tab role/label:\n\n```bash\nxcodebuildmcp ui-automation wait-for-ui \\\n --simulator-id \u003cUDID\u003e \\\n --predicate exists \\\n --identifier tab_reports \\\n --timeout-ms 7000 \\\n --output json \\\n --style minimal \\\n --verbose\n\nxcodebuildmcp ui-automation wait-for-ui \\\n --simulator-id \u003cUDID\u003e \\\n --predicate exists \\\n --label Reports \\\n --role tab \\\n --timeout-ms 7000 \\\n --output json \\\n --style minimal \\\n --verbose\n```\n\n### Actual result\n\nBoth waits time out with no candidates. The runtime snapshot contains a single `Tab Bar` element but no child tab controls and no actionable `Reports` target:\n\n```json\n{\n \"elementCount\": 7,\n \"targetCount\": 0,\n \"screenHash\": \"1aztj8k\"\n}\n```\n\nRelevant elements from `data.capture.elements`:\n\n```json\n[\n {\n \"ref\": \"e1\",\n \"role\": \"application\",\n \"label\": \"SampleTabApp\",\n \"frame\": { \"x\": 0, \"y\": 0, \"width\": 440, \"height\": 956 },\n \"actions\": []\n },\n {\n \"ref\": \"e3\",\n \"role\": \"other\",\n \"label\": \"Home\",\n \"actions\": [\"longPress\", \"touch\"]\n },\n {\n \"ref\": \"e7\",\n \"role\": \"other\",\n \"label\": \"Tab Bar\",\n \"frame\": { \"x\": 0, \"y\": 873, \"width\": 440, \"height\": 83 },\n \"actions\": [\"longPress\", \"touch\"]\n }\n]\n```\n\nThe action hints confirm there is no tappable tab target:\n\n```json\n{\"action\":\"longPress\",\"elementRef\":\"e7\",\"label\":\"Tab Bar\"}\n{\"action\":\"touch\",\"elementRef\":\"e7\",\"label\":\"Tab Bar\"}\n```\n\n`wait-for-ui --identifier tab_reports` and `wait-for-ui --label Reports --role tab` both return:\n\n```json\n{\n \"code\": \"WAIT_TIMEOUT\",\n \"message\": \"Timed out after 7000ms waiting for UI predicate 'exists'.\",\n \"candidates\": []\n}\n```\n\n### Expected result\n\nFor a standard SwiftUI `TabView`, the runtime snapshot should expose each visible tab item as a targetable element, ideally with:\n\n- role `tab` or an equivalent actionable role;\n- label such as `Reports`;\n- any available accessibility identifier from the tab item/content association, when iOS exposes it;\n- a `tap` action and stable `elementRef`.\n\nThat would let agents switch tabs using the v2.6 runtime workflow instead of coordinates or app-side UIKit overlays.\n\n### Workaround\n\nAn app-side UIKit overlay of transparent `UIButton`s at the tab bar frame works. In the same app/session, adding buttons with `accessibilityIdentifier` values like `tab_reports` produced runtime refs such as:\n\n```json\n{\n \"ref\": \"e11\",\n \"role\": \"button\",\n \"label\": \"Reports\",\n \"identifier\": \"tab_reports\",\n \"actions\": [\"tap\", \"longPress\", \"touch\"]\n}\n```\n\nThen `tap --element-ref e11` successfully navigated to the Reports screen and the refreshed snapshot reported `tab_reports` as selected.\n\nThat workaround is undesirable for SwiftUI-first apps, so it would be useful if XcodeBuildMCP/AXe could expose standard SwiftUI tab items directly.\n","author":{"url":"https://github.com/dpearson2699","@type":"Person","name":"dpearson2699"},"datePublished":"2026-06-02T06:29:50.000Z","interactionStatistic":{"@type":"InteractionCounter","interactionType":"https://schema.org/CommentAction","userInteractionCount":1},"url":"https://github.com/439/XcodeBuildMCP/issues/439"}
| route-pattern | /_view_fragments/issues/show/:user_id/:repository/:id/issue_layout(.:format) |
| route-controller | voltron_issues_fragments |
| route-action | issue_layout |
| fetch-nonce | v2:5f022843-9220-ee2a-0566-46ca5d3c053d |
| current-catalog-service-hash | 81bb79d38c15960b92d99bca9288a9108c7a47b18f2423d0f6438c5b7bcd2114 |
| request-id | BFF4:150C3:28074F3:388F5BF:6A4CECCD |
| html-safe-nonce | a84d6e277f5236eadb6c3f83df278483c95d03b08472fcc14a55c9d0f29fba6c |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiJCRkY0OjE1MEMzOjI4MDc0RjM6Mzg4RjVCRjo2QTRDRUNDRCIsInZpc2l0b3JfaWQiOiI3MDQxMzU5MDIyNTM2ODQ2NTQyIiwicmVnaW9uX2VkZ2UiOiJpYWQiLCJyZWdpb25fcmVuZGVyIjoiaWFkIn0= |
| visitor-hmac | 7938c4a4d75f3d47be54d75ce2e427ce0316babb19f702e638d01fce160bd43c |
| hovercard-subject-tag | issue:4569042492 |
| github-keyboard-shortcuts | repository,issues,copilot |
| google-site-verification | Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I |
| octolytics-url | https://collector.github.com/github/collect |
| analytics-location | / |
| fb:app_id | 1401488693436528 |
| apple-itunes-app | app-id=1477376905, app-argument=https://github.com/_view_fragments/issues/show/getsentry/XcodeBuildMCP/439/issue_layout |
| twitter:image | https://opengraph.githubassets.com/618e3b6ff4da12f5ba5da2e95df8a67ea5a47eb2464e6f7c036ea8cb93872acf/getsentry/XcodeBuildMCP/issues/439 |
| twitter:card | summary_large_image |
| og:image | https://opengraph.githubassets.com/618e3b6ff4da12f5ba5da2e95df8a67ea5a47eb2464e6f7c036ea8cb93872acf/getsentry/XcodeBuildMCP/issues/439 |
| og:image:alt | Summary With XcodeBuildMCP 2.6.0 runtime UI automation, SwiftUI TabView tab bar items can collapse into a single non-actionable Tab Bar element in snapshot-ui. The individual tabs are not exposed a... |
| og:image:width | 1200 |
| og:image:height | 600 |
| og:site_name | GitHub |
| og:type | object |
| og:author:username | dpearson2699 |
| hostname | github.com |
| expected-hostname | github.com |
| None | 299b43bca6e02ad35197ffeba30d2466846d5fb02ab96fbced5b5e6cec589fb8 |
| turbo-cache-control | no-preview |
| go-import | github.com/getsentry/XcodeBuildMCP git https://github.com/getsentry/XcodeBuildMCP.git |
| octolytics-dimension-user_id | 1396951 |
| octolytics-dimension-user_login | getsentry |
| octolytics-dimension-repository_id | 945551361 |
| octolytics-dimension-repository_nwo | getsentry/XcodeBuildMCP |
| octolytics-dimension-repository_public | true |
| octolytics-dimension-repository_is_fork | false |
| octolytics-dimension-repository_network_root_id | 945551361 |
| octolytics-dimension-repository_network_root_nwo | getsentry/XcodeBuildMCP |
| turbo-body-classes | logged-out env-production page-responsive |
| disable-turbo | false |
| browser-stats-url | https://api.github.com/_private/browser/stats |
| browser-errors-url | https://api.github.com/_private/browser/errors |
| release | efec6750a5afcaeaf5dfcf629f404cf98c8371e3 |
| ui-target | full |
| theme-color | #1e2327 |
| color-scheme | light dark |
Links:
Viewport: width=device-width