iOS Snapshot Element Support

This page tracks how snapshot -i presents common iOS interaction surfaces. It is scoped to the XCTest-backed iOS snapshot path and the default non-raw presentation. Use snapshot --raw or snapshot --json when investigating the provider tree itself.

Sources used for this checklist:

Status Key

StatusMeaning
SupportedExpected to produce one actionable, unambiguous node in snapshot -i.
Pass-throughPreserved when XCTest exposes it, but no custom iOS presentation shaping yet.
Command-supportedHandled by a dedicated command rather than snapshot presentation.
Needs fixtureKnown common element, but we still need raw tree and screenshot-overlay samples before claiming support.
Out of scopeUseful UI information, but not an interaction target for snapshot -i.

Matrix

Apple/HIG areaCommon iOS surfaceExpected XCTest/accessibility shapeCurrent supportTested withNotes
Menus and actionsButton, toolbar button, pull-down or menu buttonButton, sometimes wrapped in Other with the same label/rectSupportedSettings rows, Expensify Home, Expensify action menuSame-rect Other -> Button wrappers collapse to the button. Descendant duplicate text/image decoration is suppressed.
Menus and actionsLinkLink, sometimes wrapped in repeated static/link nodesSupportedUnit fixture from Settings privacy link shapeRepeated link/static descendants collapse to one link. Needs more live Safari/Mail coverage.
Selection and inputSwitch toggleCell -> Button -> Switch, or a standalone SwitchSupportedSettings Camera live screen, unit fixtureRow-backed switch collapses to the switch control, not the row/button wrapper.
Selection and inputToggle buttonUsually Button with selected/value/trait semanticsPass-throughNone yetWe keep the button. Need real samples to decide whether selected/value should be surfaced more explicitly.
Selection and inputCheckboxCheckBox/Checkbox or button-like custom nodePass-throughNone yetCommon on macOS and web-like/custom iOS apps. Interactive filtering keeps role strings containing checkbox, but iOS shaping has no special checkbox rules.
Selection and inputRadio button/groupRadioButton, RadioGroup, or button-like custom nodesPass-throughNone yetInteractive filtering keeps role strings containing radio. Need grouped native/custom samples.
Selection and inputText fieldTextField, SecureTextField, or wrapper Other -> TextFieldSupportedExpensify Search, unit fixtureFillability already recognizes text/search/secure/text-view types. Wrapper collapses to the editable node.
Selection and inputSearch fieldSearchField, often inside toolbar/search wrappersSupportedSettings search field, Expensify search fieldSettings toolbar duplicates collapse to one search field plus Dictate button.
Selection and inputText view / multiline editorTextView/TextAreaPass-throughUnit coverage for read/fill helpersFillability recognizes text views, but iOS presentation has no live complex editor sample yet.
Selection and inputToken fieldTextField, token cells/buttons, or custom wrappersNeeds fixtureNone yetNeed Mail/Calendar recipient-field samples. Likely mixed editable field plus token buttons.
Selection and inputDigit entry / OTPMultiple TextFields, one hidden text field, or custom key gridNeeds fixtureNone yetWe should avoid collapsing distinct digit boxes until tested.
Selection and inputSliderSlider, usually adjustable and rect-backedPass-throughNone yetsnapshot -i keeps rect-backed controls. Need Settings volume/brightness samples to verify value formatting and adjustability.
Selection and inputStepperStepper or increment/decrement buttonsNeeds fixtureNone yetNeed native examples to decide whether to expose one adjustable control or separate buttons.
Selection and inputSegmented controlSegmentedControl with segment buttons, or collapsed adjustable-like controlNeeds fixtureNone yetCurrent workflow docs still call out horizontal tab/filter bars that may collapse into one composite. Needs real-app coverage.
Selection and inputPicker / picker wheelPicker, PickerWheel, option cells, or modal sheetNeeds fixtureNone yetNeed Clock/Calendar/Settings samples. We should not over-collapse value wheels before testing.
Selection and inputDate pickerDatePicker, calendar buttons, picker wheels, compact button + popoverNeeds fixtureNone yetTest compact, inline, and wheels styles separately.
Selection and inputVirtual keyboard and keysKeyboard, KeyCommand-supportedExpensify SearchOffscreen keyboard subtrees are suppressed when they are below the app viewport. Keyboard interaction belongs to keyboard/fill/type; visible app-owned Done buttons remain normal buttons.
Navigation and searchNavigation bar / toolbarNavigationBar, Toolbar, title text, bar buttonsSupportedSettings, Expensify SearchNavigation/action buttons remain; duplicated title/search wrapper nodes are suppressed when they duplicate semantic children.
Navigation and searchTab barTabBar, tab buttons, or custom Other nodesPass-throughExpensify HomeExpensify tabs are exposed as distinct Other items. Need native UITabBar samples to decide if TabBar container should stay visible or collapse.
Navigation and searchSidebar/list navigationTable, CollectionView, Cell, row button wrappersSupportedSettings top/bottom, Expensify listsRow-backed Settings cells collapse to a single Cell. Scroll-hidden above/below hints stay on the scroll container.
Navigation and searchSearch results listScrollView/Table/CollectionView plus rowsSupportedExpensify SearchRepeated legitimate list rows do not trigger the duplicate-nav warning when they are stacked instead of overlapping.
Menus and actionsContext menu / edit menuMenu, MenuItem, sheet/popover, or transient system surfaceNeeds fixtureNone yetNeed long-press samples from Photos/Files/Text selection.
Menus and actionsActivity/share viewSheet with buttons, collections, extension cellsNeeds fixtureNone yetTreat as normal app/system UI until samples show duplication patterns.
PresentationAlertAlert plus buttons, or native alert command resultCommand-supportedProvider testsUse alert wait/get/accept/dismiss for native alerts. Snapshot should still be inspected when an app-owned sheet looks like an alert.
PresentationSheet, bottom sheet, popoverSheet/Popover/Other wrappers plus buttons/fieldsSupported for common wrappersExpensify action menuBackdrop dismiss and action-row wrappers collapse when semantic children are present. Need native sheet/popover examples.
StatusActivity indicator, progress indicator, gaugeActivityIndicator, ProgressIndicator, Other with valueOut of scopeNone yetThese are important state, but not primary interaction targets. They should stay in full snapshots; snapshot -i may omit them unless rect-backed.
StatusPage control / page indicatorPageIndicator, adjustable trait, dots/buttonsNeeds fixtureNone yetOften interactive via swipe or adjustable actions. Need samples before deciding presentation.
Layout and organizationStatic text, headers, images, decorationStaticText, Image, OtherSupported as descendants/noiseSettings, ExpensifyRepeated static/link/image descendants under an actionable parent are suppressed. Standalone useful text remains visible when retained by the interactive tree.
Layout and organizationScroll bars / scroll indicatorsOther with labels like vertical scroll barSupportedSettings top/bottom, Expensify listsScroll indicator nodes are removed from the interactive tree and converted into [content above/below ... hidden] hints on the nearest scroll container.
Layout and organizationCollection/table/scroll containersCollectionView, Table, ScrollViewSupportedSettings, ExpensifyContainers remain when they communicate scrollability or hidden content.

Next Apps To Sample

Use snapshot -i, snapshot -i --raw --json, and screenshot --overlay-refs for each sample before updating this page.

Element familySuggested apps/screens
Slider / page indicatorSettings > Sounds & Haptics, Photos onboarding/carousel, Control Center if accessible
Segmented controlsPhotos library filters, Calendar view switcher, App Store tabs/filters
Picker/date pickerClock alarm editor, Calendar event editor, Reminders date picker
StepperCalendar/Reminders repeat or count fields, any system form that exposes increment/decrement
Token fieldMail compose recipients, Calendar invitees
Context/edit menuFiles long-press, Photos long-press, text selection in Notes
Native tab barApp Store, Phone, Photos
Share/activity sheetPhotos share, Safari share

When adding coverage, record:

  • app and screen;
  • shaped snapshot -i output;
  • raw snapshot -i --raw --json node shape for the relevant subtree;
  • overlay screenshot path;
  • whether the result is supported, pass-through, or needs implementation work.

Need React or React Native expertise you can count on?