Eigene Lokator-Strategie für Selenium implementieren

Keine Kommentare

In Selenium können die HTML-Elemente auf verschiedenen Wegen lokalisiert werden. Detaillierte Informationen dazu finden sich hier. In der Standardeinstellung nutzt Selenium den id-Lokator, wenn kein explizites Präfix definiert ist. In meinem Projekt haben wir die Anforderung die zu testenden Elemente über den Labeltext zu lokalisieren, da die id- und name-Attribute generiert werden. Das Ziel des eigenen Lokators ist es den Wert des id-Attributes des folgenden Feldes zu ermitteln:

<label for="IDGEN123456789">Foo-Label</label> 
<input id="IDGEN123456789" value="test"/>

Daniel hat bereits einen sehr guten Artikel über Tipps und Tricks zur Benutzung von Lokatoren und ähnliche Themen in diesem Bereich geschrieben. In diesem Blogartikel möchte ich auf die Erstellung einer eigenen Lokator-Strategie eingehen. Der Hauptgrund für mich war, dass XPath-Ausdrücke in den Testfällen nicht wirklich wartbar sind. Normalerweise möchte ich solche Ausdrücke zum lokalisieren eines Elements in einem Testfall nicht sehen:

xpath=//label[contains(.,'Foo-Label')]/@for

Ich möchte an dieser Stelle keine Diskussion starten, ob denn jetzt CSS- oder XPath-Lokatoren der bessere Weg sind. In diesem Beispiel wird XPath genutzt. Nach kurzer Recherche fand ich diese nützliche User-Extension. Das ist schon fast alles was wir brauchen, um die Elemente zu lokalisieren. Aber starten wir am Anfang.

Implementierung der Lokator-Strategie für Selenium

Als erste muss eine JavaScript-Datei (user-extension.js) mit der Lokator-Strategie erstellt werden:

PageBot.prototype.locateElementByLabelText = function(labelText, inDocument) {
[...]
}

Das Präfix ist sehr wichtig, da alle locateElementBy*-Methoden als Lokator-Strategie automatisch hinzugefügt werden. Für den vollständigen Quellcode verweise ich an dieser Stelle auf diese Seite.

Um die Erweiterung in den Tests zu nutzen, muss die user-extension.js dem Selenium Server bekannt gemacht werden:

java -cp selenium-server-standalone-2.16.1.jar org.openqa.selenium.server.SeleniumServer -port 4455 -singlewindow -userExtensions "user-extensions.js"

Nach diesen Schritten ist man in der Lage den neuen Lokator zu benutzen:

labeltext=Foo-Label

Selenium IDE

Aber es wäre auch noch sehr cool, wenn es möglich wäre diesen Lokator in der Selenium IDE zu nutzen. Kein Problem 🙂 Für dieses Feature ist die Implementierung eines LocatorBuilders notwendig:

LocatorBuilders.add('labeltext', function(e) {
		if (e.id) {
			var locator = "xpath=" + "//" + "label[@for='" + e.id +"']" + "/span/text()";
			var label = this.findElement(locator);
			return "labeltext=" + label.textContent;
		}
		return null;
	});

Falls die neue Strategie per default genutzt werden soll, braucht man nur diese Zeile noch ins Skript einfügen:

LocatorBuilders.order = ['labeltext', 'id', 'link', 'name', 'dom:name', 'xpath:link', 'xpath:img', 'xpath:attributes', 'xpath:href', 'dom:index', 'xpath:position'];

Die obigen Skripte sollten in einer separaten Datei gespeichert werden (z.B. user-extension-ide.js), weil der LocatorBuilder nur in der Selenium IDE benötigt wird.

Installation in der Selenium IDE

Zur Installation braucht man nur die Skripte im Options-Menu, wie auf folgendem Bildschirmfoto, konfigurieren:

Benutzung

Andreas hat hier ein paar Tipps zum debuggen von XPath und CSS Lokatoren gegeben. In seinem Screencast zeigt er die Verwendung des „Find“-Buttons in der Selenium IDE zum lokalisieren von Elementen. Wenn die obigen Skripte korrekt installiert sind, dann ist man in der Lage dieses nützliche Feature auch mit dem neuen „labeltext“-Lokator zu nutzen.

In Kombination mit der Selenium IDE Erweiterung für das Robot Framework ist es möglich die Testfälle aufzuzeichnen und direkt in ein sehr lesbares Format zu exportieren:

Select From List  labeltext=Label1  Test
Input Text  labeltext=Label2  AnotherValue
Textfield Should Contain  labeltext=Label3  Test

Der Quelltext von diesem Beispiel ist auf Github verfügbar.

Dennis Schulte

Dennis Schulte ist seit 2009 als Senior IT Consultant bei der codecentric AG tätig. Er unterstützt seine Kunden insbesondere im Bereich Enterprise-Architekturen, Microservices, Continuous Delivery, DevOps und der Optimierung von IT-Prozessen. Aufgrund seiner langjährigen Erfahrung als Architekt und Entwickler verfügt er über ein umfassendes Wissen im Bereich Java und Open-Source-Technologien. Seine Projektschwerpunkte liegen in der Architekturberatung und der Durchführung von Projekten in Enterprise-Unternehmen.

Share on FacebookGoogle+Share on LinkedInTweet about this on TwitterShare on RedditDigg thisShare on StumbleUpon

Kommentieren

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.