Protractor ist installiert, der Test geschrieben, aber die Konsole spuckt nur Fehlermeldungen aus? Hier sind ein paar Tipps, wie verschiedene Funktionalitäten getestet werden können.
Elemente finden
Elemente, mit denen die Nutzer interagieren sollen, können nach verschiedenen Selektoren ausgewählt werden:
- nach Element-ID
element(by.id('id'))
- nach HTML-Tag
element(by.tagName('div'))
- nach CSS-Klasse
element(by.css('.class'))
- Input-Feld anhand seines Models
element(by.model('profile.firstName'))
- Button oder Label anhand seines Bindings
element(by.binding('dict.helloWorld'))
- Ein bestimmtes von mehreren Elementen mit dem gleichen HTML-Tag oder der gleichen CSS-Klasse
element.all(by.tagName('li')).first(); element.all(by.tagName('li')).last(); element.all(by.tagName('li')).get(1);
Testen, ob ein Element klickbar ist
Es gibt mehrere Möglichkeiten, zu überprüfen, ob das Element überhaupt da ist:
- Element (DOM-Knoten) ist vorhanden (aber nicht zwingend sichtbar)
expect(element(by.css('.class')).isPresent()).toBe(true);
- Element wird angezeigt
expect(element(by.css('.class')).isDisplayed()).toBe(true);
- Element ist klickbar
expect(element(by.tagName('button')).isEnabled()).toBe(true);
Hartnäckig unsichtbare Elemente sichtbar machen
Beispiel: Die select-Optionen bekommen für ein schöneres Layout einen Style “invisible”, bis die Selectbox angeklickt wird. Protractor kann damit nicht umgehen, weshalb ein bisschen getrickst werden muss:
browser.executeScript('return document.getElementsByTagName("select")[0].style.visibility = "visible"').then(function () {});
Auf Elemente warten
Soll ein Element angeklickt werden, das erst per Animation eingeblendet wird, gibt es eine Fehlermeldung, wenn zu früh geklickt wurde. Hier kann es sinnvoll sein, den Browser anzuweisen, auf das Ende der Animation zu warten.
browser.wait(element(by.id('id')).isDisplayed()).toBe(true);
mit Timeout:
browser.wait(element(by.id('id'),500).isDisplayed()).toBe(true);
Diese Funktion ist eher buggy. Häufig wird die Fehlermeldung “unimplemented function ‘is pending'” angezeigt. Das kann aber auch ein Hinweis auf einen Fehler im Test sein, z.B. wenn das Element über den verwendeten Selector gar nicht auffindbar ist.
URL vergleichen
Beispiel: Es soll überprüft werden, ob der Klick auf einen Button eine neue Seite öffnet.
element(by.tagName('button')).click().then(function () { expect(ptor.getCurrentUrl()).toMatch('#/neue-seite'); })
Text vergleichen
Wenn sich der Text eines Elements unter bestimmten Bedingungen ändert, kann er hinterher verglichen werden.
oldButtonName = element(by.tagName('button')).getText(); //Text ändern newButtonName = element(by.tagName ('button')).getText(); expect(newButtonName).not.toBe(oldButtonName);
Formulare ausfüllen
Text-Inputfelder leeren und dann mit „send keys“ ausfüllen:
element(by.model('profile.firstName')).clear(); element(by.model('profile.firstName')).sendKeys('Name');
Date-Input nicht leeren! Datum im Format dd-mm-yyyy eingeben:
element(by.model('profile.birthday')).sendKeys('05-06-1980');
Checkbox anklicken und hinterher das Model auf true oder false testen:
element(by.css('.checkbox')).click().then(function () { expect(element(by.model('active'))).toBeTruthy(); });
Erste Option der ersten Selectbox auswählen, wenn es mehrere Selectboxen (Dropdowns) gibt:
element.all(by.tagName('select')).first().element(by.css('option[value="0"]')).click();
Länge von Tabellen abfragen
Damit lässt sich z.B. anschließend testen, ob das Anlegen einer weiteren Zeile funktioniert hat.
element.all(by.css('.table tbody tr')).then(function (items) { length = items.length; });
Scrollen
Wird kein AngularJS verwendet, kann das Fenster so zu einer bestimmten Position gescrollt werden:
ptor.executeScript('window.scrollTo(0,0);').then(function () { page.saveButton.click(); })
Mit AngularJS funktioniert das etwas anders. Hiermit wird das Fenster zu einem bestimmten Element gescrollt:
var scrollIntoView = function (element) { arguments[0].scrollIntoView(); }; scrollDown = element(by.binding('dict.helloWorld')).getWebElement(); browser.executeScript(scrollIntoView, scrollDown);
Test pausieren
Ein Test kann angehalten oder der Browser daran gehindert werden, sich nach dem Test automatisch zu schließen.
- Debug-Funktion an der Stelle im Code aufrufen, an der der Test pausieren soll:
browser.debugger();
- Protractor mit debug-Flag starten
protractor debug protractor.conf.js
- “c” eintippen, um zu starten oder den Test nach dem Breakpoint fortzusetzen
Sicherlich gibt es einfachere Dinge als das Testen von Funktionen mit Hilfe von Oberflächentests. Doch mit Hilfe dieser Tipps und Tricks können zumindest für grundlegende Funktionalitäten nun Tests geschrieben werden, ohne Fehler wie am Fließband zu produzieren.