Reputation: 3817
I have a UIViewController
subclass with a corresponding view designed in interface builder. In interface builder, I've set an accessibility identifier on two labels and Accessibility
as a feature is enabled for both.
I want to define my app flow in code, so I load the VC by let vc = storyboard.instantiateViewController(withIdentifier: storyboardIdentifier) as? MyVC
rather than by defining segues in IB.
In viewDidLoad
, I can confirm that .accessibilityIdentifier
is set.
And yet, in my tests, the elements cannot be found. This always returns false:
let app = XCUIApplication()
app.staticTexts["myIdentifier"].waitForExistence(timeout: 10)
If I then go on to print out the view hierarchy:
print(app.debugDescription)
→Application, 0x280e55960, pid: 1609, label: 'My App'
Window (Main), 0x280e55a40, {{0.0, 0.0}, {320.0, 568.0}}
Other, 0x280e55c00, {{0.0, 0.0}, {320.0, 568.0}}
NavigationBar, 0x280e55ce0, {{0.0, 20.0}, {320.0, 44.0}}, identifier: 'Thing'
Button, 0x280e55ea0, {{0.0, 20.0}, {62.0, 44.0}}, label: 'Back'
Other, 0x280e55f80, {{130.5, 32.0}, {59.5, 20.5}}, label: 'Thing'
Other, 0x280e56060, {{0.0, 0.0}, {320.0, 568.0}}
Other, 0x280e56140, {{0.0, 0.0}, {320.0, 568.0}}
Other, 0x280e56220, {{0.0, 0.0}, {320.0, 568.0}}
Other, 0x280e56300, {{0.0, 64.0}, {320.0, 504.0}}
Image, 0x280e563e0, {{0.0, 248.0}, {320.0, 320.0}}, identifier: 'imageName'
I didn't set the identifier on Image
- UIImage(named: "imageName")
has done that automatically. The labels of interest are descendants of a sibling of the Image
(i.e. grandchildren of Other, 0x280e56300
)
I've read various guides (1, 2) and believe I'm doing everything as I should, and yet the elements remain hidden to the test framework.
Edited to add:
Since the app being tested is in a separate process, I added a UIAlertController
to confirm the .accessibilityIdentifier
of the labels of interest when their parent view appears in the context of being driven by the UI test mechanism - they are definitely set, but the testing framework just can't see them.
Upvotes: 3
Views: 4210
Reputation: 44
I ran into a similar issue after embedding a text field and UILabel into a stack view using the hierarchy tree in the document outline. Doing this resulted in the UILabel accessibility label returning nil even though it had a value. If I set its accessibility label programmatically then it returned a value.
Also, if I added a new UILabel (and set its accessibility label) to the storyboard, outside the stackview, and then built the app both UILabels had values for their accessibility labels. I could then remove the second UILabel without the original UILabel losing its accessibility label.
Hopefully, this makes sense. It's one of my first posts.
Upvotes: 0
Reputation: 3817
Having painstakingly recreated the view step by step, confirming that elements could be found by their .accessibilityIdentifier
at every step along the way, it was the final wrapping in a UIStackView
that "broke" things.
That is, while everything worked with this view hierarchy:
+ View
Safe Area
+ View
+ Stack view
Label
Label (with identifier)
+ Stack view
Label
Label (with identifier)
Image View
Wrapping the plain view and image view in another stackview to achieve this:
+ View
Safe Area
+ Stack view <-- problematic stack view
+ View
+ Stack view
Label
Label (with identifier)
+ Stack view
Label
Label (with identifier)
Image View
... broke things. Backtracking one step and achieving the same wrapping in a different way did not break accessibility.
Broke: Selecting View and Image View in the view hierarchy tree, then choosing embed in stackview from the icon in the editor pane.
Did not break: Selecting View and Image View in the designer and then choosing embed in stackview from the icon in the editor pane.
I realise this is a very anecdotal answer (and having lost more than half a day to this I've no intention of going back to break it again!), but it seems the way in which views are selected prior to embedding in a stack view makes a difference.
Upvotes: 4