iOS 14 / UI 测试 DatePicker

iOS 14 / UI Testing DatePicker

我正在努力修复 iOS 14 的 UI 测试,该测试在 DatePicker 视图上设置了日期。他们以前 运行 在 iOS 13 上显示为轮式拾取器时没有任何问题。我的代码用于设置不同的轮子,但由于 iOS 14 上不再有任何轮子,这不再有效。

我尝试使用一个小型演示项目并使用 XCode 12 记录按钮记录日期的变化,但它不起作用(在 Mac OS 10.15。 6) 由于错误:按日期按钮后出现“时间戳事件匹配错误:找不到匹配元素”。

我正在寻找的是 UI 测试用例,用于为 iOS 14:

的新日期选择器设置日期

这是我的演示项目:

import SwiftUI

struct ContentView: View {
    @State private var date = Date()

    var body: some View {
        Form {
            DatePicker(selection: $date, displayedComponents: .date) {
                Text("Date")
            }
        }
    }
}

问题只是如何点击外部展开的选择器以关闭它。您可以通过简单的点击来完成,您可以使用扩展来模拟:

extension XCUIApplication {
    func tapCoordinate(at point: CGPoint) {
        let normalized = coordinate(withNormalizedOffset: .zero)
        let offset = CGVector(dx: point.x, dy: point.y)
        let coordinate = normalized.withOffset(offset)
        coordinate.tap()
    }
}

这是一种基于录音的有点幼稚的方法;您可以根据需要清理它:

func testExample() throws {
    let app = XCUIApplication()
    app.launch()
    XCTAssertTrue(app.cells["Date, Date Picker, Sep 24, 2020"].exists)
    app.tables.datePickers.containing(.other, identifier:"Date Picker").element.tap()
    app.datePickers.collectionViews.buttons["Friday, September 4"].otherElements.containing(.staticText, identifier:"4").element.tap()
    app.tapCoordinate(at: CGPoint(x:30,y:30))
    XCTAssertTrue(app.cells["Date, Date Picker, Sep 4, 2020"].exists)
}

当然,这仅在 今天 有效。但它会让你前进。

如果您想要看到关闭水龙头有效,请添加延迟:

    app.tapCoordinate(at: CGPoint(x:30,y:30))
    let delayExpectation = XCTestExpectation()
    delayExpectation.isInverted = true
    wait(for: [delayExpectation], timeout: 1)

您会看到展开的选择器确实在测试结束前消失了。

可能适用于 iOS 14 台设备,但它不适用于 iOS 15.2 设备。我面临的问题是 calendar-style 弹出窗口没有被关闭。经过数小时的反复试验,我发现关闭弹出窗口的代码与显示弹出窗口的代码相同。

在我的例子中,我在我的应用程序中声明了 DatePicker 如下:

DatePicker("Date Selected", selection: $selectedDate, displayedComponents: [.date])
    .accessibilityIdentifier("DatePicker")
    .datePickerStyle(.compact)

然后,在我的 UI 测试中,我正在执行以下操作:

// 1. Show the DatePicker popup
application.datePickers["DatePicker"].tap()
        
// 2. Choose a date in the popup
application.datePickers.collectionViews.buttons["Friday, January 14"].tap()
        
// 3. Dismiss the DatePicker popup
application.datePickers["DatePicker"].tap()

我整理了一个最小的 SwiftUI 应用来演示这个 here