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:
Here's the code:
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?
You can find a minimal application project that demonstrates the problem here.
I posted this same question on the Apple Developer Forums (here) and got back a response that has worked for me.
The idea is to define a forceTap()
extension function on the XCUIElement class, as follows:
extension XCUIElement {
func forceTap() {
if (isHittable) {
tap()
} else {
coordinate(withNormalizedOffset: CGVector(dx:0.0, dy:0.0)).tap()
}
}
}
Explanation: If the XCUIElement instance is hittable, then the XCUIElement instance's tap() function is called. Otherwise, an XCUICoordinate instance is created for a point within the XCUIElement instance and that XCUICoordinate instance's tap() function is called instead.
The final line of my test function is now changed to the following:
application.datePickers["DatePicker"].forceTap()