Element Lookup Issues
This article helps to resolve possible functional issues that may arise during element lookup, where the desired element is either not found or has unexpected property values. Such issues can manifest with several symptoms.
For non-functional issues, such as slow performance during element lookup, please refer to the WebDriverAgent Slowness guide.
No Element in Page Source¶
The desired element is shown as part of a parent element container, and is not individually distinguishable in the page source tree. Sometimes the entire application view is shown as one single element container.
Ensure application accessibility¶
The XCUITest driver is based on Apple's XCTest framework, which uses the information provided by the system accessibility framework to distinguish and interact with on-screen elements. The same approach is used by various screen readers, VoiceOver, etc. This means that if the application is missing accessibility indicators for certain elements, then they may not be visible.
You may start your journey into what Accessibility is and how to deal with it in your applications from the official Apple's accessibility guideline. Bear in mind that this tutorial only describes apps based on official Apple frameworks like UIKit or SwiftUI. If you use a different framework to build the application's user interface, for example React Native, then consider looking for framework-specific accessibility guidelines.
It is also possible that the source tree displayed in the Xcode accessibility inspector differs from
the tree generated by XCTest. The best possible way to verify the page source generated by the
latter is to check the output of the debugDescription
attribute of the corresponding XCUIApplication element. The XCUITest driver exposes this
functionality using the mobile: source execute
method with format set to description.
Check if this is a hybrid application¶
Hybrid applications are applications that use web views in order to represent their whole user interface or portions of it. The iOS web view engine only allows for limited accessibility interactions via ARIA attributes, which may result in certain elements being absent.
One approach to handle this is to switch the driver context in order to get full native access to the page DOM. Read Automating Hybrid Apps for more details.
For app developers, setting aria-label
and role
attributes allow exposing web elements to the accessibility tree, as accessibilityLabel
in WKWebView. The primary purpose of these attributes is to make web elements accessible for
tools such as VoiceOver, but they also expose these elements to the XCUITest driver's NATIVE_APP
context. Consider adding these attributes to elements that you want to expose to the driver.
Adjust the tree depth¶
Apple's XCTest represents the page source as hierarchical structure (a tree), where each UI element
has ancestor, descendant or sibling relationships to other elements. Complex applications with
deeply nested views may therefore result in tree structures of large depth. For performance reasons,
the XCUITest driver sets the maximum nesting level to 50, which means that elements of depth 51
or greater will not be visible at all.
The driver allows to increase this limit using the snapshotMaxDepth
setting, but only to a maximum value of 62. This is due to an Apple limitation, where XCTest
cannot return any elements located at depth 63 or greater. This limitation is linked to the
operation of NSDictionary and cannot be worked around.
The suggested approach for handling the depth limit of 62 is to refactor the code of the
actual application under test. For example, applications built using React Native
are known to create deeply nested view hierarchies. There are several approaches that can help
mitigate this:
- Try to remove unnecessary nesting levels
- Use the Fabric renderer with View Flattening
- Use native stack navigator instead of stack navigator
- Reduce the amount of view tags/test IDs
Check the corresponding issue for more details.
Deeply nested hierarchies might also be the reason for the element lookup slowness. Read the Diagnosing WebDriverAgent Slowness article to troubleshoot such cases.
Select the correct active application¶
Certain UI elements may appear as though they belong to the application under test, but are actually part of a completely different application (oftentimes the iOS system itself - the springboard). Application ownership of certain elements may even change in different iOS versions. Frequent candidates for such behavior are:
- System alerts, such as camera or geolocation permission requests
- Quick access toolbars, such as Control Center
- Various RPC sheets, such as the Share To sheet
WebDriverAgent is designed in such a way that it only interacts with a single app hierarchy at a
time. This is considered the active application. The driver provides two approaches to change
the active app:
- The
mobile: activateAppexecute method allows to explicitly change the currently active application - The
defaultActiveApplicationsetting allows to set the preferred active application. This means that if WebDriverAgent detects multiple applications, it will attempt to automatically set the preferred application as active.
Check the main Troubleshooting guide and/or Switching Between iOS Apps During a Test article for more details on how to make such elements available.
Test Cannot Find a Known Element¶
The desired element is shown in the page tree, but cannot be found using an automated test.
Check for race conditions¶
Sometimes automation might run too quickly or too slowly depending on the application's UI state. This means lookup may fail before the element has appeared, or after it has already disappeared.
- If lookup is too fast: consider using timers, e.g. repeat the
findElementaction multiple times until either the element is found or the timeout occurs. All clients have convenience wrappers for such timers in form of expected conditions. - If lookup is too slow: try to optimize your script for the maximum performance, e.g. use optimal/fast element locators, adjust the application and driver settings to perform optimally, etc.
You may also encounter situations where the automation framework is already optimized, but the
target element disappears quickly by design, for example, a notification popup that only appears
for a second and then is immediately hidden. For such "special" elements, consider using approaches
different from findElement:
- Post-test video recording analysis (video FPS should usually be enough to catch all short-living elements)
- Work with application developers to introduce a debug setting to change the behavior for such elements and make them stay visible for longer time
- Use non-UI-related assertions, like log analysis or direct API calls
Check for environment mismatches¶
There are known cases where the application interface/behavior might differ in simulators and real devices. It might even differ if the screen size or device model/OS version/system setting differs. That is why always make sure that your test development environment, such as one where Appium Inspector is used, is as close as possible to the environment where automated tests are run.
Incorrect Element Property Value¶
The desired element is shown in the page tree, but the value of a certain element property is not
as expected. For example, the element's visible property may be set to true, even though the
element is not actually shown in the application interface, or vice versa.
The driver has minimum influence to attribute values¶
This is a simple and at the same time complicated topic.
Since the XCUITest driver is based on Apple's XCTest, where possible, attribute values are retrieved from the latter. The standard attributes provided by XCTest can be found in XCUIElementAttributes protocol reference, while the full list of attributes supported by XCUITest driver's WebElement can be found in the Element Attributes document.
Most of the supported driver attributes are simple compilations of standard XCTest attributes. For
example, elementType is translated to type by matching the corresponding enum
value to a string representation, while name is compiled from the original element's identifier
and label, depending on what is present first. The full list of mapping rules between standard and
XCUITest attribute values can be found in WebDriverAgent sources.
Still, some supported driver attributes, like visible or accessible, have no direct mapping in
XCTest and are retrieved directly from the accessibility framework using dark magic.
This means that the actual value of these attributes depends on accessibility internals, and is
available mostly due to legacy convenience purposes, since XCTest does not even expose them.
We'd love to deprecate and remove this legacy burden and only rely on officially supported
attributes, but historically many people rely on these attributes, even though their values might
be not reliable, and there is no good way to debug this behavior or somehow influence it.
The final recommendation here would be:
- If the problematic attribute is based on a public XCUIElement attribute, try to run a vanilla XCTest test with the same app, and compare the attribute value to the one you see in the XCUITest driver. If XCTest returns a correct value, then feel free to raise an issue to the Appium team. However, if the XCTest value is still incorrect, then the only place to complain would be the Apple support forum or an XCTest bug tracker.
- If the problematic attribute is a "custom" driver attribute, like
visibleoraccessible, then we, most likely, won't be able to help you. You may try to contribute to the corresponding WebDriverAgent sources, but keep in mind that many automation tests rely on the current way these attributes are calculated, and we probably don't want to break them.
Long Element Property Value is Truncated¶
The desired element is shown in the page tree, but the value of a certain long element property is truncated and not fully shown.
Use value retrieval methods¶
The XCTest framework limits element property values to 512 bytes in snapshots for performance reasons. Such behavior can primarily be observed when retrieving the full page source using the driver, or via debugDescription in XCTest directly.
The solution here is to retrieve the property value using the corresponding API (such as Get Element Attribute / Get Element Text). Please see this issue and this PR for more details.