nalexn / ViewInspector

Runtime introspection and unit testing of SwiftUI views
MIT License
2.14k stars 147 forks source link

Better API for inspecting hierarchical lists #188

Open aaryankotharii opened 2 years ago

aaryankotharii commented 2 years ago

unable to test hierarchical list

UI taken from hackingwithswift

struct Bookmark: Identifiable {
    let id = UUID()
    let name: String
    let icon: String
    var items: [Bookmark]?

    // some example websites
    static let apple = Bookmark(name: "Apple", icon: "1.circle")
    static let bbc = Bookmark(name: "BBC", icon: "square.and.pencil")
    static let swift = Bookmark(name: "Swift", icon: "bolt.fill")
    static let twitter = Bookmark(name: "Twitter", icon: "mic")

    // some example groups
    static let example1 = Bookmark(name: "Favorites", icon: "star", items: [Bookmark.apple, Bookmark.bbc, Bookmark.swift, Bookmark.twitter])
    static let example2 = Bookmark(name: "Recent", icon: "timer", items: [Bookmark.apple, Bookmark.bbc, Bookmark.swift, Bookmark.twitter])
    static let example3 = Bookmark(name: "Recommended", icon: "hand.thumbsup", items: [Bookmark.apple, Bookmark.bbc, Bookmark.swift, Bookmark.twitter])
}

struct ListTest: View, Inspectable {
    let items: [Bookmark] = [.example1, .example2, .example3]

    var body: some View {
        List(items, children: \.items) { row in
            Image(systemName: row.icon)
            Text(row.name)
        }
    }
}

test written

class ListTests: XCTestCase {
    func testListKeyIcon() throws {
        let sut = ListTest()
        let text = try sut.inspect().list().text(0)
    }
}

error view(ListTest.self).list().text(0) found OutlineGroup<Swift.Array<WalletUITests.Bookmark>, Foundation.UUID, SwiftUI.TupleView<(SwiftUI.Image, SwiftUI.Text)>, SwiftUI.TupleView<(SwiftUI.Image, SwiftUI.Text)>, SwiftUI.DisclosureGroup<SwiftUI.TupleView<(SwiftUI.Image, SwiftUI.Text)>, SwiftUI.OutlineSubgroupChildren>> instead of Text

nalexn commented 1 year ago

Hey, in your specific case you can get to the Text using this chain:

let text = try sut.inspect().list().outlineGroup(0).leaf(Bookmark.example1).text(1)

I do find this quite verbose and unintuitive, I'll explore how to improve the experience of inspecting the hierarchical lists.