Why can’t I find elements using `AppiumBy.accessibilityId` in Appium 2 for iOS native apps?

I previously used MobileBy.AccessibilityId(“Continue”)and it worked fine for a system modal button on iOS. After upgrading to Appium 2, usingAppiumBy.accessibilityId(“Continue”) no longer finds the element.

When inspecting the screen with Appium Inspector, the modal doesn’t appear, but Xcode’s Accessibility Inspector shows the button label. Before the upgrade, my scripts could locate it without issue.

I need detailed steps to reliably find this button in Appium 2.

A quick thing to check: in Appium 2, system dialogs and iOS modals often live outside your app’s main process. That’s why AppiumBy.accessibilityId(“Continue”) may fail even though Xcode’s Accessibility Inspector shows it.

You can handle these system-level buttons using the alert API:

if driver.switch_to.alert:
    driver.switch_to.alert.accept()

Or, set this capability to automatically accept alerts:

caps = {
    "platformName": "iOS",
    "deviceName": "iPhone",
    "app": "/path/to/app",
    "autoAcceptAlerts": True
}

This ensures your tests don’t hang on system dialogs. For elements inside your app, AppiumBy.accessibilityId should continue working as before.

Appium 2 relies more strictly on XCTest’s accessibility tree. If a button isn’t appearing in Appium Inspector, it might not be in the app’s context. In my projects, switching to an iOS predicate string solved the issue:

from appium.webdriver.common.appiumby import AppiumBy

button = driver.find_element(
    AppiumBy.IOS_PREDICATE, "label == 'Continue' AND type == 'XCUIElementTypeButton'"
)
button.click()

Predicate locators tend to be much more reliable than accessibility on iOS 2.x, especially for modals or dynamically loaded elements.

Another approach is checking your current context. Sometimes your test is still in a webview or wrong native context, which makes accessibilityId fail. Switching to NATIVE_APP fixed it for me:

contexts = driver.contexts
driver.switch_to.context("NATIVE_APP")
driver.find_element(AppiumBy.ACCESSIBILITY_ID, "Continue").click()

Also, if the button still doesn’t show in Appium Inspector, it may be a true system alert. In that case, handling it via alert APIs or autoAcceptAlerts is the way to go.