Le plus gros obstacle dans le test d'ExtJS avec Selenium est qu'ExtJS ne rend pas les éléments HTML standard et que Selenium IDE générera naïvement (et à juste titre) des commandes ciblées sur des éléments qui agissent simplement comme décor - des éléments superflus qui aident ExtJS avec l'ensemble du bureau- regarde et ressent. Voici quelques trucs et astuces que j'ai rassemblés lors de l'écriture de test Selenium automatisé sur une application ExtJS.
Conseils généraux
Localisation des éléments
Lors de la génération de cas de test Selenium en enregistrant les actions des utilisateurs avec Selenium IDE sur Firefox, Selenium basera les actions enregistrées sur les identifiants des éléments HTML. Cependant, pour la plupart des éléments cliquables, ExtJS utilise des identifiants générés comme "ext-gen-345" qui sont susceptibles de changer lors d'une prochaine visite sur la même page, même si aucune modification de code n'a été effectuée. Après avoir enregistré les actions de l'utilisateur pour un test, un effort manuel est nécessaire pour exécuter toutes ces actions qui dépendent des identifiants générés et pour les remplacer. Deux types de remplacements peuvent être effectués:
Remplacement d'un localisateur d'identifiant par un localisateur CSS ou XPath
Les localisateurs CSS commencent par "css =" et les localisateurs XPath commencent par "//" (le préfixe "xpath =" est facultatif). Les localisateurs CSS sont moins détaillés et plus faciles à lire et devraient être préférés aux localisateurs XPath. Cependant, il peut y avoir des cas où des localisateurs XPath doivent être utilisés car un localisateur CSS ne peut tout simplement pas le couper.
Exécution de JavaScript
Certains éléments nécessitent plus que de simples interactions souris / clavier en raison du rendu complexe effectué par ExtJS. Par exemple, un Ext.form.CombBox n'est pas vraiment un <select>
élément mais une entrée de texte avec une liste déroulante détachée qui se trouve quelque part au bas de l'arborescence du document. Afin de simuler correctement une sélection ComboBox, il est possible de simuler d'abord un clic sur la flèche déroulante puis de cliquer sur la liste qui apparaît. Cependant, localiser ces éléments via des localisateurs CSS ou XPath peut être fastidieux. Une alternative consiste à localiser le composant ComoBox lui-même et à appeler des méthodes dessus pour simuler la sélection:
var combo = Ext.getCmp('genderComboBox'); // returns the ComboBox components
combo.setValue('female'); // set the value
combo.fireEvent('select'); // because setValue() doesn't trigger the event
Dans Selenium, la runScript
commande peut être utilisée pour effectuer l'opération ci-dessus sous une forme plus concise:
with (Ext.getCmp('genderComboBox')) { setValue('female'); fireEvent('select'); }
Faire face à AJAX et au rendu lent
Selenium a des saveurs "* AndWait" pour toutes les commandes d'attente de chargement de page lorsqu'une action de l'utilisateur entraîne des transitions ou des recharges de page. Cependant, comme les récupérations AJAX n'impliquent pas de chargements de page réels, ces commandes ne peuvent pas être utilisées pour la synchronisation. La solution est d'utiliser des indices visuels comme la présence / absence d'un indicateur de progression AJAX ou l'apparition de lignes dans une grille, des composants supplémentaires, des liens etc. Par exemple:
Command: waitForElementNotPresent
Target: css=div:contains('Loading...')
Parfois, un élément n'apparaît qu'après un certain temps, selon la vitesse à laquelle ExtJS restitue les composants après qu'une action de l'utilisateur entraîne un changement de vue. Au lieu d'utiliser des délais arbitraires avec la pause
commande, la méthode idéale est d'attendre que l'élément d'intérêt soit à notre portée. Par exemple, pour cliquer sur un élément après avoir attendu qu'il apparaisse:
Command: waitForElementPresent
Target: css=span:contains('Do the funky thing')
Command: click
Target: css=span:contains('Do the funky thing')
S'appuyer sur des pauses arbitraires n'est pas une bonne idée car les différences de timing résultant de l'exécution des tests dans différents navigateurs ou sur différentes machines rendront les cas de test floconneux.
Éléments non cliquables
Certains éléments ne peuvent pas être déclenchés par la click
commande. C'est parce que l'écouteur d'événements est en fait sur le conteneur, surveillant les événements de souris sur ses éléments enfants, qui finissent par remonter jusqu'au parent. Le contrôle onglet est un exemple. Pour cliquer sur l'onglet a, vous devez simuler un mouseDown
événement au niveau de l'étiquette de l'onglet:
Command: mouseDownAt
Target: css=.x-tab-strip-text:contains('Options')
Value: 0,0
Validation sur le terrain
Les champs de formulaire (composants Ext.form. *) Qui ont des expressions régulières associées ou des vtypes pour la validation déclencheront la validation avec un certain délai (voir la validationDelay
propriété qui est définie sur 250 ms par défaut), après que l'utilisateur a saisi du texte ou immédiatement lorsque le champ perd focus - ou floue (voir la validateOnDelay
propriété). Afin de déclencher la validation du champ après avoir émis la commande de type Selenium pour entrer du texte dans un champ, vous devez effectuer l'une des opérations suivantes:
Déclenchement de la validation retardée
ExtJS déclenche le temporisateur de délai de validation lorsque le champ reçoit des événements de keyup. Pour déclencher ce minuteur, émettez simplement un événement de keyup factice (peu importe la clé que vous utilisez car ExtJS l'ignore), suivi d'une courte pause qui est plus longue que le validationDelay:
Command: keyUp
Target: someTextArea
Value: x
Command: pause
Target: 500
Déclenchement de la validation immédiate
Vous pouvez injecter un événement de flou dans le champ pour déclencher une validation immédiate:
Command: runScript
Target: someComponent.nameTextField.fireEvent("blur")
Vérification des résultats de validation
Après validation, vous pouvez vérifier la présence ou l'absence d'un champ d'erreur:
Command: verifyElementNotPresent
Target: //*[@id="nameTextField"]/../*[@class="x-form-invalid-msg" and not(contains(@style, "display: none"))]
Command: verifyElementPresent
Target: //*[@id="nameTextField"]/../*[@class="x-form-invalid-msg" and not(contains(@style, "display: none"))]
Notez que la vérification "display: none" est nécessaire car une fois qu'un champ d'erreur est affiché et qu'il doit ensuite être caché, ExtJS masquera simplement le champ d'erreur au lieu de le supprimer entièrement de l'arborescence DOM.
Conseils spécifiques aux éléments
Cliquer sur un bouton Ext.form.Button
Option 1
Commande: cliquez sur Cible: css = bouton: contient ('Enregistrer')
Sélectionne le bouton par sa légende
Option 2
Commande: cliquez sur Target: css = # save-options button
Sélectionne le bouton par son identifiant
Sélection d'une valeur à partir d'un ext.form.ComboBox
Command: runScript
Target: with (Ext.getCmp('genderComboBox')) { setValue('female'); fireEvent('select'); }
Définit d'abord la valeur, puis déclenche explicitement l'événement select au cas où il y aurait des observateurs.