How do I get the number of elements matching an identifier, say "fooImage" returned by an XCUIQuery?
Asked Answered
C

2

8

lets say I have a table with three images whose accessiblityIdentifier set to "fooImage".

XCTAssertTrue(table["tableName"].images.count == 3) will work, but this is sucky -- what if someone adds another image type? I want the count of all the images whose identifier == "fooImage".

XCUIApplication().images["fooImage"].count is a compile fail with Value of type 'XCUIElement' has no member 'count'.

Carleecarleen answered 28/2, 2018 at 18:14 Comment(0)
T
14

Using subscripting on an XCUIElementQuery will give you an XCUIElement which doesn't have a count property. You wanna use count on an XCUIElementQuery like this.

XCUIApplication().images.matching(identifier: "fooImage").count
Tar answered 1/3, 2018 at 15:33 Comment(0)
M
1

To allow this with XCUIElement, it has a private query getter. Since the private API would be used only in UI tests (and thus not embedded within the app), there's no risk of rejection, but it is still vulnerable to internal changes, so use if you know what this means.

The following extension can be used to add the wanted behavior:

extension XCUIElement {
    @nonobjc var query: XCUIElementQuery? {
        final class QueryGetterHelper { // Used to allow compilation of the `responds(to:)` below
            @objc var query: XCUIElementQuery?
        }

        if !self.responds(to: #selector(getter: QueryGetterHelper.query)) {
            XCTFail("Internal interface changed: tests needs updating")
            return nil
        }
        return self.value(forKey: "query") as? XCUIElementQuery
    }

    @nonobjc var count: Int {
        return self.query?.count ?? 0
    }
}

The extension will fail the test if the internal interface ever changes (if the internal query getter gets renamed), preventing tests from suddenly not working without explanations (this code has been tested with the latest Xcode available at the time, Xcode 10 beta 6).

Once the extension has been added, the code in the question XCUIApplication().images["fooImage"].count will compile and have the expected behavior.

Mcginn answered 30/8, 2018 at 19:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.