web-dev-qa-db-fra.com

UI Testing Failure - Ni l'élément ni aucun descendant n'a le focus du clavier sur secureTextField

C'est mon cas:

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

UI Testing Failure - Aucun élément ni aucun descendant n'a le focus du clavier. Élément:

Qu'est-ce qui ne va pas? Cela fonctionne bien pour textFields normal, mais le problème ne se pose qu'avec secureTextFields. Des solutions de contournement?

87

Ce problème m'a causé beaucoup de souffrance, mais j'ai réussi à trouver une solution appropriée. Dans le simulateur, assurez-vous que «Matériel -> Clavier -> Connecter le clavier matériel» est désactivé.

163
Ted Kaminski

Récemment, nous avons trouvé un moyen de rendre la solution de la réponse acceptée persistante Pour désactiver les paramètres du simulateur: "Matériel -> Clavier -> Connecter le clavier matériel" à partir de la ligne de commande, vous devez écrire:

defaults write com.Apple.iphonesimulator ConnectHardwareKeyboard 0

Cela n'affectera pas un simulateur en cours d'exécution - vous devez redémarrer le simulateur ou en créer un nouveau pour que ce paramètre ait son effet.

14
AlexDenisov

J'ai écrit une petite extension (Swift) qui me convient parfaitement. Voici le code:

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

L'idée principale est de continuer à appuyer sur un élément (champ de texte) avant que le clavier ne soit présenté.

13
berezhnyi oleksandr

Stanislav a la bonne idée. 

Dans un environnement d'équipe, vous avez besoin de quelque chose qui fonctionnera automatiquement. J'ai trouvé un correctif ici sur mon blog.

Fondamentalement, vous venez de coller:

UIPasteboard.generalPasteboard().string = "Their password"
let passwordSecureTextField = app.secureTextFields["password"]
passwordSecureTextField.pressForDuration(1.1)
app.menuItems["Paste"].tap()
11
RyanPliske
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()
}
4
Anthony

Une autre cause de cette erreur est s'il existe une vue parent du champ de texte dans lequel vous essayez de saisir du texte défini comme élément d'accessibilité (view.isAccessibilityElement = true). Dans ce cas, XCTest n'est pas en mesure d'obtenir un descripteur sur la sous-vue pour saisir le texte et renvoie l'erreur.

UI Testing Failure - Aucun élément, ni aucun descendant n'a de clavier concentrer.

Ce n'est pas qu'aucun élément n'a le focus (comme vous pouvez souvent voir le clavier levé et le curseur clignotant dans UITextField), c'est simplement qu'aucun élément il ne peut atteindre n'a le focus. Je me suis heurté à cela en essayant de saisir du texte dans un UISearchBar. La barre de recherche elle-même n'est pas le champ de texte. Lors de sa définition en tant qu'élément d'accessibilité, l'accès à UITextField sous-jacent était bloqué. Pour résoudre ce problème, searchBar.accessibilityIdentifier = "My Identifier" a été défini sur UISearchBar, mais isAccessibilityElement n'a pas été défini sur true. Après cela, testez le code de la forme:

app.otherElements["My Identifier"].tap()
app.otherElements["My Identifier"].typeText("sample text")

Travaux

4
user3847320

Cela s'est produit avec moi plusieurs fois. Vous devez désactiver le matériel clavier et la même disposition que OSX dans votre simulateur.

Matériel/Clavier (tout désactiver)

Après cela, le logiciel du clavier ne sera pas ignoré et vos tests pourront taper du texte.

 Disable Hardware

4

Utilisez un sommeil entre le lancement de l'application et la saisie de données dans des champs de texte comme ceci:

sleep(2)

Dans mon cas, je continuais à avoir cette erreur à chaque fois et seule cette solution m'aidait.

4
Kingalione

Cela aide peut-être: je viens d'ajouter une action "tap" avant l'erreur; c'est tout :)

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

Enregistrez le cas comme bon vous semble, clavier ou sans clavier . Mais procédez comme suit avant de jouer au test.

Cette option suivante (connecter le clavier matériel) doit être décochée pendant le test.

 enter image description here

3
umairhhhs

[Republier Bartłomiej Semańczyk le commentaire de/comme réponse car cela résout le problème pour moi]

Je devais faire Simulator> Reset Contents and Settings dans la barre de menus du simulateur pour que cela commence à fonctionner pour moi.

2
rogueleaderr

Une autre réponse, mais pour nous le problème était que la vue était trop proche d'une autre vue qu'un reconnaissance de geste sur celle-ci. Nous avons constaté que la vue devait être éloignée d’au moins 20 pixels (dans notre cas, ci-dessous). Littéralement 15 ne fonctionnait pas et 20 ou plus le faisaient. C'est étrange, je l'avoue, mais nous avions quelques UITextViews qui fonctionnaient et d'autres qui ne le faisaient pas et qui étaient tous sous le même parent et dont le même positionnement était identique (et les noms de variables bien sûr). Le clavier allumé ou éteint ou quoi que ce soit ne faisait aucune différence. L'accessibilité a montré les champs. Nous avons redémarré nos ordinateurs. Nous avons fait des constructions propres. Checkouts de source fraîche. 

0
David J

Le problème pour moi était le même que pour Ted. En fait, si le champ du mot de passe est exploité après le champ de connexion et que la base de connaissances matérielle est activée, le clavier logiciel s'auto-ignorera lors de la deuxième tape du champ, et ce n'est pas spécifique aux tests d'interface utilisateur.

Après un peu de temps avec AppleScript, voici ce que je propose (les améliorations sont les bienvenues):

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

Créez un fichier de script avec le code ci-dessus et ajoutez-le aux cibles nécessaires (probablement uniquement pour les tests d'interface utilisateur, vous pouvez ajouter un script similaire à vos cibles de développement pour réactiver le clavier matériel pendant le développement) . Vous devez ajouter Run Script phase in construire des phases et l'utiliser comme ceci: osascript Path/To/Script/script_name.applescript

0
Timur Kuchkarov

Parfois, les champs de texte ne sont pas implémentés en tant que champs de texte ou sont encapsulés dans un autre élément d'interface utilisateur et ne sont pas facilement accessibles. Voici un travail autour de:

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

0
Eugene Berezin

Votre première ligne est simplement une définition de query, ce qui ne signifie pas que passwordSecureTextField existerait réellement.

Votre deuxième ligne va dynamiquement exécuter la requête et essayer de (re) lier la requête à l'élément d'interface utilisateur. Vous devez placer un point d'arrêt dessus et vérifier qu'un seul et même élément est trouvé. Ou utilisez simplement une assertion:

XCTAssertFalse(passwordSecureTextField.exists);

Sinon, cela semble correct, tap devrait rendre le clavier visible, puis typeText devrait fonctionner. Le journal des erreurs devrait vous donner plus d’informations.

0
JOM

Nous avons rencontré la même erreur lors de la définition de la valeur accessibilityIdentifier pour une vue personnalisée (sous-classe UIStackView) contenant des sous-vues UIControl. Dans ce cas, XCTest n'a pas pu obtenir le focus clavier pour les éléments descendants.

Notre solution consistait simplement à supprimer la accessibilityIdentifier de notre vue parent et à définir la accessibilityIdentifier pour les sous-vues via des propriétés dédiées. 

0
shadowhorst

Ce qui a résolu ce problème pour moi, c’est d’ajouter une seconde de sommeil:

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

Ne vous trompez pas, le problème est que la raison est que vous avez enregistré votre temps de test. Votre application connectera un clavier matériel alors que votre simulateur de temps de test automatique utilise uniquement un clavier logiciel. donc pour savoir comment résoudre ce problème. Il suffit d’utiliser un clavier logiciel sur votre temps d’enregistrement. vous pouvez voir la magie.

0
codercat