Quick Navigator
© 2004-2017 by Rocketlab

hand crafted in the beautiful mountains of Switzerland

Selenium – Tabellen und Inhalte


Selenium - Webdriver Academy

 

Mit Selenium XPath Tabellen, Zellen und Inhalte lokalisieren

Wie bereits in den vorangegangenen Artikeln beschrieben, lassen sich Inhalte generell über die By.Id(), By.name() oder By.cssSelector() Methoden ansprechen. Bei Tabellen und insbesondere bei Zellen ist es aber so, dass man diese eher selten (bis gar nicht) mit Ids, Namen oder Ähnlichem versieht.

Mit der By.xpath() Methode können wir jedes Element direkt und zweifelsfrei ansprechen. Sogar verschachtelte Tabellen (das sind z.B Tabellen in Tabellen) lassen sich hiermit abdecken.

Für die Praxisanwendung ist allerdings die Erstellung korrekter XPaths entscheidend. Hierfür ist das Wissen der DOM Struktur sowie Eltern- und Kindelementen Voraussetzung. Wir veranschaulichen dies an mehreren Beispielen, so dass die Methodik klar und verständlich ist und Sie am Ende gar der Auffassung sein könnten, dass XPath Strukturen gar nicht so schwer sind. Sie sind es nämlich überhaupt nicht.

 

Einfache Tabellen

Nehmen wir an wir haben eine einfache Tabelle mit mehreren Spalten sowie Zeilen. Im Sourcecode sieht dies in etwas so aus

<html>
<head>
<title>Einfache Tabelle</title>
</head>
<body>
<table name="tabone" id="tabone" width="100%">
<tbody>
<tr>
<td>erste zeile & erste spalte</td>
<td>erste zeile & zweite spalte</td>
</tr>
<tr>
<td>zweite zeile & erste spalte</td>
<td>zweite zeile & zweite spalte</td>
</tr>
</tbody>
</table>
</body>

Ergibt folgende Tabelle

Tabelle 1

Tabelle 1

Sie möchten nun die Zelle in der zweiten Spalte und der zweiten Zeile (oben fett markiert) erreichen. Wir lösen dies ganz einfach mit XPath. Die Struktur wird folgendermassen aufgebaut:

//table/tbody/tr[2]/td[2]

// so fängt jede XPath Struktur an

table : Dies ist das erste Elternelement vom Typ „table“ auf der HTML Site, usw.

Weshalb steht nun eine «2» als Index hinter TR und TD? Die Erklärung hierfür ist ganz einfach. Wir sprechen hier auch von Kindelementen. Sowohl TR als auch TD kam bereits mehrfach auf der Site vor. Innerhalb der Strukur (der Tabelle) ist das TR Tag in der zweiten Zeile das zweite (das erste kommt bereits ins Zeile 1 vor), innerhalb des TR Tags kommt das von uns gewollte TD auch als zweites vor (TD Tag davor markiert die erste Spalte). Somit zählt man ausgehend vom vorhergehenden Knoten (Node), hier TR, den Index, hier eben «2».

Das ist eigentlich schon alles. Mehr gibt es nicht wissen. In der Praxis ist es aber so, dass sehr komplexe Konstruktionen leicht Verwirrung hervorrufen. Es ist nicht immer so leicht, XPaths auf Anhieb fehlerfrei zu erstellen.

 

Verschachtelte Tabellen

Etwas schwieriger wird es, wenn Tabellen innerhalb von Tabellen vorkommen. Man spricht hier auch von verschachtelten Tabellen (nested tables). Mit oben erwähnter Vorgehensweise ist es aber trotzdem leicht zu bewältigen.

Die Tabelle sieht so aus

Tabelle 2

Tabelle 2

Der entsprechende XPath wird so aufgebaut, dass er im zweiten table Elternteil beginnt (= Index «2»).

Somit erhalten wir folgende XPath Struktur: //table/tbody/tr[2]/td[2]/table/tbody/tr[2]/td[2]

Es wird somit nur der fett gedruckte Teil (innere Tabelle) an die äussere Tabelle angehängt. In Ihrem Selenium Code sieht das Ganze dann in etwa so aus

String zelleninhalt = driver.findElement(By.xpath("//table/tbody/tr[2]/td[2]/table/tbody/tr[2]/td[2]").getText();

Sie werden sich vielleicht fragen, weshalb wir nicht gleich die zweite Tabelle als Basis nehmen und XPath so erstellen //table[2]/tbody/tr[2]/td[2]

Da wir verschachtelt arbeiten, würde die nächste Tabelle ausserhalb angesprochen werden, aber eben nicht die innere. Deshalb muss auch die äussere Tabelle mit dabei stehen.

Hinweis: die Webtools von Mozilla Firefox erstellen XPath Strukturen mit Namespaces (meist «x»). Selenium kann diese nicht verarbeiten.

 

XPath mit Attributen deklarieren

Jetzt wird es kompliziert – aber nicht wirklich. Stellen Sie sich vor, im Sourcecode gibt es mehrere Verschachtelungen, zum Beispiel 5 Tabellen in einander. Sie möchten jetzt auf eine Zelle in der 4 Tabelle zugreifen. Neben wir an, Sie haben alle Tabellen korrekt mit IDs versehen (in der Praxis leider eher nicht der Fall). Dann können Sie die entsprechende Tabelle, in der sich die Zelle befindet, die Sie ansprechen möchten, direkt adressieren, nämlich anhand ihrer ID:
//table[@id="tabfour"]/tbody/tr[3]/td[7]

Mit ihrem gewonnen Wissen des vorangegangenen Texts wissen Sie, dass sich die Zelle in der dritten Zeile und der siebten Spalte befindet. Das ganze ist in der Tabelle mit der id="tabfour" zu finden.

Im Selenium Code schreiben Sie dies in etwa so

String zelleninhalt = driver.findElement(By.xpath("//table[@id=\"tabfour\"]/tbody/tr[3]/td[7]").getText();

Bitte beachten Sie beiden Backspaces «\» vor den Anführungszeichen. Dies ist nötig, damit der JavaCompiler keinen Fehler wirft.

Spielen Sie ein bisschen selbst herum und gewöhnen Sie sich an XPath. Sie werden sehen, es ist halb so wild.

Am Ende sei noch ein Tipp oder Vielmehr ein Helferlein verraten: Sowohl für Mozilla Firefox als auch den Chrome Browser stehen diverse XPath Addons zur Verfügung. Diese erleichtern Ihre Arbeit enorm. Hierbei möchten besonders die Erweiterung für Firebug mit dem Namen Firepath empfehlen.

 

 

Elemente einer HTML Seite

Selenium – Linkelemente adressieren


Selenium - Webdriver Academy

 

Selenium im Umgang mit Linkelementen einer HTML Site

Selenium bietet mehrere Möglichkeiten, auf Linkelemente einer Website zugreifen zu können. Wie bereits im Artikel Lokalisierung von Seitenelementen aufgezeigt gibt es bereits zahlreiche Methoden, um Elemente zu finden, z.B. über CSS Selektoren, DOM Struktur, xPath usw. In diesem Artikel wird der Bereich Links nun noch um einige wertvolle Methoden erweitert, so dass Sie wirklich in der Lage sind, alle Elemente und Links zu adressieren.

Wieder gehen wir per findElement() Methode vor, welche uns eine enorme Funktionsvielfalt zur Verfügung stellt.

 

Methode Beschreibung

Codebeispiel

 By.linkText() Es wird ein Link angeklickt, welcher den mitgelieferten String innerhalb der a-Tags zeigt. z.B. <a href=“http://www.example.com/Muenchen“>{String}</a>Der String muss exakt so angegeben werden, wie er im HTML Quellcode vorkommt, da Selenium hier case-sensitive vorgeht.HTML5 Besonderheit: Seit Einführung von HTML5 als Standard ist es dem a-href Tag erlaubt, nicht mehr nur innerhalb, sondern jetzt auch ausserhalb der folgenden Tags zu stehen: <div>, <p> und <h1>. Die By.linkText() Methode erkennt Links sowohl innerhalb als auch ausserhalb dieser Block-Elemente.  driver.findElement(By.linkText({String})).click();
 By.partialLinkText()  Funktioniert ähnlich wie By.linkText(), allerdings ist hier nur ein Teil des innertext als Angabe nötig. Bedenken Sie aber, dass hier die Gefahr besteht, dass es mehr als ein Element mit diesen Eigenschaften auf der gleichen Website existiert. Adressiert wird dann jeweils nur das Element, welches als erstes auf der Website (von oben angefangen) vorkommt.  driver.findElement(By.partialLinkText("name")).click();
 By.tagName(„a“)  Dies ist eine sehr ungenaue Methode, da Sie hiermit erst einmal alle vorkommenden Links auf einer Site treffen. Diese Methode bietet sich aber dennoch an, um alle Links zunächst einmal „einzusammeln“ und dann per Loop (z.B. über eine While Schleife) alle Links überprüfen, ob eventuell ein Deadlink auf der Seite existiert.  List<WebElement> linkElements = driver.findElements(By.tagName("a"));
 By.cssSelector()  Bilder-Links können über die verschiedenen Selektoren wie im Artikel Lokalisierung von Seitenelementen bereits erklärt adressiert werden. Am einfachsten über den title Tag, name Tag oder was immer im Sourcecode vorhanden ist.Das Codebeispiel rechts bezieht sich auf folgenden Source (Auszug):<a class=“lfloat“ title=“Software Testing mit Rocketlab“ href=“https://www.rocketlab.de“>
<i class=“com_logo img xlt_8fjkl ygt_3ijlk2″>
<u>Rocketlab Logo</u>
</i>
</a>Natürlich ist auch xPath, Id usw. anwendbar in gleicher Weise.
 driver.findElement(By.cssSelector("a[title=\"Software Testing mit Rocketlab\"]")).click();

 

 

 

Selenium – Formulare testen


Selenium - Webdriver Academy

Formulare werden am Frontend sehr häufig gestestet. Diese werden aus verschiedenen Elementen und auch Technologien (z.B. jQuery Formulare) gebaut und stellen mit unter eine Herausforderung für den Tester dar. So ist es unter HP QTP/ UFT nur mit dem zusätzlichen Plugin Web-Toolkit möglich, Ajax bzw. jQuery Formulare zu testen. Selenium ist hier bereits sehr gut ausgestattet und lässt sogar Typenabfragen zu, wie z.B. Abfragen nach multi oder single Selectfeld.

Bevor Sie loslegen muss folgendes Selenium Paket importiert werden:

org.openqa.selenium.support.ui.Select

Jetzt noch ein Selectfeld multiAuswahlfeld als Select Objekt instanzieren:

Select multiAuswahlfeld = new Select(driver.findElement(By.Id("staedte_auswahl")));

Und schon können Sie mit der Instanz multiAuswahlfeld in Ihrem Selenium Script arbeiten. Grundsätzlich gibt es 3 Möglichkeiten für Ihr Seleniumscript, auf die jeweilige Auswahl in einem Selectfeld zuzugreifen.

Im HTML Sourcecode gibt es folgendes Formularelement:

<select id="staedte_auswahl" class="formselect" multiple="multiple">
<option value="x">- - - Bitte w&auml;hlen Sie einen Ort - - -</option>
<option value="muc">M&uuml;nchen</option>
<option value="stu">Stuttgart</option>
<option value="sg">St. Gallen</option>...
</select>

Den ersten gültigen Eintrag (hier im Beispiel „München“) können Sie auf folgende drei unterschiedliche Weisen in Selenium ansprechen:

  1. Innertext: selectByVisibleText()
    Beispiel Selenium Code: multiAuswahlfeld.selectByVisibleText("München");
  2. Value: selectByValue()
    Beispiel Selenium Code: multiAuswahlfeld.selectByValue("muc")
  3. Index: selectByIndex()
    Beispiel Selenium Code: multiAuswahlfeld.selectByIndex(1)
    Achten Sie darauf, dass der erste Eintrag in der Liste den Index=0 hat.

 

Falls Sie mehr als einen Eintrag selektieren möchten, wiederholen Sie den Befehl in Ihrem Selenium Programmcode einfach. Zum Deselektieren gibt es einen weiteren Befehl:

multiAuswahlfeld.deselectByVisibleText("Zürich");

Hiermit erreichen Sie, dass die Auswahl des Eintrags „Zürich“ wieder deselektiert wird. Falls dieser aber vorher nicht Selektiert war, kommt es zu einem Fehler.

Sie können übrigens auch die ganze Auswahl mit einem Befehl aufheben: deselectAll().

Somit empfiehlt es sich, Exceptions abzufangen und vorher abzufragen, ob der Eintrag bereits selektiert war. Zudem gibt es die Möglichkeit, abzufragen, ob ein Selectfeld ein Multi-Selectfeld ist. Hierzu verwenden Sie den Befehl isMultiple(). Beispiel in der Verwendung innerhalb eines Selenium Scripts:

if (multiAuswahlfeld.isMultiple()) {
// Anweisungen
}

 

Selenium Befehlsübersicht für Webformulare

 

Methode Beschreibung

Codebeispiel

 selectByVisibleText() Wählt in der Optionenliste einen Eintrag aus.  selectByVisibleText(„München“);
 deselectByVisibleText() Löscht die Auswahl eines bestimmten Eintrags aus einem Optionenliste.  deselectByVisibleText(„München“);
 selectByValue() Selektiert einen Eintrag durch Adressierung des Übergabewertes value.  selectByValue(„stu“);
 deselectByValue() Selektion wird wieder aufgehoben.  deselectByValue(„stu“);
 selectByIndex() Selektiert einen Eintrag durch Angabe eines Indexes. Achtung: Alle Indices fangen bei 0 an.  selectByIndex(3);
 deselectByIndex() Hebt Selektion wieder auf.  deselectByIndex(3);
 deselectAll() Hebt die komplette Selektion auf, so dass am Ende nicht ausgewählt ist.  deselectAll()
 isMultiple() Wir verwendet, um abzufragen, ob ein Selectfeld muliple ist oder nicht. Ist es multiple so wird der Wert True zurückgegeben.  Element.isMultiple()
 submit() Formularfeld oder komplettes Formular wird versendet. Kann alternativ zum Klick auf den Absende-Button verwendet werden.  Formular.submit()

 

Bitte beachten Sie, dass Sie mit Selenium einzelne Felder absenden (submit();) können, nicht nur das komplette Formular, so wie Sie es bei HTML Formularen eigentlich gewohnt sind.

Im Selenese sieht der Befehl zum Absenden nur des Vornamen(felds) so aus: driver.findElement(ById("input_vorname")).submit();

Um das komplette Formular zu versenden, klicken Sie entweder mit click() auf den Absende-Button oder adressieren den form-open Tag entweder nach Name, Id oder was immer zur Verfügung steht.

 


Launch the rocket!


Wir freuen uns auf neue Partner, die mit uns gemeinsam
außergewöhliche Dinge erschaffen möchten.
Schreiben Sie uns, wenn Sie mit uns zusammenarbeiten möchten.