Ответ 1
Этот вопрос вызвал у меня мир боли, но мне удалось найти правильное решение. В симуляторе убедитесь, что "Hardware → Keyboard → Connect hardware keyboard" выключено.
Это мой случай:
let passwordSecureTextField = app.secureTextFields["password"]
passwordSecureTextField.tap()
passwordSecureTextField.typeText("wrong_password") //here is an error
Ошибка тестирования пользовательского интерфейса. Ни элемент, ни потомок не имеют фокуса клавиатуры. Элемент:
Что не так? Это нормально для обычного textFields
, но проблема возникает только с secureTextFields
. Любые обходные пути?
Этот вопрос вызвал у меня мир боли, но мне удалось найти правильное решение. В симуляторе убедитесь, что "Hardware → Keyboard → Connect hardware keyboard" выключено.
В последнее время мы обнаружили взломы, чтобы сделать решение из принятого ответа упорным. Чтобы отключить настройку Simulator: "Оборудование → Клавиатура → Подключить аппаратную клавиатуру" из командной строки, следует написать:
defaults write com.apple.iphonesimulator ConnectHardwareKeyboard 0
Это не повлияет на работу симулятора - вам нужно перезапустить симулятор или запустить новый, чтобы этот параметр имел эффект.
Я написал небольшое расширение (Swift), которое отлично подходит для меня. Вот код:
extension XCTestCase {
func tapElementAndWaitForKeyboardToAppear(element: XCUIElement) {
let keyboard = XCUIApplication().keyboards.element
while (true) {
element.tap()
if keyboard.exists {
break;
}
NSRunLoop.currentRunLoop().runUntilDate(NSDate(timeIntervalSinceNow: 0.5))
}
}
}
Основная идея заключается в том, чтобы продолжать нажимать элемент (текстовое поле) до того, как будет представлена клавиатура.
У Станислава есть правильная идея.
В командной среде вам нужно что-то, что будет автоматически работать. Я придумал исправление здесь в своем блоге.
В основном вы просто вставляете:
UIPasteboard.generalPasteboard().string = "Their password"
let passwordSecureTextField = app.secureTextFields["password"]
passwordSecureTextField.pressForDuration(1.1)
app.menuItems["Paste"].tap()
Другой причиной этой ошибки является наличие родительского представления текстового поля, в котором вы пытаетесь ввести текст, который устанавливается как элемент доступности (view.isAccessibilityElement = true
). В этом случае XCTest не может получить дескриптор в subview для ввода текста и возвращает ошибку.
Ошибка тестирования пользовательского интерфейса - ни элемент, ни потомок не имеют клавиатуры фокус.
Не то, чтобы ни один элемент не имел фокуса (так как вы часто видите клавиатуру вверх и мигающий курсор в UITextField), просто элемент, к которому он может попасть, имеет фокус. Я столкнулся с этим при попытке ввода текста в UISearchBar. Строка поиска сама по себе не является текстовым полем, при установке в качестве элемента доступности доступ к базовому UITextField был заблокирован. Чтобы решить эту проблему, searchBar.accessibilityIdentifier = "My Identifier"
был установлен на UISearchBar
, однако isAccessibilityElement
не был установлен на true
. После этого введите тестовый код формы:
app.otherElements["My Identifier"].tap()
app.otherElements["My Identifier"].typeText("sample text")
Работа
func pasteTextFieldText(app:XCUIApplication, element:XCUIElement, value:String, clearText:Bool) {
// Get the password into the pasteboard buffer
UIPasteboard.generalPasteboard().string = value
// Bring up the popup menu on the password field
element.tap()
if clearText {
element.buttons["Clear text"].tap()
}
element.doubleTap()
// Tap the Paste button to input the password
app.menuItems["Paste"].tap()
}
Это происходило со мной много раз. Вы должны отключить оборудование клавиатуры и ту же компоновку, что и OSX в своем симуляторе
Оборудование/Клавиатура (отключить все)
После этого программное обеспечение клавиатуры не будет отменено, и ваши тесты могут набирать текст
Используйте сон между запуском приложения и вводом данных в текстовые поля следующим образом:
sleep(2)
В моем случае я постоянно получал эту ошибку, и только это решение помогло мне.
Это может помочь: я просто добавляю действие "нажмите" перед ошибкой; это все:)
[app.textFields[@"theTitle"] tap];
[app.textFields[@"theTitle"] typeText:@"kk"];
Запишите случай, как хотите, с клавиатурой или без клавиатуры. Но перед игрой сделайте следующее.
Этот следующий параметр (подключить аппаратную клавиатуру) должен быть отключен во время воспроизведения теста.
[Reposting Bartłomiej Semańczyk комментарий как ответ, потому что он решил проблему для меня]
Мне нужно было сделать Simulator > Reset Содержание и настройки в строке меню симулятора, чтобы начать работать для меня.
Ваша первая строка - это просто определение запроса, что не означает, что passwordSecureTextField
действительно существует.
Вторая строка будет динамически выполнять запрос и попытаться (повторно) связать запрос с элементом пользовательского интерфейса. Вы должны положить на него точку останова и убедиться, что найден один и только один элемент. Или просто используйте assert:
XCTAssertFalse(passwordSecureTextField.exists);
В противном случае он выглядит нормально, tap
должен принудительно отображать клавиатуру, а затем typeText
должен работать. Журнал ошибок должен сообщить вам больше информации.
Не перепутайтесь. Проблема в том, что вы заметили, что время вашего приложения будет подключаться к аппаратной клавиатуре, в то время как ваш автоматический симулятор времени тестирования использует только программную клавиатуру. поэтому для того, чтобы исправить эти проблемы. Просто используйте клавиатуру программного обеспечения во время записи. вы можете увидеть волшебство.
Проблема для меня была такой же, как для Теда. Фактически, если поле пароля активируется после того, как поле входа в систему и аппаратный КБ включен, клавиатура программного обеспечения отклонит себя во втором полевом поле, и это не относится к испытаниям пользовательского интерфейса.
После некоторого времени возиться с AppleScript, вот что я придумал (улучшения приветствуются):
tell application "Simulator"
activate
tell application "System Events"
try
tell process "Simulator"
tell menu bar 1
tell menu bar item "Hardware"
tell menu "Hardware"
tell menu item "Keyboard"
tell menu "Keyboard"
set menuItem to menu item "Connect Hardware Keyboard"
tell menu item "Connect Hardware Keyboard"
set checkboxStatus to value of attribute "AXMenuItemMarkChar" of menuItem
if checkboxStatus is equal to "✓" then
click
end if
end tell
end tell
end tell
end tell
end tell
end tell
end tell
on error
tell application "System Preferences"
activate
set securityPane to pane id "com.apple.preference.security"
tell securityPane to reveal anchor "Privacy_Accessibility"
display dialog "Xcode needs Universal access to disable hardware keyboard during tests(otherwise tests may fail because of focus issues)"
end tell
end try
end tell
end tell
Создайте файл script с указанным выше кодом и добавьте его в нужные целевые объекты (возможно, только целевые тесты пользовательского интерфейса), вы можете добавить аналогичные script к вашим целям разработки, чтобы снова включить HW-клавиатуру во время разработки).
Вы должны добавить фазу фазы Run Script
в фазе сборки и использовать ее следующим образом:
osascript Path/To/Script/script_name.applescript
Мы столкнулись с той же ошибкой при установке значения accessibilityIdentifier
для пользовательского представления (подклассом UIStackView
), содержащего UIControl
subviews. В этом случае XCTest не смог получить фокус клавиатуры для дочерних элементов.
Наше решение состояло в том, чтобы просто удалить accessibilityIdentifier
из нашего родительского представления и установить accessibilityIdentifier
для подзаголовков через специальные свойства.
Иногда текстовые поля не реализуются как текстовые поля, или они заключены в другой элемент пользовательского интерфейса и не легко доступны. Вот обходное решение:
//XCUIApplication().scrollViews.otherElements.staticTexts["Email"] the locator for the element
RegistrationScreenStep1of2.emailTextField.tap()
let keys = app.keys
keys["p"].tap() //type the keys that you need
//If you stored your data somewhere and need to access that string //you can cats your string to an array and then pass the index //number to key[]
let newUserEmail = Array(newPatient.email())
let password = Array(newPatient.password)
//When you cast your string to an array the elements of the array //are Character so you would need to cast them into string otherwise //Xcode will compain.
let keys = app.keys
keys[String(newUserEmail[0])].tap()
keys[String(newUserEmail[1])].tap()
keys[String(newUserEmail[2])].tap()
keys[String(newUserEmail[3])].tap()
keys[String(newUserEmail[4])].tap()
keys[String(newUserEmail[5])].tap()
Другой ответ, но для нас проблема заключалась в том, что представление было слишком близко к другому мнению, что распознаватель жестов на нем. Мы обнаружили, что нам нужно, чтобы изображение было не менее 20 пикселей (в нашем случае ниже). Буквально 15 не сработало, а 20 и более сработало. Это странно, я признаю, но у нас было несколько UITextViews, которые работали, и некоторые, которые не работали, и все находились под одним и тем же родителем и имели идентичное другое позиционирование (и, конечно, имена переменных). Клавиатура включена или выключена или что-то не имеет значения. Доступность показала поля. Мы перезапустили наши компьютеры. Мы сделали чистые сборки. Свежий источник проверки.
Что исправило эту проблему для меня, так это добавив 1 секунду сна:
let textField = app.textFields["identifier"]
textField.tap()
sleep(1)
textField.typeText(text)
Имел ту же проблему с Securetextfields. Опция подключения оборудования в моем симуляторе была, но все же столкнулась с проблемой. Наконец, это сработало для меня (Swift 3):
let enterPasswordSecureTextField = app.secureTextFields["Enter Password"]
enterPasswordSecureTextField.tap()
enterPasswordSecureTextField.typeText("12345678")