feat(companion): type text with replace semantics

This commit is contained in:
pj committed 2026-06-07 15:41:16 +05:30
1 parent f45d25d1bb
commit 84e8274d09
1 file changed
+43
+43
View File
@@ -0,0 +1,43 @@
import XCTest
// Types unicode text into the focused element through the public typeText API,
// avoiding the pasteboard entirely. With replace enabled, the current value
// length is consumed first by prepending that many delete keys so the whole
// replacement happens in one typeText call.
enum TextInput {
static func type(text: String, replace: Bool, bundleIdentifier: String) throws {
let application = XCUIApplication(bundleIdentifier: bundleIdentifier)
let focused = focusedElement(in: application)
var payload = text
if replace {
let currentLength = currentValueLength(of: focused)
if currentLength > 0 {
let deletes = String(repeating: XCUIKeyboardKey.delete.rawValue, count: currentLength)
payload = deletes + text
}
}
if let focused = focused {
focused.typeText(payload)
} else {
application.typeText(payload)
}
}
private static func focusedElement(in application: XCUIApplication) -> XCUIElement? {
let predicate = NSPredicate(format: "hasKeyboardFocus == true")
let matches = application.descendants(matching: .any).matching(predicate)
if matches.count > 0 {
return matches.element(boundBy: 0)
}
return nil
}
private static func currentValueLength(of element: XCUIElement?) -> Int {
guard let element = element, let value = element.value as? String else {
return 0
}
return value.count
}
}