I have defined a DatePicker to have the compact style, as follows:
struct ContentView: View {
@State private var selectedDate = Date()
var body: some View {
DatePicker("Date Selected", selection: $selectedDate, displayedComponents: [.date])
.accessibilityIdentifier("DatePicker")
.datePickerStyle(.compact)
}
}
I have defined a UI test that taps on the DatePicker to show the DatePicker popup, then taps on one of the dates in the DatePicker popup to select that date, and then taps on the DatePicker again to dismiss the DatePicker popup, as follows:
func test_date_picker() {
let application = XCUIApplication()
// 0. Launch the app
application.launch()
// 1. Show the DatePicker popup
application.datePickers["DatePicker"].tap()
// 2. Change the selected date
application.datePickers.collectionViews.buttons["Friday, November 25"].tap()
// 3. Dismiss the DatePicker popup
application.datePickers["DatePicker"].tap()
}
This test works on iOS 14 and iOS 15 devices. Sadly, the final application.datePickers["DatePicker"].tap()
call is failing on iOS 16 devices because application.datePickers["DatePicker"]
is not hittable. How do I dismiss the DatePicker popup on iOS 16 devices?
For what it's worth, I'm running the test via Xcode 14.1 on iOS 16.1 simulator devices. I do not have a real iOS 16 device to hand so I cannot verify the behaviour on a real iOS 16 device.
Lastly, you can find a minimal application project that demonstrates the problem here.
It's because the object you're trying to tap()
isn't Hittable
- you can check that by adding an assertTrue
.
Here's a way to do it using an extension:
extension XCUIElement {
func forceTap() {
if(self.isHittable) {
self.tap()
} else {
let coordinate: XCUICoordinate = self.coordinate(withNormalizedOffset: CGVector(dx:0.0, dy:0.0))
coordinate.tap()
}
}
}
And call it with application.datePickers["DatePicker"].forceTap()
.