Die größte Hürde beim Testen von ExtJS mit Selenium besteht darin, dass ExtJS keine Standard-HTML-Elemente rendert und die Selenium-IDE naiv (und zu Recht) Befehle generiert, die auf Elemente abzielen, die nur als Dekor dienen - überflüssige Elemente, die ExtJS auf dem gesamten Desktop unterstützen. Look-and-Feel. Hier sind einige Tipps und Tricks, die ich beim Schreiben eines automatisierten Selenium-Tests gegen eine ExtJS-App gesammelt habe.
Allgemeine Hinweise
Elemente lokalisieren
Beim Generieren von Selenium-Testfällen durch Aufzeichnen von Benutzeraktionen mit Selenium IDE unter Firefox basiert Selenium die aufgezeichneten Aktionen auf den IDs der HTML-Elemente. Für die meisten anklickbaren Elemente verwendet ExtJS jedoch generierte IDs wie "ext-gen-345", die sich bei einem späteren Besuch derselben Seite wahrscheinlich ändern, selbst wenn keine Codeänderungen vorgenommen wurden. Nach dem Aufzeichnen von Benutzeraktionen für einen Test muss manuell gearbeitet werden, um alle Aktionen, die von den generierten IDs abhängen, durchzuführen und zu ersetzen. Es gibt zwei Arten von Ersetzungen, die vorgenommen werden können:
Ersetzen eines ID-Locators durch einen CSS- oder XPath-Locator
CSS-Locators beginnen mit "css =" und XPath-Locators beginnen mit "//" (das Präfix "xpath =" ist optional). CSS-Locators sind weniger ausführlich und leichter zu lesen und sollten XPath-Locators vorgezogen werden. Es kann jedoch Fälle geben, in denen XPath-Locators verwendet werden müssen, da ein CSS-Locator sie einfach nicht schneiden kann.
JavaScript ausführen
Einige Elemente erfordern aufgrund des komplexen Renderings von ExtJS mehr als nur einfache Maus- / Tastaturinteraktionen. Beispielsweise ist eine Ext.form.CombBox nicht wirklich ein <select>
Element, sondern eine Texteingabe mit einer getrennten Dropdown-Liste, die sich irgendwo am Ende des Dokumentbaums befindet. Um eine ComboBox-Auswahl richtig zu simulieren, können Sie zuerst einen Klick auf den Dropdown-Pfeil simulieren und dann auf die angezeigte Liste klicken. Das Auffinden dieser Elemente über CSS- oder XPath-Locators kann jedoch umständlich sein. Eine Alternative besteht darin, die ComoBox-Komponente selbst zu suchen und Methoden aufzurufen, um die Auswahl zu simulieren:
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
In Selenium kann der runScript
Befehl verwendet werden, um die obige Operation in einer präziseren Form auszuführen:
with (Ext.getCmp('genderComboBox')) { setValue('female'); fireEvent('select'); }
Umgang mit AJAX und Slow Rendering
Selen verfügt über die Varianten "* AndWait" für alle Befehle zum Warten auf das Laden von Seiten, wenn eine Benutzeraktion zu Seitenübergängen oder Neuladungen führt. Da AJAX-Abrufe jedoch keine tatsächlichen Seitenladevorgänge beinhalten, können diese Befehle nicht für die Synchronisierung verwendet werden. Die Lösung besteht darin, visuelle Hinweise wie das Vorhandensein / Fehlen einer AJAX-Fortschrittsanzeige oder das Auftreten von Zeilen in einem Raster, zusätzliche Komponenten, Links usw. zu verwenden. Zum Beispiel:
Command: waitForElementNotPresent
Target: css=div:contains('Loading...')
Manchmal wird ein Element erst nach einer bestimmten Zeit angezeigt, je nachdem, wie schnell ExtJS Komponenten rendert, nachdem eine Benutzeraktion zu einer Ansichtsänderung geführt hat. Anstatt willkürliche Verzögerungen mit dem pause
Befehl zu verwenden, besteht die ideale Methode darin, zu warten, bis das interessierende Element in unsere Reichweite gelangt. So klicken Sie beispielsweise auf ein Element, nachdem Sie darauf gewartet haben, dass es angezeigt wird:
Command: waitForElementPresent
Target: css=span:contains('Do the funky thing')
Command: click
Target: css=span:contains('Do the funky thing')
Sich auf beliebige Pausen zu verlassen, ist keine gute Idee, da Zeitunterschiede, die sich aus der Ausführung der Tests in verschiedenen Browsern oder auf verschiedenen Computern ergeben, die Testfälle schuppig machen.
Nicht anklickbare Elemente
Einige Elemente können vom click
Befehl nicht ausgelöst werden . Dies liegt daran, dass sich der Ereignis-Listener tatsächlich im Container befindet und nach Mausereignissen für seine untergeordneten Elemente sucht, die schließlich zum übergeordneten Element aufsteigen. Das Registersteuerelement ist ein Beispiel. Um auf die Registerkarte a zu klicken, müssen Sie ein mouseDown
Ereignis auf der Registerkarte beschriften:
Command: mouseDownAt
Target: css=.x-tab-strip-text:contains('Options')
Value: 0,0
Feldvalidierung
Formularfelder (Ext.form. * -Komponenten), denen reguläre Ausdrücke oder v-Typen zur Validierung zugeordnet sind, lösen die Validierung mit einer bestimmten Verzögerung aus (siehe die validationDelay
Eigenschaft, die standardmäßig auf 250 ms festgelegt ist), nachdem der Benutzer Text eingegeben hat oder sofort, wenn das Feld verliert Fokus - oder Unschärfen (siehe validateOnDelay
Eigenschaft). Um die Feldvalidierung nach der Ausgabe des Befehls Typ Selenium auszulösen, um Text in ein Feld einzugeben, müssen Sie einen der folgenden Schritte ausführen:
Auslösen einer verzögerten Validierung
ExtJS löst den Validierungsverzögerungszeitgeber aus, wenn das Feld Keyup-Ereignisse empfängt. Um diesen Timer auszulösen, geben Sie einfach ein Dummy-Keyup-Ereignis aus (es spielt keine Rolle, welchen Schlüssel Sie verwenden, da ExtJS ihn ignoriert), gefolgt von einer kurzen Pause, die länger als die Validierungsverzögerung ist:
Command: keyUp
Target: someTextArea
Value: x
Command: pause
Target: 500
Sofortige Validierung auslösen
Sie können ein Unschärfeereignis in das Feld einfügen, um eine sofortige Validierung auszulösen:
Command: runScript
Target: someComponent.nameTextField.fireEvent("blur")
Überprüfung auf Validierungsergebnisse
Nach der Validierung können Sie überprüfen, ob ein Fehlerfeld vorhanden ist oder nicht:
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"))]
Beachten Sie, dass die Prüfung "Anzeige: Keine" erforderlich ist, da ExtJS das Fehlerfeld einfach ausblendet, sobald es angezeigt wird und dann ausgeblendet werden muss, anstatt es vollständig aus dem DOM-Baum zu entfernen.
Elementspezifische Tipps
Klicken Sie auf eine Ext.form.Button
Option 1
Befehl: Klicken Sie auf Ziel: css = Schaltfläche: enthält ('Speichern')
Wählt die Schaltfläche anhand ihrer Beschriftung aus
Option 2
Befehl: Klicken Sie auf die Schaltfläche Ziel: css = # Speicheroptionen
Wählt die Schaltfläche anhand ihrer ID aus
Auswählen eines Werts aus einer Ext.form.ComboBox
Command: runScript
Target: with (Ext.getCmp('genderComboBox')) { setValue('female'); fireEvent('select'); }
Legt zuerst den Wert fest und löst dann das Auswahlereignis explizit aus, falls Beobachter vorhanden sind.