Ошибка тестирования пользовательского интерфейса. Ни элемент, ни потомок не имеют фокуса клавиатуры на secureTextField

Это мой случай:

let passwordSecureTextField = app.secureTextFields["password"]
passwordSecureTextField.tap()
passwordSecureTextField.typeText("wrong_password") //here is an error

Ошибка тестирования пользовательского интерфейса. Ни элемент, ни потомок не имеют фокуса клавиатуры. Элемент:

Что не так? Это нормально для обычного textFields, но проблема возникает только с secureTextFields. Любые обходные пути?

Ответ 1

Этот вопрос вызвал у меня мир боли, но мне удалось найти правильное решение. В симуляторе убедитесь, что "Hardware → Keyboard → Connect hardware keyboard" выключено.

Ответ 2

В последнее время мы обнаружили взломы, чтобы сделать решение из принятого ответа упорным. Чтобы отключить настройку Simulator: "Оборудование → Клавиатура → Подключить аппаратную клавиатуру" из командной строки, следует написать:

defaults write com.apple.iphonesimulator ConnectHardwareKeyboard 0

Это не повлияет на работу симулятора - вам нужно перезапустить симулятор или запустить новый, чтобы этот параметр имел эффект.

Ответ 3

Я написал небольшое расширение (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))
        }
    }
}

Основная идея заключается в том, чтобы продолжать нажимать элемент (текстовое поле) до того, как будет представлена ​​клавиатура.

Ответ 4

У Станислава есть правильная идея.

В командной среде вам нужно что-то, что будет автоматически работать. Я придумал исправление здесь в своем блоге.

В основном вы просто вставляете:

UIPasteboard.generalPasteboard().string = "Their password"
let passwordSecureTextField = app.secureTextFields["password"]
passwordSecureTextField.pressForDuration(1.1)
app.menuItems["Paste"].tap()

Ответ 5

Другой причиной этой ошибки является наличие родительского представления текстового поля, в котором вы пытаетесь ввести текст, который устанавливается как элемент доступности (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")

Работа

Ответ 6

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()
}

Ответ 7

Это происходило со мной много раз. Вы должны отключить оборудование клавиатуры и ту же компоновку, что и OSX в своем симуляторе

Оборудование/Клавиатура (отключить все)

После этого программное обеспечение клавиатуры не будет отменено, и ваши тесты могут набирать текст

Отключить оборудование

Ответ 8

Используйте сон между запуском приложения и вводом данных в текстовые поля следующим образом:

sleep(2)

В моем случае я постоянно получал эту ошибку, и только это решение помогло мне.

Ответ 9

Это может помочь: я просто добавляю действие "нажмите" перед ошибкой; это все:)

[app.textFields[@"theTitle"] tap];
[app.textFields[@"theTitle"] typeText:@"kk"];

Ответ 10

Запишите случай, как хотите, с клавиатурой или без клавиатуры. Но перед игрой сделайте следующее.

Этот следующий параметр (подключить аппаратную клавиатуру) должен быть отключен во время воспроизведения теста.

enter image description here

Ответ 11

[Reposting Bartłomiej Semańczyk комментарий как ответ, потому что он решил проблему для меня]

Мне нужно было сделать Simulator > Reset Содержание и настройки в строке меню симулятора, чтобы начать работать для меня.

Ответ 12

Ваша первая строка - это просто определение запроса, что не означает, что passwordSecureTextField действительно существует.

Вторая строка будет динамически выполнять запрос и попытаться (повторно) связать запрос с элементом пользовательского интерфейса. Вы должны положить на него точку останова и убедиться, что найден один и только один элемент. Или просто используйте assert:

XCTAssertFalse(passwordSecureTextField.exists);

В противном случае он выглядит нормально, tap должен принудительно отображать клавиатуру, а затем typeText должен работать. Журнал ошибок должен сообщить вам больше информации.

Ответ 13

Не перепутайтесь. Проблема в том, что вы заметили, что время вашего приложения будет подключаться к аппаратной клавиатуре, в то время как ваш автоматический симулятор времени тестирования использует только программную клавиатуру. поэтому для того, чтобы исправить эти проблемы. Просто используйте клавиатуру программного обеспечения во время записи. вы можете увидеть волшебство.

Ответ 14

Проблема для меня была такой же, как для Теда. Фактически, если поле пароля активируется после того, как поле входа в систему и аппаратный КБ включен, клавиатура программного обеспечения отклонит себя во втором полевом поле, и это не относится к испытаниям пользовательского интерфейса.

После некоторого времени возиться с 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

Ответ 15

Мы столкнулись с той же ошибкой при установке значения accessibilityIdentifier для пользовательского представления (подклассом UIStackView), содержащего UIControl subviews. В этом случае XCTest не смог получить фокус клавиатуры для дочерних элементов.

Наше решение состояло в том, чтобы просто удалить accessibilityIdentifier из нашего родительского представления и установить accessibilityIdentifier для подзаголовков через специальные свойства.

Ответ 16

Иногда текстовые поля не реализуются как текстовые поля, или они заключены в другой элемент пользовательского интерфейса и не легко доступны. Вот обходное решение:

//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()       

Ответ 17

Другой ответ, но для нас проблема заключалась в том, что представление было слишком близко к другому мнению, что распознаватель жестов на нем. Мы обнаружили, что нам нужно, чтобы изображение было не менее 20 пикселей (в нашем случае ниже). Буквально 15 не сработало, а 20 и более сработало. Это странно, я признаю, но у нас было несколько UITextViews, которые работали, и некоторые, которые не работали, и все находились под одним и тем же родителем и имели идентичное другое позиционирование (и, конечно, имена переменных). Клавиатура включена или выключена или что-то не имеет значения. Доступность показала поля. Мы перезапустили наши компьютеры. Мы сделали чистые сборки. Свежий источник проверки.

Ответ 18

Что исправило эту проблему для меня, так это добавив 1 секунду сна:

let textField = app.textFields["identifier"]
textField.tap()
sleep(1)
textField.typeText(text)

Ответ 19

Имел ту же проблему с Securetextfields. Опция подключения оборудования в моем симуляторе была, но все же столкнулась с проблемой. Наконец, это сработало для меня (Swift 3):

 let enterPasswordSecureTextField = app.secureTextFields["Enter Password"]
    enterPasswordSecureTextField.tap()
    enterPasswordSecureTextField.typeText("12345678")