使用 XCUIElementQuery 查找嵌入在 SwiftUI 中的表单中的 DatePicker() 的可访问性(标识符:)
Finding the accessibility(identifier:) of DatePicker() embedded in a Form in SwiftUI using an XCUIElementQuery
我有一个 SwiftUI 视图,它有一个包含 DatePicker 的表单:
struct GettingUpTimeSettingView: View {
@State private var viewModel = GettingUpTimeSettingViewModel()
var body: some View {
VStack {
Form {
Spacer()
Text(viewModel.questionString)
.accessibility(identifier: "Question")
Spacer()
DatePicker("Alarm Time",
selection: $viewModel.gettingUpTime,
displayedComponents: .hourAndMinute)
.accessibility(identifier: "Time")
.animation(.easeInOut)
Spacer()
Text(viewModel.explanationString)
.accessibility(identifier: "Explanation")
}
}
}
}
以及用于 UI 测试的 XCTestCase class:
class SleepyGPIntroUITests: XCTestCase {
private var app: XCUIApplication!
override func setUp() {
continueAfterFailure = false
app = XCUIApplication()
app.launch()
greeting = app.staticTexts["Greeting"]
}
override func tearDown() {
app = nil
}
func test_InitialScreen_ChangesTo_GettingUpScreen_Automatically() {
//Given
let questionText = "What time do you want to get up?"
let explanationText = "This should be the same time every day, including at weekends and on days off. Our best chance of great sleep comes when we have a regular routine."
let timeText = "7:00am"
let question = app.staticTexts["Question"]
let explanation = app.staticTexts["Explanation"]
let time = app.staticTexts["Time"]
//When
_ = time.waitForExistence(timeout: 2)
//Then
XCTAssertFalse(greeting.exists)
XCTAssertEqual(question.label, questionText, "Should show question at top of view")
XCTAssertEqual(explanation.label, explanationText, "Should show explanation in view")
XCTAssertEqual(time.label, timeText, "Should show the correct default time")
}
当我 运行 测试时,它失败并给我这个消息:
Failed to get matching snapshot: No matches found for Elements matching predicate '"Time" IN identifiers' from input {(
StaticText, identifier: 'Question', label: 'What time do you want to get up?',
StaticText, identifier: 'Explanation', label: 'This should be the same time every day, including at weekends and on days off. Our best chance of great sleep comes when we have a regular routine.'
)}
我不确定这是因为 DatePicker() 包含在表单中,还是因为我没有使用正确的 XCUIElementQuery 来查找它?
当我将 DatePicker 移出窗体时,我可以找到它,但只能使用它的标签,而不是它的可访问性标识符。
文本对象的可访问性标识符工作正常。
我也可以使用
找到它
app.datePickers.firstMatch
当它在表单之外时,而不是当它包含在表单中时。
我发现 答案描述了当 SwiftUI 对象包含在表单中时的一些奇怪行为,但仍然没有解决我的问题。
非常感谢。
tl:dr 无法将 XCUIElementQuery 获取到 return DatePicker 元素UI测试 DatePicker 是否包含在一个 SwiftUI 表单。
我已经为任何感兴趣的人找到了答案。
首先,一条基本建议,如果您在 UI 测试 XCode 时正在努力寻找如何访问元素,只需使用记录功能并访问手动添加元素。
这就是我所做的,它向我展示了在 SwiftUI 中点击 DatePicker() 之前,它实际上显示为一个按钮,因此在上面的示例中访问它我使用了这段代码:
let alarmTimeButton = app.tables.buttons["Time"]
我有一个 SwiftUI 视图,它有一个包含 DatePicker 的表单:
struct GettingUpTimeSettingView: View {
@State private var viewModel = GettingUpTimeSettingViewModel()
var body: some View {
VStack {
Form {
Spacer()
Text(viewModel.questionString)
.accessibility(identifier: "Question")
Spacer()
DatePicker("Alarm Time",
selection: $viewModel.gettingUpTime,
displayedComponents: .hourAndMinute)
.accessibility(identifier: "Time")
.animation(.easeInOut)
Spacer()
Text(viewModel.explanationString)
.accessibility(identifier: "Explanation")
}
}
}
}
以及用于 UI 测试的 XCTestCase class:
class SleepyGPIntroUITests: XCTestCase {
private var app: XCUIApplication!
override func setUp() {
continueAfterFailure = false
app = XCUIApplication()
app.launch()
greeting = app.staticTexts["Greeting"]
}
override func tearDown() {
app = nil
}
func test_InitialScreen_ChangesTo_GettingUpScreen_Automatically() {
//Given
let questionText = "What time do you want to get up?"
let explanationText = "This should be the same time every day, including at weekends and on days off. Our best chance of great sleep comes when we have a regular routine."
let timeText = "7:00am"
let question = app.staticTexts["Question"]
let explanation = app.staticTexts["Explanation"]
let time = app.staticTexts["Time"]
//When
_ = time.waitForExistence(timeout: 2)
//Then
XCTAssertFalse(greeting.exists)
XCTAssertEqual(question.label, questionText, "Should show question at top of view")
XCTAssertEqual(explanation.label, explanationText, "Should show explanation in view")
XCTAssertEqual(time.label, timeText, "Should show the correct default time")
}
当我 运行 测试时,它失败并给我这个消息:
Failed to get matching snapshot: No matches found for Elements matching predicate '"Time" IN identifiers' from input {( StaticText, identifier: 'Question', label: 'What time do you want to get up?', StaticText, identifier: 'Explanation', label: 'This should be the same time every day, including at weekends and on days off. Our best chance of great sleep comes when we have a regular routine.' )}
我不确定这是因为 DatePicker() 包含在表单中,还是因为我没有使用正确的 XCUIElementQuery 来查找它?
当我将 DatePicker 移出窗体时,我可以找到它,但只能使用它的标签,而不是它的可访问性标识符。
文本对象的可访问性标识符工作正常。
我也可以使用
找到它app.datePickers.firstMatch
当它在表单之外时,而不是当它包含在表单中时。
我发现
非常感谢。
tl:dr 无法将 XCUIElementQuery 获取到 return DatePicker 元素UI测试 DatePicker 是否包含在一个 SwiftUI 表单。
我已经为任何感兴趣的人找到了答案。
首先,一条基本建议,如果您在 UI 测试 XCode 时正在努力寻找如何访问元素,只需使用记录功能并访问手动添加元素。
这就是我所做的,它向我展示了在 SwiftUI 中点击 DatePicker() 之前,它实际上显示为一个按钮,因此在上面的示例中访问它我使用了这段代码:
let alarmTimeButton = app.tables.buttons["Time"]