如何在 iOS 16 设备上运行的 UI 测试中关闭 DatePicker 弹出窗口?

问题描述 投票:0回答:1

我定义了一个DatePicker以具有compact样式,如下:

struct ContentView: View {
    
    @State private var selectedDate = Date()
    
    var body: some View {
        DatePicker("Date Selected", selection: $selectedDate, displayedComponents: [.date])
            .accessibilityIdentifier("DatePicker")
            .datePickerStyle(.compact)
    }
}

我定义了一个 UI 测试:

  1. 点击 DatePicker 以显示 DatePicker 弹出窗口;然后
  2. 点击 DatePicker 弹出窗口中的日期之一来选择该日期;然后
  3. 再次点击 DatePicker 可关闭 DatePicker 弹出窗口。

这是代码:

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()
}

此测试适用于 iOS 14 和 iOS 15 设备。遗憾的是,最后的

application.datePickers["DatePicker"].tap()
调用在 iOS 16 设备上失败,因为
application.datePickers["DatePicker"]
不可命中。如何在 iOS 16 设备上关闭 DatePicker 弹出窗口?

就其价值而言,我正在 iOS 16.1 模拟器设备上通过 Xcode 14.1 运行测试。我手头没有真正的 iOS 16 设备,因此无法验证真实 iOS 16 设备上的行为。

最后,您可以在此处找到一个演示问题的最小应用程序项目。

swiftui datepicker xcuitest
1个回答
2
投票

我在苹果开发者论坛(这里)上发布了同样的问题,并得到了对我有用的回复。

想法是在

XCUIElement
类上定义一个 forceTap() 扩展函数,如下:

extension XCUIElement {
    func forceTap() {
        if (isHittable) {
            tap()
        } else {
            coordinate(withNormalizedOffset: CGVector(dx:0.0, dy:0.0)).tap()
        }
    }
}

说明:如果 XCUIElement 实例可命中,则调用 XCUIElement 实例的 tap() 函数。否则,将为 XCUIElement 实例内的点创建 XCUICooperative 实例,并调用该 XCUICooperative 实例的 tap() 函数。

我的测试函数的最后一行现在更改为以下内容:

application.datePickers["DatePicker"].forceTap()
© www.soinside.com 2019 - 2024. All rights reserved.