Xcode UITest sometimes does not find property of XCUIElement
Solution 1
I contacted Apple, and they found my bug:
The view of my main view controller had its accessibility
property set to true
. This was wrong; it must be set to false
:
The explanation is found in the docs to isAccessibilityElement
:
The default value for this property is false unless the receiver is a standard UIKit control, in which case the value is true.
Assistive applications can get information only about objects that are represented by accessibility elements. Therefore, if you implement a custom control or view that should be accessible to users with disabilities, set this property to true. The only exception to this practice is a view that merely serves as a container for other items that should be accessible. Such a view should implement the UIAccessibilityContainer protocol and set this property to false.
As soon as I set accessibility of the main view to false, the UI test succeeded.
Solution 2
In addition with above answers... I would like to add one point This may happen because the XCUIElement you are accessing is not available on screen. Suppose you are executing test case for login screen and simulator is launching with dashboard not with login screen. This happen with my case. I tried to logout and then execute test case. Error disappears
Reinhard Männer
I learned programming 1968 on the PERM (Programmierbare elektronische Rechenanlage München), a monster one room wide and high, filled with electronic tubes (PERM was used by a number of Munich professors to develop ALGOL 60). As an assistant professor, I developed a 68000 based 30 processor system used for image processing and analysis of nuclear physics data. As a full professor at the Universities of Mannheim and Heidelberg, I developed together with Siemens/Munich the Synapse neuro computer, and many special purpose computers with applications in high energy physics and medicine, among them a systolic trigger processor with 28.600 processor elements. The ATLAS experiment at CERN used 1.700 of our special purpose computers to read out data, and eventually found the Higgs particle. Together with my PhD students, I cofounded a number of spinoff companies, among them Medical Communications GmbH, Volume Graphics GmbH, Silicon Software GmbH, Tesa Scribos GmbH and VRmagic GmbH. After retirement, I do iOS programming just for fun, and I am very interested in basic Physics problems like the foundations of Quantum Mechanics and Quantum Gravity.
Updated on July 10, 2022Comments
-
Reinhard Männer almost 2 years
In my UI tests, the frame property of some
XCUIElement
are found, but not of others.
The accessibility identifiers used below are set in storyboard, andapp
is initialised insetUp()
asXCUIApplication()
.Here is the storyboard layout:
The two UI elements used in the test are Text Field and Add Button.
Here is the relevant code:
func test() { // given let mainViewNavigationBar = app.navigationBars[„NavBar“] let navBarHeight = mainViewNavigationBar.frame.size.height print("navBarHeight: \(navBarHeight)") // is printed out correctly let addShoppingItemTextField = app.textFields["TextField"] let textFieldHeight = addShoppingItemTextField.frame.size.height // error breakpoint here print("textFieldHeight: \(textFieldHeight)") }
The test stops at an error breakpoint at the second last line with the following message:
No matches found for Find: Descendants matching type TextField from input {( Application, 0x60000019f070, pid: 13114, label: ‚xxx‘ )}
I do not understand why the
frame
property, which should be defined for allXCUIElement
, is found in the first case, but not in the second.EDIT
Oletha pointed out below, that my constant
addShoppingItemTextField
is anXCUIElementQuery
that should be resolved when I try to read theframe
property of thetextField
.
Indeed, when the program stops at the test error breakpoint and I print its description, I getPrinting description of addShoppingItemTextField: Query chain: →Find: Target Application 0x6080000a6ea0 ↪︎Find: Descendants matching type TextField ↪︎Find: Elements matching predicate '"TextField" IN identifiers'
But the find fails, although Accessibility is enabled, and the Accessibility Identifier is set to
TextField
:I also inserted in the app
print(textField.accessibilityIdentifier!)
in
viewDidLoad()
, and it printed outTextField
correctly.As a workaround, I set the test to recording, and tapped the
textField
. This created code for the access to thetextField
. I then replaced letaddShoppingItemTextField = app.textFields["TextField"]
by (the right side was generated by the recording):let addShoppingItemTextField = app.otherElements.containing(.navigationBar, identifier:"WatchNotOK") .children(matching: .other).element.children(matching: .other).element .children(matching: .other).element
And now the code works without errors.
So it seems to me that the query for the accessibility identifier of a
textField
does not work correctly.EDIT 2
I give up: Without changing anything in the storyboard, the test now stops with the same test error (No matches found for Find: Elements matching predicate '"WatchNotOK" IN identifiers‘) at the line
let navBarHeight = mainViewNavigationBar.frame.size.height
. This did work all the time.
This indicates to me that Xcode UI tests are broken. -
NRitH almost 5 yearsThanks for finding the fix, but I still don't see how the docs apply here. Does it mean that by disabling
isAccessibilityElement
for UI testing purposes, it will no longer be accessible when running the app in a non-testing environment? -
Reinhard Männer almost 5 yearsUp to now I used accessibility only for UI testing. But my understanding is that if accessibility is disabled for a custom view, it will no longer be accessible during normal (non UI testing) operation. However, views embedded in this custom „container“ view can still be accessible. So this should not be a limitation.
-
NRitH almost 5 yearsIn my case, it may be a limitation. I have four
UISwitch
es, each of which has an associatedUILabel
. I want to test the state of the switches, but I have to turn off their accessibility. Now, if I want them to be accessible at runtime, I can turn on accessibility for the view that contains each switch and its label, but then I have to manually update the accessibility label when the switch state changes. It would be better to keep the accessibility on for the user, so I may have to drop tests for the switches. -
Jayprakash Dubey over 2 years@ReinhardMänner: I'm not using Storyboard. Designed UI using thirdparty framework (similar to Swift UI) and also programmatically not setting any accessibility enable/disable.: