Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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'.

like image 742
ablarg Avatar asked Feb 28 '18 18:02

ablarg


2 Answers

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
like image 145
Titouan de Bailleul Avatar answered Jan 03 '23 11:01

Titouan de Bailleul


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.

like image 34
Stéphane Copin Avatar answered Jan 03 '23 10:01

Stéphane Copin