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 – Lokalisierung von Seitenelementen


Selenium - Webdriver Academy

Um Elemente auf einer HTML Site zu lokalisieren, gibt es mehrere Möglichkeiten, diese anzusprechen.

Ausgehend von der Methode findElement(By.locator()) können unterschiedliche Lokatoren verwendet werden. Jede Methode wird zur besseren Veranschaulichung mit einem Codebeispiel erklärt:

 

Methode Beschreibung

Codebeispiel

By.cssSelector Lokalisieren von Elementen über CSS Selektor findElement(By.cssSelector(„input#email“))
By.id Lokalisieren von Elementen durch die Element id
(z.B. bei <img src“xy.jpg“ id=“pic1″ border=0 alt=“Bild“>
findElement(By.id(„someId“))
By.identifier Dieser Lokalisierer funktioniert ähnlich wie der eben erwähnte, ist aber anwendbar auf id, name, type, class, usw. findElement(By.identifier(„formfeld_name“))
By.name Lokalisieren von Elementen mithilfe des name Attributes findElement(By.name(„someName“))
By.xpath Lokalisieren durch den XPath findElement(By.xpath(„id(’search_mini_form_autocomplete‘)/ul/li[3]“))
By.linkText Lokalisieren von Elementen durch den auf der Site angezeigten Text (innertext) findElement(By.linkText(„REGISTRATION“))
By.partialLinkText Lokalisieren von Elementen, welches einen Teiltext innerhalb eines Links hat
Ist vergleichbar mit linkText, allerdings ist hier ein Teil des angezeigten Texts ausreichend.
findElement(By.partialLinkText(„REG“))
By.className Lokalisieren von Elementen mithilfe des Klassen Attributs class findElement(By.className(„someClassName“))
By.tagName Lokalisieren von Elementen durch den HTML Tag Namen findElement(By.tagName(„div“))

 

Für eine öftere Verwendung eines Elements kann man dieses auch Instanzieren, damit man es nicht immer neu deklarieren muss. Hierfür benötigt man die Webelement Klasse des webdriver, welche im Paket org.openqa.selenium.* zu finden ist.

In der Praxis sieht es dann ungefähr so aus:
WebElement meinElement = driver.findElement(By.cssSelector("li.search"));
meinElement.sendKeys("Stichwort");

 

 

Anmerkung: Der Befehl sendKeys(String) entspricht der Eingabe eines String (in Klammern) in z.B. ein Suchfeld, Formularfeld, …

 


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.