Reinforce text typing within XCUITests

This commit is contained in:
Stefan Ceriu
2026-08-11 09:13:18 +03:00
parent 3f6347b6c9
commit d57c376b21
@@ -10,21 +10,43 @@ import SwiftUI
import XCTest import XCTest
extension XCUIElement { extension XCUIElement {
/// Clears the element's content and types the given text into it.
///
/// Keystrokes are silently dropped when the element hasn't finished taking focus, which corrupts the
/// value in ways that are hard to spot later on, so the result is verified and retried before failing.
func clearAndTypeText(_ text: String, app: XCUIApplication) { func clearAndTypeText(_ text: String, app: XCUIApplication) {
tap(.center) for _ in 0..<3 {
tap(.center)
app.showKeyboardIfNeeded()
app.showKeyboardIfNeeded()
guard let currentValue = value as? String else { _ = app.keyboards.firstMatch.waitForExistence(timeout: 10.0)
XCTFail("Tried to clear and type text into a non string value")
return guard let currentValue = value as? String else {
XCTFail("Tried to clear and type text into a non string value")
return
}
let deleteString = String(repeating: XCUIKeyboardKey.delete.rawValue, count: currentValue.count)
typeText(deleteString)
// Note: In the past, we had to type chars one by one to avoid CI flakiness
typeText(text)
// A newline submits the field, which tears it down before its value can be read back.
if text.contains("\n") || containsTypedText(text) {
return
}
} }
let deleteString = String(repeating: XCUIKeyboardKey.delete.rawValue, count: currentValue.count) XCTFail("Failed to type the expected text, the value is \(value as? String ?? "nil")")
typeText(deleteString) }
// Note: In the past, we had to type chars one by one to avoid CI flakiness /// Whether the element's value reflects the given text.
typeText(text) ///
/// Secure text fields report a bullet per character instead of the text itself, so all that can be compared is the length.
private func containsTypedText(_ text: String) -> Bool {
guard let value = value as? String else { return false }
return elementType == .secureTextField ? value.count == text.count : value == text
} }
func tap(_ point: UnitPoint) { func tap(_ point: UnitPoint) {