Accessing nested UIElements in Xcode 7 UI Testing
Asked Answered
O

4

5

I am having trouble locating XCUIElements on a screen for the app I am testing. I realize you can access a button for example via something like:

app.buttons[].elementBoundByIndex(0)

But the problem is sometimes, the component is not found. Like in a case where I have a Button in a cell in a UITableView. I try to make an XCUIElementQuery to find the button, and it is not there. I try to look for tables or tableviews or collection views and even though they are in the view controller, they are not found in UI Testing. The count of the returned array will be zero.

I attempted originally to record the test, but clicking the element I am trying to access did not work. Xcode detected it as an "Other Element" and when trying to tap during, playback the application does not advance.

Is there a high level way to access a component like a UIView high in the UI hierarchy to cascade down?

Ordonnance answered 2/10, 2015 at 17:43 Comment(4)
Did you ever resolve this issue? do you have a link to the dev forums post you mentioned?Unbalance
Can't find a link but it was in one of these: forums.developer.apple.com/welcomeOrdonnance
In any case, try setting a breakpoint when you hit the area you're trying to debug. Then po print(app.debugDescription). You will see the hierarchy then.Ordonnance
We had to solve it by removing a few accessibility identifiers on superviews in the stack. Not ideal but did get it working without changing actual functionality.Unbalance
O
7

I didn't know this at the time, but what I was looking for was basically debugDescription:

Set a breakpoint when you hit the area you're trying to debug. Then

po print(app.debugDescription)

in the debug console. You will see the hierarchy then.

Ordonnance answered 14/4, 2016 at 17:53 Comment(1)
Thank you! This saves me so much trial & error, every time I encounter a nested element that cannot be foundMousterian
C
5

Ideally you should set an accessibilityIdentifier on your button and search for it via that. The accessibilityIdentifier should be unique for elements on the screen. You can set an accessibilityIdentifier in the Identity Inspector in Interface Builder (command-option-3) or in code directly. Once you have one, the query looks like:

app.buttons["SomeAccessibilityIdentifier"]
Courtenay answered 2/10, 2015 at 18:1 Comment(5)
Ideally, that's how it's supposed to work. I manually went into the storyboard and added an accessibility identifier to the element, but this doesn't work. It can't find the element by Accessibility Label or by Accessibility Identifier. Does the XCUIElementQuery propagate from the head of the tree all the way through to the leaves?Ordonnance
By default it does search all descendants, not just children. Is this button coming on screen due to a screen transition, and perhaps it isn't present yet when you're querying for it? If you use the test recording functionality can you get the recording to interact with the button? Also, if you enable the accessibility inspector (Simulator Settings app -> General -> Accessibility), can you select the button and inspect its traits?Courtenay
Hmmmm, no, it doesn't seem to pick it up. In fact, it looks like it selects the view, just like Xcode 7's recorder seems to do (I had already tried recording). There is an open discussion on the Apple Developer Forums between someone having the same issue and a Dev at Apple though. Maybe it has something to do with the way the UI for that particular view is structured.Ordonnance
Likely that's the case, but you may want to double check that accessibility is enabled for that button.Courtenay
My experiences have been that the accessibility elements only get found when running on-device tests, but not in the simulator.Hiroshima
I
0

Ryan Poolos answer was the best answer for me as it solved my issue with nested UI Elements

We had to solve it by removing a few accessibility identifiers on superviews in the stack. Not ideal but did get it working without changing actual functionality. – Ryan Poolos

So with that in mind, I found the xib file with the element in question, selected the element, selected the tab "Show the Identity Inspector" on the right panel and unchecked the Accessibility checkbox.

right panel

I then did a recording of the element which resulted in:

[[[[[XCUIApplication alloc] init].scrollViews.tables childrenMatchingType:XCUIElementTypeOther] elementBoundByIndex:index] childrenMatchingType:XCUIElementTypeButton].element;

Notice how XCUIElementTypeOther is in the query. This was not the case when the accessibility identifiers were enabled as I would get:

    [[[[[XCUIApplication alloc] init].scrollViews.tables.otherElements containingType:XCUIElementTypeStaticText identifier:@"username"] childrenMatchingType:XCUIElementTypeButton].element tap];

Obviously I wouldnt know the username as it would always change and this was a major problem. But after removing the accessibility identifiers,

containingType:XCUIElementTypeStaticText identifier:@"username"

changed to

childrenMatchingType:XCUIElementTypeOther] elementBoundByIndex:index

SUCCESS :)

Irreconcilable answered 17/11, 2016 at 19:25 Comment(0)
E
-1

In my own experience you being able to find an element (an UIView in your case as UIButton inherits from UIview) through its accessibilityIdentifier depends on how you added it to the view.

I assume that in your case you added the button to the cell programatically with addSubView. If that's the case, probably you will not be able to access to it. I've had the same problem and asked the question here but no proper solution at the moment, so my advice is try to avoid adding views with addSubView the moment...

Evelunn answered 28/6, 2016 at 11:10 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.