Elements Lookup Troubleshooting
This article helps to resolve possible issues that may pop up while looking up for elements with XCUITest driver, where the desired element is either not found or not visible in the page source at all.
Since there might be multiple reasons to why an element cannot be found the topic is divided into sections where each section contains visible symptoms with the list of their possible resolutions.
Symptom #1¶
The desired element is shown as part of a bigger container and is not distinguishable in the page source tree. Sometimes the whole application view with all elements in it is visible as one single container.
Resolutions To Symptom #1¶
Make sure the application under test is accessible¶
The XCUITest driver is based on Apple's XCTest framework. And the latter uses the information provided by the system
accessibility framework to interact with on-screen elements, and to distinguish them. The same approach is used by
various screen readers, VoiceOver, etc. 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 Xcode accessibility inspector differs from the tree geneerated
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. XCUITest driver allows to perform a direct forwarding for this API by
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. Web views is the technology that allows to seamlessly integrate web pages browsing experience into native mobile applications. Applications might contain native views mixed with web views, or the whole application UI might be just a single web view. And while the built-in web view engine allows limited accessibility interactions via ARIA attributes, consider switching a driver context instead in order to get full native access to the page DOM. Read Automating Hybrid Apps for more details there.
Make sure the application accessibility tree is not too deep¶
Apple's XCTest represents the page source as hierarchical structure (a tree), where each UI element has ancestor and
descendant relationships to other elements. There are applications having complex UI structure with deeply nested
views. Such deep structures are known to create problems for XCTest as the latter is unable to work with tree elements
whose nesting level is deeper than 62
. This limitation has to do with how NSDictionary
works and cannot be worked
around. The default maximum nesting level for the XCUITest driver is set to 50
and could be customized by the
snapshotMaxDepth setting.
React Native is known to create
such deep hierarchies and the only viable solution for now is to fix the application
under test by flattening nested views. 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 the latter.
Make sure a valid active application is selected in WebDriverAgent¶
Sometimes, even if visually it looks like UI elements belong to the same application, they are referenced by absolutely different apps. Moreover, the operating system may change elements ownership in different versions. In the UI inspector it looks like visually the element is visible, but no "real" accessibility control relies on it. Most frequent candidates for such behavior are: - System alerts, for example camera or geolocation permission requests - Quick access toolbars, for example the one where Wi-Fi or Bluetooth state could be changed - Various RPC sheets, for example the Share To collection
WebDriverAgent is designed the way it only interacts with a single app hierarchy at the particular
moment of time. Such application is called active
.
It is possible to switch between applications in runtime using
mobile: activateApp API or
to provide a hint for WebDriverAgent on which application to prefer if multiple apps are running
using the defaultActiveApplication setting.
Check the Troubleshooting guide and/or
Switching Between iOS Apps During a Test
article for more details on how to make such elements available.
Symptom #2¶
The desired element is shown in the page tree, but cannot be found if looked up from an automated test.
Resolutions To Symptom #2¶
Make sure there is no race condition¶
Sometimes the automation might too fast or too slow depending on in which state the UI is while the lookup is being
executed. If it is too fast then consider using lookup timers, e.g. repeat the findElement
more than once until
either the element is found or the timeout occurs. All clients have convenience wrappers for such timers in form of
expected conditions.
If the automation is too slow, e.g. the desired element disappears faster than findElement
could detect its presence
then make sure your script is optimized for the maximum performance, e.g. optimal/fast element locators are used,
the application itself and driver settings are adjusted to perform optimally, etc.
There might be situations where the automation framework is already optimized, although the desired element is
a short-living one, for example some notification popup that only appears for a second and then is immediately hidden.
For such "special" elements consider using approaches different from findElement
, for example post-test video recording analysis (video FPS should usually be enough to catch all short-living elements), or introducing special
application debug settings to change the behavior for such elements and make them stay visible for longer time, or
using non-UI-related assertions, like logs analysis or direct API calls.
Make sure the debug environment matches to the testing one¶
There are known cases where 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 your debug environment, for example one where Appium Inspector is used, is as close as possible to the environment where automated tests are being executed.
Symptom #3¶
The desired element is shown in the page tree, but its property value is not as expected, for example, it is shown as visible while one does not see it in the application interface or vice versa.
Resolutions To Symptom #3¶
XCUITest driver has minimum influence to attribute values¶
This is a simple and at the same time complicated topic. Since XCUITest driver is based on Apple's XCTest,
all attribute values are retrieved from the latter. Standard attributes provided by XCTest could be found in
XCUIElementAttributes
protocol reference. The full list of attributes supported by XCUITest driver's WebElement
could be found in the Element Attributes document.
Most of the above attributes are simple compilations of standard attributes, for example, elementType
is
translated to type
by matching the corresponding
enum value to a string representation, name
is compiled from original element's identifier and label depending on what is
present first. The full list of mapping rules between standard and XCUITest attribute values could be found in
WebDriverAgent sources.
Although, some attributes there, like visible
or accessible
have no direct mapping in XCTest
and are retrieved directly from the accessibility framework ~~using dark magic~~.
This means the actual value of these attributes only depends on accessibility internals and is there
mostly due to ~~legacy~~ convenience purposes, as the original XCTest does not even expose them.
We'd love to deprecate and remove this legacy burden and only rely on officially supported attributes,
although historically many people rely on them, so we keep it, 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 there would be:
- If the value of an attribute that directly or indirectly relies on a public XCUIElement attribute
is different from what you expect then run a vanilla XCTest with the same app and make sure
it's not the same as you see in the XCUITest driver. If it is then the only place to complain
would be the Apple support forum or a XCTest bug tracker. If you can confirm the issue lies in
WebDriverAgent's mapping logic then feel free to raise an
issue to its maintainers.
- If the value of an attribute that is a "custom" XCUITest attribute, like visible
or accessible
,
is different from what you expect then we, most likely, won't be able to help you. You may try
to improve the corresponding WebDriverAgent sources, but keep in mind there are many automation
tests around that rely on the current way these attributes are calculated, and we probably don't
want to break them.