You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I have been using ViewInspector with good success, but seem to have become stuck on how to correctly inspect a view and wonder if you could help me get my thinking straight:
Given this view:
public struct PersonCardView: View {
var data: PersonCardData
let actions: TimelineEntryActions
public var body: some View {
PersonCardViewContent(data: data)
.onTapGesture {
actions.onTap()
}
}
}
public struct PersonCardViewContent: View {
var data: PersonCardData
static let minHeight: CGFloat = 250
public var body: some View {
PersonCardHStack {
PersonCardTextBlock(data: data)
if let image = data.image {
PersonCardImage(image: image)
}
}
.padding(EdgeInsets(
top: 0,
leading: TimelineViewMetrics.cardPaddingLeading,
bottom: 0,
trailing: 0
))
.frame(minHeight: PersonCardView.minHeight)
.cardBackground()
}
}
I can successfully test that the onTap gesture is correctly wired up with this test:
func testA10_viewIsCorrectlyWiredToAction_onTap() throws {
// Setup actions to test
let expectation = expectation(description: "Action called")
let minimalData = PersonCardData(
type: .undefined,
timestamp: Date(),
givenName: "",
familyName: "",
jobTitle: "",
department: "",
organization: "",
image: nil
)
let actions = actions(expectation, onTap: true)
// Inspect view
let view = PersonCardView(data: minimalData, actions: actions)
let target = try view.inspect().find(PersonCardViewContent.self)
// Process under test
try target.callOnTapGesture()
// Expectation
waitForExpectations(timeout: 0.1)
}
However, the only reason that the view is structured with the separate PersonCardViewContent was to get the test to pass. The actual SwiftUI view I originally wanted to test was basically the same, but with the onTapGesture just attached directly to the contents of the body:
public struct PersonCardView: View {
var data: PersonCardData
let actions: TimelineEntryActions
static let minHeight: CGFloat = 250
public var body: some View {
PersonCardHStack {
PersonCardTextBlock(data: data)
if let image = data.image {
PersonCardImage(image: image)
}
}
.padding(EdgeInsets(
top: 0,
leading: TimelineViewMetrics.cardPaddingLeading,
bottom: 0,
trailing: 0
))
.frame(minHeight: PersonCardView.minHeight)
.cardBackground()
.onTapGesture {
actions.onTap()
}
}
}
In this case, I tried using .find(PersonCardView.self) as the target, but that would not trigger the expectation as the onTapGesture is not on that view, it's on the first child of that view...
PersonCardHStack is a custom SwiftUI layout, and I am unsure how to target it or its contents. I am sure this is a key contributor. It seems like in the PRs that have previously been addressed that it is possible to now target contents of custom layouts, but I am clearly missing something.
I would appreciate any pointers, so I don't have to change my view structure just to make this action wiring testable.
The text was updated successfully, but these errors were encountered:
babbage
changed the title
Inspection of onTap gesture
Inspection of onTap gesture on custom Layout
May 13, 2024
I have since modified the test to target the PersonCardViewContent by using:
let target = try view.inspect().find(PersonCardView.self).first!
This lets me make PersonCardViewContent no longer public, which is nice and what I'd prefer to do, since no other view should be instantiating that view. However, I can't use this approach with the originally preferred view structure... if I do, the target ends up being the PersonCardTextBlock and the test fails saying:
failed: caught error: "PersonCardTextBlock does not have 'onTapGesture' modifier"
I have been using ViewInspector with good success, but seem to have become stuck on how to correctly inspect a view and wonder if you could help me get my thinking straight:
Given this view:
I can successfully test that the
onTap
gesture is correctly wired up with this test:However, the only reason that the view is structured with the separate
PersonCardViewContent
was to get the test to pass. The actual SwiftUI view I originally wanted to test was basically the same, but with the onTapGesture just attached directly to the contents of the body:In this case, I tried using
.find(PersonCardView.self)
as the target, but that would not trigger the expectation as the onTapGesture is not on that view, it's on the first child of that view...PersonCardHStack
is a custom SwiftUI layout, and I am unsure how to target it or its contents. I am sure this is a key contributor. It seems like in the PRs that have previously been addressed that it is possible to now target contents of custom layouts, but I am clearly missing something.I would appreciate any pointers, so I don't have to change my view structure just to make this action wiring testable.
The text was updated successfully, but these errors were encountered: