Find parent or sibling with Xcode UI testing
Asked Answered
V

2

13

I am working with UITableViews and I would like to find the cell that corresponds to a control or static text inside the cell.

More generally, a good way to find any parent or sibling of a given element would be great to know.

Right now I'm just looping through cells until I find the correct one, which I would like to avoid. I've tried using app.tables.cells.containingPredicate, but haven't had any luck.

let pred = NSPredicate { (element, bindings: [String : AnyObject]?) -> Bool in
      return element.staticTexts["My Text"].exists
}
let cells = app.tables.cells.containingPredicate(pred)

The element passed to the predicate block is an XCElementSnapshot which has no staticTexts.

EDIT

James is correct, the containingType:identifier: method works great.

In swift, it looks like this

let cell = app.tables.cells.containingType(.StaticText, identifier: "My Text")

Where the identifier in the method signature does NOT correspond to the element's identifier property, rather it is simply the regular way you would access an element by text in brackets.

app.cells.staticTexts["My Text"] 
Vibrio answered 3/12, 2015 at 13:52 Comment(5)
I'm still confused as of why app.cells.staticTexts["My Text"] didn't work for you. If the string "My Text" belongs to any cell, the snapshot of your app's accessibility hierarchy would find the string and match it. The containingType:identifier: method creates an XCUIElementQuery, and this does not mean the XCUIElement from this query actually exists in your app.Strongwilled
app.cells.staticTexts[] would give me back a static text, i.e. UILabel, whereas I needed the UITableViewCell, not the labelVibrio
I see. Correct me if I'm wrong, but doing let cell = app.tables.cells.containingType(.StaticText, identifier: "My Text") is creating a XCUIElementQuery, not an XCUIElement, so you're not actually instantiating an element in your app, just creating a query to an element that might not even exist. If on console you do po app.tables.cells.containingType(.StaticText, identifier: "blah blah") it will always return an object even if it doesn't exist, and you can't run any assertions on an XCUIElementQuery, or even the .exist or .hittable methods to see if your element is real.Strongwilled
@FranciscoJ.Mejias you can use .element to get the element for the query, and then assertions on thatVibrio
got it, so you're doing app.tables.cells.containingType(.StaticText, identifier: "My Text").element.exists for example. Thank you for helping me understand =)Strongwilled
B
15

Have you tried using containingType instead of containingPredicate? It seems to give you exactly what you're looking for. I'm not too familiar with Swift, but in Objective C, it will look like this:

[app.cells containingType:XCUIElementTypeStaticText identifier:@"My Text"];
Backspin answered 4/12, 2015 at 2:13 Comment(5)
I thought the 'identifier' in the method was the element's identifier property, thanks for the correctionVibrio
Swift: app.cells.staticTexts["My Text"]Acidimeter
@JoeMasilotti Any idea why the method signature is identifier: , but that doesn't correspond to the identifier property on XCUIElement? XCUIElementQuery's identifier is the stuff in brackets?Vibrio
@Vibrio Awesome, I'm glad it helped!Backspin
@Vibrio The X in staticTexts["X"]can be used to match an accessibility label, accessibility identifier, title, name, and/or value depending on the element in question. I have not found a definitive answer to which is used for which.Acidimeter
P
1

Here's an example of a way I found to get a sibling element. I was trying to get to a price element based on a specified name element where I had no IDs to work with.

I had an xml structured more or less like this:

 <pre><code>Other
                  Other 
                       Cell
                           Other
                           Other
                           StaticText
                           Other
                           StaticText, label: 'Name1'
                           StaticText, label: '$5.00'
                       Cell
                           Other
                           Other
                           StaticText
                           Other
                           StaticText, label: 'Name2'
                           StaticText, label: '$2.00' </code></pre>

I wanted to get the label text for the price of 'Name1' or 'Name2'.

I used the following to get to the element: app.cells.containing(nameNSPredicate).children(matching: .staticText).element(matching: priceNSPredicate).firstMatch

Pellegrino answered 15/6, 2021 at 21:14 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.